繁体   English   中英

确定核心音频AudioBuffer中的帧数

[英]Determine Number of Frames in a Core Audio AudioBuffer

我试图在iPhone / iPad上访问音频文件的原始数据。 我有以下代码,这是我需要的路径的基本开始。 但是,一旦我有了一个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;
        }
    }
}

基本上我不知道如何判断每个缓冲区包含多少帧,因此我无法从它们中可靠地提取数据。 我是处理原始音频数据的新手,所以我愿意接受有关如何最好地读取AudioBuffer结构的mData属性的任何建议。 我在过去也没有做过很多关于void指针的事情,所以在这种情况下对它的帮助也会很棒!

audioBuffer.mDataByteSize告诉您缓冲区的大小。 你知道吗? 只是因为你没有,你不能看看struct AudioBuffer的声明。 您应该始终查看头文件以及文档。

要使mDataByteSize有意义,您必须知道数据的格式。 输出值的计数是mDataByteSize / sizeof(outputType)。 但是,您似乎对格式感到困惑 - 您必须在某处指定它。 首先,您将其视为16位签名int

SInt16 *frames = audioBuffer.mData

然后你把它当作32位浮点数

Float32 currentFrame = frames[i] / 32768.0f

inbetween你假设有24000个值,当然如果没有24000个16bit值,这将会崩溃。 此外,您将数据称为“帧”,但您真正的意思是样本。 您称为“currentFrame”的每个值都是音频的一个示例。 'Frame'通常指的是像.mData这样的样本块

因此,假设数据格式是32位浮点数(请注意,我不知道它是否,它可能是8位int,或32位固定所有我知道)

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];
  }
}

注意,sizeof(Float32)总是4,但我把它留下来清楚。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM