ios - 确定核心音频 AudioBuffer 中的帧数

标签 ios core-audio avfoundation pcm void-pointers

我正在尝试访问 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 告诉您缓冲区的大小。你知道吗?以防万一您没有查看结构 AudioBuffer 的声明。您应该始终查看头文件和文档。

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

SInt16 *frames = audioBuffer.mData

然后你把它当作32位 float

Float32 currentFrame = frames[i]/32768.0f

中间假设有 24000 个值,当然,如果没有恰好有 24000 个 16 位值,这将崩溃。此外,您将数据称为“帧”,但您真正的意思是样本。您称为“currentFrame”的每个值都是音频的一个样本。 “Frame”通常指的是样本 block ,例如 .mData

所以,假设数据格式是 32 位 float (请注意,我不知道它是否是 8 位整数,或者据我所知是 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,但为了清楚起见,我将其保留。

关于ios - 确定核心音频 AudioBuffer 中的帧数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4299419/

相关文章:

ios - 在自定义 View 下确定 Controller 代码的范围是一个好的 Cocoa 设计模式吗?

ios - 构建 Xcode UITest 失败并显示 `error opening input file`

ios - 我将如何为 SKPaymentQueue 使用未弃用的 API?

iphone - 在后台获取可达性更改通知

ios - 该算法如何计算 rgb 颜色?

objective-c - iOS AVFoundation 将视频流式传输到 OpenGL 纹理

ios - AVFoundation 将第一帧添加到视频

ios - 记录用户输入并翻译为 iPhone 文本

ios - 应用程序在后台录制时连接蓝牙耳机会导致录制停止

ios - EZAudio 框架 -"Error: Couldn' t 初始化输出单元 ('fmt?' )"