确定核心音频AudioBuffer中的帧数 [英] Determine Number of Frames in a Core Audio AudioBuffer

查看:411
本文介绍了确定核心音频AudioBuffer中的帧数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试访问iPhone / iPad上的音频文件的原始数据。我有以下代码,这是我需要的路径的基本开始。但是,一旦我有了一个AudioBuffer,我就会感到难过。

I am trying to access the raw data for an audio file on the iPhone/iPad. I have the following code which is a basic start down the path I need. However I am stumped at what to do once I have an 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指针的事情,所以在这种情况下对它的帮助也会很棒!

Essentially I don't know how to tell how many frames each buffer contains so I can't reliably extract the data from them. I am new to working with raw audio data so I'm open to any suggestions in how to best read the mData property of the AudioBuffer struct. I also haven't done much with void pointers in the past so help with that in this context would be great too!

推荐答案

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

audioBuffer.mDataByteSize tells you the size of the buffer. Did you know this? Just incase you didn't you can't have looked at the declaration of struct AudioBuffer. You should always look at the header files as well as the docs.

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

For the mDataByteSize to make sense you must know the format of the data. The count of output values is mDataByteSize/sizeof(outputType). However, you seem confused about the format - you must have specified it somewhere. First of all you treat it as a 16bit signed int

SInt16 * frames = audioBuffer.mData

然后你将它视为32位浮点数

then you treat it as 32 bit float

Float32 currentFrame = frames [i] / 32768.0f

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

inbetween you assume that there are 24000 values, of course this will crash if there aren't exactly 24000 16bit values. Also, you refer to the data as 'frames' but what you really mean is samples. Each value you call 'currentFrame' is one sample of the audio. 'Frame' would typically refer to a block of samples like .mData

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

So, assuming the data format is 32bit Float (and please note, i have no idea if it is, it could be 8 bit int, or 32bit Fixed for all i know)

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,但是我把它留下来清楚。

Note, sizeof(Float32) is always 4, but i left it in to be clear.

这篇关于确定核心音频AudioBuffer中的帧数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆