使用远程I/O录制,AudioUnitRender -50返回代码

irt*_*d88 5 iphone core-audio audiounit

我一直在为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;
Run Code Online (Sandbox Code Playgroud)

InputCallback声明:

err = AudioUnitSetProperty(ioUnit, kAudioOutputUnitProperty_SetInputCallback, 
                           kAudioUnitScope_Input, 
                           kOutputBus, &callbackStruct, sizeof(callbackStruct));
Run Code Online (Sandbox Code Playgroud)

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));
Run Code Online (Sandbox Code Playgroud)

InputCallback函数:

AudioUnit rioUnit = THIS->ioUnit;
OSStatus renderErr;
UInt32 bus1 = 1;
renderErr = AudioUnitRender(rioUnit, ioActionFlags, inTimeStamp, bus1, inNumberFrames, THIS->bufferList);
Run Code Online (Sandbox Code Playgroud)

有几点需要注意:

  • 采样率= 22050 Hz
  • 由于远程I/O数据的规范格式是8.24位固定点,我假设样本是每个32位(或4个字节).由于unsigned int是4个字节,我用它来分配我的音频缓冲区.
  • 如果我将音频数据流实现为PassThru而不是仅输入,我可以获得相同的代码来正确呈现音频.
  • 我已经看过Michael Tyson关于远程I/O 的博客文章了.没有看到任何与我正在做的事情不同的事情.

再次感谢,你们都很棒!

德米特里

Nik*_*man 5

如果每帧有2个通道,则不能具有bytesPerSample帧的大小.由于术语有点令人困惑:

  • 样品是在波形的给定位置的单个值
  • 信道是指与特定的音频流相关联的数据,即,左立体声/右声道,对于单声道的单个信道等
  • 包含用于在波形的所有信道为一个给定的位置上的样品
  • 包含一个或多个帧

所以基本上,你需要使用bytesPerSample * mChannelsPerFramemBytesPerFrame,并使用mBytesPerFrame * mFramesPerPacketmBytesPerPacket.

另外我注意到你使用32位作为样本大小.我不确定你是否真的想这样做 - 通常,你想用16位样本录制音频.对于大多数听众而言,16位和32位音频之间的声音差异几乎是不可能的(平均CD是以44.1kHz,16位PCM为主),它将为您节省50%的I/O和存储成本.