[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