2010-11-28 13 views
7

Ich versuche, auf die Rohdaten für eine Audiodatei auf dem iPhone/iPad zuzugreifen. Ich habe den folgenden Code, der ein grundlegender Anfang auf dem Weg ist, den ich brauche. Allerdings bin ich ratlos, was ich tun soll, wenn ich einen AudioBuffer habe.Ermitteln der Anzahl der Frames in einem Core Audio 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; 
     } 
    } 
} 

Im Grunde weiß ich nicht, wie zu sagen, wie viele Frames jeder Puffer enthält, so kann ich nicht zuverlässig die Daten aus ihnen extrahieren. Ich bin neu in der Arbeit mit rohen Audiodaten, daher bin ich offen für Vorschläge, wie man die mData-Eigenschaft der AudioBuffer-Struktur am besten liest. Ich habe auch in der Vergangenheit nicht viel mit Void-Zeigern gemacht, also wäre die Hilfe in diesem Zusammenhang auch großartig!

+0

Ausgezeichnete Frage! Ihre Frage hat mir geholfen, mein ähnliches Problem zu lösen. – user523234

+0

du leckst blockBuffer –

Antwort

13

audioBuffer.mDataByteSize teilt Ihnen die Größe des Puffers mit. Wusstest du das? Nur wenn du es nicht getan hättest, hättest du dir die Deklaration von struct AudioBuffer nicht ansehen können. Sie sollten sich immer die Header-Dateien und die Dokumente ansehen.

Damit die mDataByteSize sinnvoll ist, müssen Sie das Format der Daten kennen. Die Anzahl der Ausgabewerte ist mDataByteSize/sizeof (outputType). Sie scheinen jedoch über das Format verwirrt zu sein - Sie müssen es irgendwo angegeben haben. Zu allererst Sie es behandeln, als ein 16-Bit-int

SInt16 *frames = audioBuffer.mData unterzeichnet

dann behandeln Sie es als 32-Bit-Float

Float32 currentFrame = frames[i]/32768.0f

Inbetween Sie davon ausgehen, dass es 24000 Werte, natürlich dieser Wille Absturz wenn es nicht genau 24000 16bit Werte gibt. Außerdem bezeichnen Sie die Daten als "Frames", aber was Sie wirklich meinen, sind Samples. Jeder Wert, den Sie 'currentFrame' nennen, ist ein Beispiel für das Audio. 'Frame' würde sich normalerweise auf einen Block von Samples beziehen, wie .mData

Also angenommen, das Datenformat ist 32bit Float (und bitte beachten Sie, ich habe keine Ahnung, wenn es ist, könnte es 8 Bit int oder 32bit Fixed sein für alle, die ich kenne)

Hinweis, sizeof (Float32) ist immer 4, aber ich habe es klar zu sein.

+0

audioBuffer.mDataByteSize/sizeof (Float32) war der Teil, den ich brauchte, danke! – macinjosh

+0

Wenn Sie mit cmd-click auf AudioBuffer klicken, sollte xcode zur strikten Deklaration in der Header-Datei springen. Nützlich, um herauszufinden, womit Sie es zu tun haben. – hooleyhoop

+4

Ein Digression, aber die Core Audio Definition eines Frames ist ein Beispiel für alle Kanäle. – sbooth

Verwandte Themen