PDA

View Full Version : [c] un suggerimento su malloc


Duchamp
19-11-2010, 17:54
Ciao a tutto il forum,
sono alle prese con la lettura di un wave. Non voglio tediarvi con specifiche, header o cose strane, vi dirò solo che c'è un'informazione relativa alla lunghezza in byte del file:

Subchunk2Size == NumSamples * NumChannels * BitsPerSample/8

In poche parole questo Subchunk2size contiene la dimensione del wave considerando anche il numero di campioni, di canali, il bitrate e così via. Insomma, le info giuste per allocare un array in memoria.

Ma ecco il mio dubbio: essendo una dimensione in byte, io allocherò con:


float *wave = (float *) malloc(Subchunk2Size * sizeof(float))


oppure semplicemente


float *wave = (float *) malloc(Subchunk2Size)


?

Naturalmente il mio esempio usa float, perchè immagino di avere un wave con campioni in virgola mobile.
Io sono più propenso verso la seconda modalità, ma i dubbi mi assalgono.
Ringrazio per qualsiasi delucidazione possiate darmi :)

Supdario
19-11-2010, 19:16
La seconda opzione andrebbe bene solo nel caso Subchunk2Size fosse divisibile per 4 byte (32bit). Cosa che dovrebbe essere fattibile, se il caso è questo:
44100 Hz, 2 canali, 32 bit float

Ovviamente potrai accedere al vettore solo a gruppi di float (wave[0], wave[1], ecc...).

In ogni caso ti suggerirei di usare un'altra struttura (possibilmente binaria). Anche se non ho capito bene quello che vuoi fare, mi sembra concettualmente sbagliato.

Duchamp
19-11-2010, 19:32
Ciao Supdario, molto interessante quanto hai scritto.
Parto chiarendo meglio quello che vorrei fare: semplicemente mettere in un array tutti i dati "sonori", escludendo naturalmente l'header che non mi interessa.
L'accesso a gruppi va benissimo, ma sono curioso di capire meglio l'idea della struttura binaria...

Supdario
20-11-2010, 14:01
Ciao Supdario, molto interessante quanto hai scritto.
Parto chiarendo meglio quello che vorrei fare: semplicemente mettere in un array tutti i dati "sonori", escludendo naturalmente l'header che non mi interessa.
L'accesso a gruppi va benissimo, ma sono curioso di capire meglio l'idea della struttura binaria...

Molto semplice, si tratta semplicemente di un modo più preciso per accedere ai singoli chuck, in modo da poter scegliere in modo selettivo non solo la posizione del chunk, ma anche il canale e l'unità di tempo
Supponiamo ad esempio di avere un file stereo (2 canali), profondità 32bit float e 44100 Hz di campionamento. Idealmente se hai un file audio che dura 100 secondi potresti accedere così:
float wave[canale(0-1)][tempo(0-99)][campione(0-44099)]

Anche se posso ammettere che quest'ultima soluzione (soprattutto per il fatto del tempo e campioni distinti) potrebbe non essere adeguata, quindi si potrebbe fare così:
float wave[canale(0-1)][n.chunk(da 0 a 44100*durata)]

In definitiva, la soluzione migliore sarebbe questa, supponendo che in "canali" c'è il numero dei canali, ed in "frequenza" c'è la frequenza di campionamento

int canali = 2;
int frequenza = 44100;
int durata = 120; //2 minuti
int chunksize = frequenza * canali * sizeof(float);
float **wave = (float **) malloc(sizeof(float*) * canali);
int i;
for (i = 0; i < canali; i++) wave[i] = (float *) malloc(chunksize * durata);

In questo modo hai una matrice a più canali, quindi supponendo di avere un file stereo, accedi all'ultimo campionamento del terzo secondo nel primo canale in questo modo:
wave[0][2*frequenza + 44099] = wave[0][2*44100 + 44099] = wave[0][132299]

Spero di essere stato abbastanza chiaro, se hai bisogno chiedi pure. :D