我一直在为 iOS 开发一个频率检测应用程序,但在使用来自麦克风的音频样本填充用户定义的 AudioBufferList 时遇到问题。
当我在 InputCallback 方法中调用 AudioUnitRender 时,返回码为 -50。我相信这意味着我的参数之一无效。我猜它是 AudioBufferList,但我无法弄清楚它有什么问题。我想我已经对其进行了设置,使其与我在 ASBD 中指定的数据格式相匹配。
以下是我认为可能不正确的远程 I/O 设置和函数调用:
ASBD:
size_t bytesPerSample = sizeof(AudioUnitSampleType);
AudioStreamBasicDescription localStreamFormat = {0};
localStreamFormat.mFormatID = kAudioFormatLinearPCM;
localStreamFormat.mFormatFlags = kAudioFormatFlagsAudioUnitCanonical;
localStreamFormat.mBytesPerPacket = bytesPerSample;
localStreamFormat.mBytesPerFrame = bytesPerSample;
localStreamFormat.mFramesPerPacket = 1;
localStreamFormat.mBitsPerChannel = 8 * bytesPerSample;
localStreamFormat.mChannelsPerFrame = 2;
localStreamFormat.mSampleRate = sampleRate;
InputCallback 声明:
err = AudioUnitSetProperty(ioUnit, kAudioOutputUnitProperty_SetInputCallback,
kAudioUnitScope_Input,
kOutputBus, &callbackStruct, sizeof(callbackStruct));
AudioBufferList 声明:
// Allocate AudioBuffers
bufferList = (AudioBufferList *)malloc(sizeof(AudioBuffer));
bufferList->mNumberBuffers = 1;
bufferList->mBuffers[0].mNumberChannels = 2;
bufferList->mBuffers[0].mDataByteSize = 1024;
bufferList->mBuffers[0].mData = calloc(256, sizeof(uint32_t));
输入回调函数:
AudioUnit rioUnit = THIS->ioUnit;
OSStatus renderErr;
UInt32 bus1 = 1;
renderErr = AudioUnitRender(rioUnit, ioActionFlags, inTimeStamp, bus1, inNumberFrames, THIS->bufferList);
需要注意的几点:
- 采样率 = 22050 赫兹
- 由于远程 I/O 数据的规范格式是 8.24 位定点,我假设每个样本是 32 位(或 4 个字节)。由于 unsigned int 是 4 个字节,我使用它来分配我的音频缓冲区。
- 如果我将音频数据流实现为 PassThru 而不是仅输入,我可以获得相同的代码来正确呈现音频。
- 我已经看过Michael Tyson关于远程 I/O的博文。没有看到任何与我正在做的不同的事情。
再次感谢,你们都很棒!
德米特里