使用扩展音频文件服务 (ExtAudioFileRead) 读取音频

Posted

技术标签:

【中文标题】使用扩展音频文件服务 (ExtAudioFileRead) 读取音频【英文标题】:Reading audio with Extended Audio File Services (ExtAudioFileRead) 【发布时间】:2010-03-15 20:29:10 【问题描述】:

我正在努力理解 Core Audio,或者更确切地说:Extended Audio File Services

在这里,我想使用ExtAudioFileRead() 从文件中读取一些音频数据。 只要我使用一个巨大的缓冲区来存储我的音频数据(即一个AudioBuffer),这就可以正常工作。只要我使用多个AudioBufferExtAudioFileRead() 就会返回错误代码-50(“参数列表中的错误”)。据我所知,这意味着ExtAudioFileRead() 的论点之一是错误的。应该是audioBufferList

我不能使用一个巨大的缓冲区,因为那样的话,dataByteSize 会溢出它的 UInt32-integer 范围与巨大的文件。

这里是创建audioBufferList的代码:

AudioBufferList *audioBufferList;
audioBufferList = malloc(sizeof(AudioBufferList) + (numBuffers-1)*sizeof(AudioBuffer));
audioBufferList->mNumberBuffers = numBuffers;
for (int bufferIdx = 0; bufferIdx<numBuffers; bufferIdx++ ) 
    audioBufferList->mBuffers[bufferIdx].mNumberChannels = numChannels;
    audioBufferList->mBuffers[bufferIdx].mDataByteSize = dataByteSize;
    audioBufferList->mBuffers[bufferIdx].mData = malloc(dataByteSize);

这是有效但溢出的代码:

UInt32 dataByteSize = fileLengthInFrames * bytesPerFrame; // this will overflow
AudioBufferList *audioBufferList = malloc(sizeof(audioBufferList));
audioBufferList->mNumberBuffers = 1;
audioBufferList->mBuffers[0].mNumberChannels = numChannels;
audioBufferList->mBuffers[0].mDataByteSize = dataByteSize;
audioBufferList->mBuffers[0].mData = malloc(dataByteSize);

最后,ExtAudioFileRead() 的调用(应该适用于两个版本):

UInt32 numFrames = fileLengthInFrames;
error = ExtAudioFileRead(extAudioFileRef,
                         &numFrames,
                         audioBufferList);

你知道我在这里做错了什么吗?

【问题讨论】:

【参考方案1】:

我认为您误解了 mNumberBuffers 字段的用途。对于单声道和交错立体声数据,它通常是 1。您将其设置为其他值的唯一原因是多轨数据,其中每个通道位于单独的数据缓冲区中。

如果你想读取文件的一部分,你可以将缓冲区的 dataByteSize 设置为合理的大小,当你读取文件时,告诉 API 只给你那么多字节,然后循环遍历它。

【讨论】:

那么,有没有mNumberBuffers不是1的使用场景? 我不确定这个参数是否正确,因为在 aurioTouch2 示例中,mNumberBuffers 设置为 2,我想知道是否有人知道原因。 顺便说一句,如果我想同时对缓冲区进行编码或解码,我该如何在单独的线程中完成这项工作【参考方案2】:

我也有同样的问题 mNumberBuffers > 1,,... 我的工作涉及创建自己的内部缓冲区:

类似:

char buffer1[byteSize]; 字符缓冲区2[字节大小]; ......

你也可以使用指针让事情变得更简单,..like:

缓冲区[索引][字节大小];

然后您必须手动遍历它们并在主线程中填充它们以避免音频故障。

ExtAudioFileRead 只会填充 AudioBufferList 中的缓冲区 [0],然后您可以让它在音频播放时指向不同的手动分配的缓冲区。

希望这会有所帮助。

【讨论】:

这并不是我想要做的,但如果你想用不同的数据填充几个不同的缓冲区,它肯定会有所帮助。 (我最初的想法是我可以用同一文件中的连续数据块填充多个缓冲区)。【参考方案3】:

mNumberBuffers == 2 当您处理非交错立体声时。它是未交错时的音频通道数。

【讨论】:

【参考方案4】:

Cocoa 似乎根本不接受 mNumberBuffers > 1。这是一种耻辱,因为它使整个结构无用。 (我希望这是对的……)

【讨论】:

这不是真的。我相信 mNumberBuffers>1 用于多声道音频。只是 AudioBufferList 结构的其余部分必须有意义。

以上是关于使用扩展音频文件服务 (ExtAudioFileRead) 读取音频的主要内容,如果未能解决你的问题,请参考以下文章

如何为 Web 应用程序托管音频文件

音频文件有哪些后缀名?

iOS:从通知扩展播放远程音频文件

如何在音频单元扩展(实时进程)中为音频文件播放分配内存?

android 图片选择,可选择图片,视频,音频,文件,方便扩展

android 图片选择,可选择图片,视频,音频,文件,方便扩展