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

时间:2010-12-07 07:32:51

标签: 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;

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

有几点需要注意:

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

再次感谢,你们都很棒!

德米特里

3 个答案:

答案 0 :(得分:5)

如果每帧有2个频道,则不能将bytesPerSample作为帧的大小。由于术语有点令人困惑:

  • 样本是波形中给定位置的单个值
  • 频道是指与特定音频流相关联的数据,即立体声的左/右声道,单声道的单声道等等。
  • 包含波形中给定位置的所有通道的样本
  • 数据包包含一个或多个框架

基本上,您需要bytesPerSample * mChannelsPerFrame使用mBytesPerFramemBytesPerFrame * 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,因此它分配的内存不足。