ios - AudioUnit inputCallback 与 AudioUnitRender -> audioBufferList.mBuffers[0].mDataByteSize 之间不匹配!= inNumberFrames
问题描述
我们正在使用 AudioUnits 输入回调来处理传入的缓冲区。音频单元设置主要取自
https://github.com/robovm/apple-ios-samples/blob/master/aurioTouch/Classes/AudioController.mm
我在音频回调中添加了一些健全性检查。看起来像这样
/// The audio input callback
static OSStatus audioInputCallback(void __unused *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 __unused inBusNumber,
UInt32 inNumberFrames,
AudioBufferList __unused *ioData)
{
OSStatus err = noErr;
if(!*callbackData.audioChainIsBeingReconstructed)
{
// we are calling AudioUnitRender on the input bus of AURemoteIO
// this will store the audio data captured by the microphone in cd.audioBufferList
err = AudioUnitRender(callbackData.audioUnit, ioActionFlags, inTimeStamp, kInputBus, inNumberFrames, &callbackData.audioBufferList);
// check if the sample count is set correctly
assert(callbackData.audioBufferList.mBuffers[0].mDataByteSize == inNumberFrames * sizeof(float));
// Assert that we only received one buffer
assert(callbackData.audioBufferList.mNumberBuffers == 1);
// Copy buffer
TPCircularBufferCopyAudioBufferList(callbackData.buffer, &callbackData.audioBufferList, inTimeStamp, kTPCircularBufferCopyAll, NULL);
}
return err;
}
现在有时语句会assert(callbackData.audioBufferList.mBuffers[0].mDataByteSize == inNumberFrames * sizeof(float));
失败,因为缓冲区不同。
有人对这种现象有解释吗?
解决方案
这是 iOS 上的正常行为。iOS 音频单元回调可以更改缓冲区大小中提供的帧数,使其与原始缓冲区大小不同。当操作系统状态发生变化、音频硬件状态发生变化或可用的硬件格式与您的音频格式请求不完全匹配时,就会发生这种情况。
因此,必须编写所有音频单元回调以处理来自请求值或先前回调值的可变数量的 inNumberFrames。
推荐阅读
- django - django 从管理面板中选择模板而不重新启动服务器
- json - 如何将 Elastic Search Index 中的所有数据以 JSON 格式导出到指定 _id 字段的文件?
- duplicates - ClickHouse - 将相似条目合并到一个新条目中
- c# - Async 和 await 可能会被省略?
- java - 如何优雅地结束对话?
- sql-server - 扩展事件需要哪些权限?
- windows - Windows 计划任务执行
- java - 从远程服务流式传输音频并在扬声器中播放
- c++ - 二叉树中 shared_ptr 的“双重释放或损坏”
- airflow - 无法在 Web UI 中看到 DAG