Prima di tutto, penso che in realtà desideri 3 elenchi AudioBuffer, non un elenco AudioBuffer con 3 membri AudioBuffer. Un AudioBuffer rappresenta un singolo canale di dati, quindi se hai 3 file audio stereo, dovresti inserirli in 3 elenchi AudioBuffer, con ciascun elenco con 2 AudioBuffer, un buffer per il canale sinistro e uno per il diritto. Il tuo codice elaborerebbe quindi ogni lista (e i suoi rispettivi dati di canale) separatamente, e potresti memorizzare gli elenchi in un NSArray o qualcosa del genere.
Tecnicamente, non c'è ragione per cui non si può avere un unico elenco buffer con 3 canali audio interfogliati (nel senso che sia la sinistra & canale destro vengono memorizzati in un singolo buffer di dati), ma questo va contro l'uso convenzionale di l'API e sarà un po 'confuso.
In ogni caso, questa parte dell'API CoreAudio è più C-ish di Objective-C-ish, quindi si dovrebbe usare malloc/free invece di alloc/release. Il codice dovrebbe essere simile a questa:
#define kNumChannels 2
AudioBufferList *bufferList = (AudioBufferList*)malloc(sizeof(AudioBufferList) * kNumChannels);
bufferList->mNumberBuffers = kNumChannels; // 2 for stereo, 1 for mono
for(int i = 0; i < 2; i++) {
int numSamples = 123456; // Number of sample frames in the buffer
bufferList->mBuffers[i].mNumberChannels = 1;
bufferList->mBuffers[i].mDataByteSize = numSamples * sizeof(Float32);
bufferList->mBuffers[i].mData = (Float32*)malloc(sizeof(Float32) * numSamples);
}
// Do stuff...
for(int i = 0; i < 2; i++) {
free(bufferList->mBuffers[i].mData);
}
free(bufferList);
Il codice di cui sopra è supponendo che si sta leggendo i dati come virgola mobile. Se non si sta eseguendo alcuna elaborazione speciale sui file, è più efficiente leggerli come SInt16 (dati PCM non elaborati), poiché l'iPhone non ha una FPU.
Inoltre, se non si utilizzano gli elenchi al di fuori di un singolo metodo, ha più senso allocarli nello stack anziché nell'heap dichiarandolo come un oggetto normale, non un puntatore. Hai ancora bisogno di malloc() l'effettivo membro mData di AudioBuffer, ma almeno non ti devi preoccupare di liberare() l'effettivo AudioBufferList stesso.
fonte
2010-09-22 11:50:24
Grazie. Quindi, se ho canali audio intercalati, dovrei creare 3 distinti AudioBufferList con un singolo AudioBuffer, giusto? Ma allora qual è il punto di usare AudioBufferLists? Se capisco quello che dici correttamente, starei meglio con 3 AudioBuffer (e senza AudioBufferLists) - almeno in questo caso. –
Sì, sarebbe corretto. Il punto di utilizzo di AudioBufferList è quello di semplificare la gestione dei dati multicanale, in quanto solitamente i dati interlacciati sono un vero problema per le operazioni DSP. È molto più bello avere canali stereo separati con ciascun canale nel proprio buffer. Immagina di lavorare con un segnale stereo 4.1 - allora avresti un buffer singolo con 5 canali interlacciati! Non troppo divertente con cui lavorare. –
Ah, ma non ho detto di non utilizzare interamente AudioBufferList. Anche se può sembrare sciocco passare un singolo AudioBuffer all'interno di una AudioBufferList, è molto più facile passare all'interno dell'API CoreAudio. Inoltre, la struttura AudioBufferList non impone un sovraccarico di memoria. –