我一直在为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));
InputCallback功能:
AudioUnit rioUnit = THIS->ioUnit;
OSStatus renderErr;
UInt32 bus1 = 1;
renderErr = AudioUnitRender(rioUnit, ioActionFlags, inTimeStamp, bus1, inNumberFrames, THIS->bufferList);
有几点需要注意:
再次感谢,你们都很棒!
德米特里
答案 0 :(得分:5)
如果每帧有2个频道,则不能将bytesPerSample
作为帧的大小。由于术语有点令人困惑:
基本上,您需要bytesPerSample * mChannelsPerFrame
使用mBytesPerFrame
,mBytesPerFrame * mFramesPerPacket
使用mBytesPerPacket
。
此外,我注意到您使用的是32位样本大小。我不确定你是否真的想这样做 - 通常,你想用16位样本录制音频。大多数听众几乎不可能听到16和32位音频之间的声音差异(平均CD是以44.1kHz,16位PCM为主),它将为您节省50%的I / O和存储成本。 / p>
答案 1 :(得分:0)
一个区别是Tyson的RemoteIO博客文章每个线性PCM样本使用2个字节。所以这可能是格式不兼容的错误。
答案 2 :(得分:0)
第bufferList = (AudioBufferList *)malloc(sizeof(AudioBuffer));
行也是错误的。由于AudioBuffer小于AudioBufferList,因此它分配的内存不足。