Domanda

Sto tentando di accedere ai dati grezzi di un file audio su iPhone/iPad.Ho il seguente codice che è un inizio di base lungo il percorso di cui ho bisogno.Tuttavia sono perplesso su cosa fare una volta che ho un AudioBuffer.

AVAssetReader *assetReader = [AVAssetReader assetReaderWithAsset:urlAsset error:nil];
AVAssetReaderTrackOutput *assetReaderOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:[[urlAsset tracks] objectAtIndex:0] outputSettings:nil];
[assetReader addOutput:assetReaderOutput];
[assetReader startReading];

CMSampleBufferRef ref;
NSArray *outputs = assetReader.outputs;
AVAssetReaderOutput *output = [outputs objectAtIndex:0];
int y = 0;
while (ref = [output copyNextSampleBuffer]) {
    AudioBufferList audioBufferList;
    CMBlockBufferRef blockBuffer;
    CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(ref, NULL, &audioBufferList, sizeof(audioBufferList), NULL, NULL, 0, &blockBuffer);
    for (y=0; y<audioBufferList.mNumberBuffers; y++) {
        AudioBuffer audioBuffer = audioBufferList.mBuffers[y];
        SInt16 *frames = audioBuffer.mData;
        for(int i = 0; i < 24000; i++) { // This sometimes crashes
            Float32 currentFrame = frames[i] / 32768.0f;
        }
    }
}

Essenzialmente non so come sapere quanti fotogrammi contiene ciascun buffer, quindi non posso estrarre in modo affidabile i dati da essi.Sono nuovo nel lavorare con dati audio grezzi, quindi sono aperto a qualsiasi suggerimento su come leggere al meglio la proprietà mData della struttura AudioBuffer.Inoltre, non ho fatto molto con i puntatori void in passato, quindi anche un aiuto in questo contesto sarebbe fantastico!

È stato utile?

Soluzione

audioBuffer.mDataByteSize indica la dimensione del buffer.conosci questo?Nel caso in cui non l'avessi fatto, non avresti potuto guardare la dichiarazione della struttura AudioBuffer.Dovresti sempre guardare i file di intestazione e i documenti.

Affinché mDataByteSize abbia senso è necessario conoscere il formato dei dati.Il conteggio dei valori di output è mDataByteSize/sizeof(outputType).Tuttavia, sembri confuso riguardo al formato: devi averlo specificato da qualche parte.Prima di tutto lo tratti come un firmato int a 16 bit

SInt16 *frames = audioBuffer.mData

quindi lo tratti come float a 32 bit

Float32 currentFrame = frames[i] / 32768.0f

nel frattempo presumi che ci siano 24000 valori, ovviamente questo si bloccherà se non ci sono esattamente 24000 valori a 16 bit.Inoltre, ti riferisci ai dati come "frame", ma ciò che intendi veramente sono campioni.Ogni valore che chiami "currentFrame" è un campione dell'audio."Frame" si riferisce in genere a un blocco di campioni come .mData

Quindi, presupponendo che il formato dei dati sia 32 bit Float (e tieni presente che non ho idea se lo sia, potrebbe essere 8 bit int o 32 bit Fixed per quanto ne so)

for( int y=0; y<audioBufferList.mNumberBuffers; y++ )
{
  AudioBuffer audioBuffer = audioBufferList.mBuffers[y];
  int bufferSize = audioBuffer.mDataByteSize / sizeof(Float32);
  Float32 *frame = audioBuffer.mData;
  for( int i=0; i<bufferSize; i++ ) {
    Float32 currentSample = frame[i];
  }
}

Nota, sizeof(Float32) è sempre 4, ma l'ho lasciato per essere chiari.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top