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

发布于 2024-08-25 09:42:44 字数 1841 浏览 5 评论 0原文

我正在努力理解核心音频,或者更确切地说: 扩展音频文件服务

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

我无法使用一个巨大的缓冲区,因为这样的话,dataByteSize 会因巨大文件而溢​​出其 UInt32 整数范围。

下面是创建 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);

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

I am working on understanding Core Audio, or rather: Extended Audio File Services

Here, I want to use ExtAudioFileRead() to read some audio data from a file.
This works fine as long as I use one single huge buffer to store my audio data (that is, one AudioBuffer). As soon as I use more than one AudioBuffer, ExtAudioFileRead() returns the error code -50 ("error in parameter list"). As far as I can figure out, this means that one of the arguments of ExtAudioFileRead() is wrong. Probably the audioBufferList.

I can not use one huge buffer because then, dataByteSize would overflow its UInt32-integer range with huge files.

Here is the code to create the 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);
}

And here is the working, but overflowing code:

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);

And finally, the call of ExtAudioFileRead() (should work with both versions):

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

Do you know what I am doing wrong here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

醉南桥 2024-09-01 09:42:44

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

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

I think you're misunderstanding the purpose of the mNumberBuffers field. It's typically 1 for mono and interleaved stereo data. The only reason you would set it to something else is for multi-track data where each channel is in a separate data buffer.

If you want to read a part of a file, you would set dataByteSize of the buffer to a reasonable size, and when you read the file, tell the API only to give you that many bytes, and loop over it.

黒涩兲箜 2024-09-01 09:42:44

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

类似于:

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

你也可以使用指针来使事情变得更容易,..例如:

buffer[index][byteSize];

那么您将必须手动迭代它们并在主线程上填充它们以避免音频出现故障。

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

希望这有帮助。

I also had the same problem with mNumberBuffers > 1,,...
My work around involved creating my own internal buffer:

something like:

char buffer1[byteSize];
char buffer2[byteSize];
......

you could also use pointers to make things easier,..like:

buffer[index][byteSize];

then you would have to iterate through them manually and fill them up on the main thread to avoid glitches in audio.

ExtAudioFileRead will only fill buffer[0] in the AudioBufferList, you could then have that pointing to different manually allocated buffers as the audio plays.

hope this helps.

听闻余生 2024-09-01 09:42:44

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

mNumberBuffers == 2 when you're dealing with non-interleaved stereo. It is the number of audio channels when not interleaved.

时光无声 2024-09-01 09:42:44

Cocoa 似乎根本不接受 mNumberBuffers > 1. 这很遗憾,因为它使整个结构变得毫无用处。 (我希望这是对的......)

Cocoa simply seems to not accept mNumberBuffers > 1. Which is a shame as it makes the whole structure useless. (I hope this is right...)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文