[Tech] OT: C, linux e la rappresentazione in mem

Franco Bagnoli franco.bagnoli@unifi.it
Lun 1 Mar 2004 20:38:55 CET


On Mon, 1 Mar 2004, Valerio Montagnani wrote:

> On Mon, 1 Mar 2004 16:35:50 +0100
> Valerio Montagnani <tech@vmontagnani.it> wrote:
> 
> Ok grazie amici.  E' proprio una ca***ta quella che ho scritto. Bestia
> che sono! Ho fatto tutti i conti pensando alla rappresentazione degli
> int, pur lavorando con numeri floating.
> 
> Il problema è nato dall'elaborazione successiva all'acquisizione dei
> dati. Infatti i dati audio acquisiti saranno successivamente elaborati
> con una una funzione che fa fft e poi rimaneggiati ancora da altre
> funzioni, fino all'estrazione di coefficienti mel. Dato che le funzioni
> che fanno tutto questo lavoro hanno bisogno di trattare i dati con una
> precisione superiore agli 8 bit (in genere è sufficiente creare un array
> di tipo unsigned char, per accogliere i dati audio), ho pensato di
> allocare dinamicamente un buffer di tipo float invece che unsigned char,
> per evitare il casting successivamente. Quindi ho continuato a ragionare
> come se avessi a che fare con i numeri interi, non considerando affatto
> come sono rappresentati i float.

ma vuoi fare il casting subito e memorizzarli come float, o stai pensando 
ad una union? 

> Bene. Ricominciamo.  Se ho 2 canali e rappresento un campione come float
> significa che nei primi 64 bit del buffer ho la rappresentazione float
> del primo campione acquisito dal canale sx e quindi dal canale dx. Nei
> successivi 64 ho di nuovo 32 bit riservati al canale sx e 32 al dx e
> così via... Se effettivamente il kernel di linux disponga prima il
> canale sx e poi il dx non è rilevante (per il mio problema, tuttavia se
> qualcuno sapesse in che ordine sono disposti i canali, mi farebbe
> piacere saperlo). Volendo estrarre dal buffer un canale solo per fare
> tutte le elaborazioni che vi ho descritto a grandi linee sopra, basta
> impostare un ciclo che si sposti a salti di 64 bit (di cui solo dei
> primi 32 sono quelli che devo usare), lungo tutto il buffer. Giusto
> vero? In questo modo, indipendentemente da come sarà rappresentato il
> campione di tipo float (24 bit + 8 bit o altro), mi becco sempre il
> campione del canale sx rappresentato in virgola mobile.

un array di struct? 

typedef struct {
	float sx; 
	float dx;
} sound;

sound * vect; 

vect = (sound *) malloc (N*sizeof(sound));

for (i=0; i<n; i++) {
	use(vect[i].dx);
}

> Un'ultima cosa, una bischerata, ma sono un programmatore alla prime
> armi. Su tutti i manuali che ho letto c'è sempre un esempio per
> descrivere l'allocazione dimanica di un vettore usando malloc, calloc o
> altro. Ma qual'è la sintassi per allocare un array a due o tre
> dimensioni?

essenzialmente due: Se il vettore a due (tre) dimensioni è una matrice, 
allora puoi memorizzarla con un vettore a una dimensione facendo qualche 
algebra con gli indici: 

#define m(i,j) m[(j)*Nx+(i)]

m = (float *) malloc(Nx*Ny*sizeof(float));

m(0,0)=3;
m(10,23)=7; 
ecc. 

(occhio a fare i loop sull'ordine giusto 

for (j=0; j<Ny; j++) {
	for (i=0; i<Nx; i++) {
		m(i,j)=...

altrimenti i dati non ci stanno nella cache e la velocità rallenta un bel 
po'.) 

Oppure allochi un vettore di puntatori 

float ** m;

m = (float **) malloc (Ny* sizeof(float*));
for (j=0; j<Ny; j++) {
	m[j] = (float *) malloc (Nx* sizeof(float)); 
}

m[j][i] = ....;

che è conveniente se le righe non sono (come qui) tutte della stessa 
lunghezza. 

Non ho mai capito la dichiarazione

float m[3][5];

che in effetti equivale alla prima soluzione e non può essere fatta 
dinamicamente...


-- 
Franco Bagnoli (franchino) <franco.bagnoli@unifi.it> (bagnoli@dma.unifi.it)
virtual location: Dipartimento di Energetica "S. Stecco"
ultra-virtual affiliation: Centro Dinamiche Complesse (CSDC-Firenze)
real location: Dip. Matematica Applicata "G. Sansone", Universita' Firenze,
Via S. Marta, 3 I-50139 Firenze, Italy. Tel. +39 0554796422, fax: +39 055471787




Maggiori informazioni sulla lista flug-tech