设置带有单声道输入和立体声输出的音频单元iOS [英] Setting up audio unit iOS with mono input and stereo output

查看:179
本文介绍了设置带有单声道输入和立体声输出的音频单元iOS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试设置一个具有单声道输入和立体声输出功能的音频单元。打算通过左声道输出播放正弦波音调,并通过右声道输出定期播放不同的符号波。

I'm trying to set up an audio unit capable of mono input and stereo output. Intend on playing a sine wave tone through the left channel output and a different sign wave periodically through the right channel out.

我收到错误消息,

'NSInternalInconsistencyException', reason: ' Error initialing unit: -50;

当我尝试在此处初始化音频单元时,

when I attempt to initialize my audio unit here,

// Initialize audio unit
OSErr err = AudioUnitInitialize(self.ioUnit);
NSAssert1(err == noErr, @"Error initializing unit: %hd", err);

我相信这与我如何设置音频单元有关

I believe it has to do with how I am setting up the audio unit,

// Audio component description
AudioComponentDescription desc;
desc.componentType          = kAudioUnitType_Output;
desc.componentSubType       = kAudioUnitSubType_RemoteIO;
desc.componentManufacturer  = kAudioUnitManufacturer_Apple;
desc.componentFlags         = 0;
desc.componentFlagsMask     = 0;

// Get component
AudioComponent inputComponent = AudioComponentFindNext(NULL, &desc);

// Get Audio units
AudioComponentInstanceNew(inputComponent, &ioUnit);

// Enable input, which disabled by default. Output enable by default
UInt32 enableInput = 1;
AudioUnitSetProperty(ioUnit,
                     kAudioOutputUnitProperty_EnableIO,
                     kAudioUnitScope_Input,
                     kInputBus,
                     &enableInput,
                     sizeof(enableInput));

AudioStreamBasicDescription monoStreamFormat;
monoStreamFormat.mSampleRate          = 44100.00;
monoStreamFormat.mFormatID            = kAudioFormatLinearPCM;
monoStreamFormat.mFormatFlags         = kAudioFormatFlagsAudioUnitCanonical;
monoStreamFormat.mBytesPerPacket      = 2;
monoStreamFormat.mBytesPerFrame       = 2;
monoStreamFormat.mFramesPerPacket     = 1;
monoStreamFormat.mChannelsPerFrame    = 1;
monoStreamFormat.mBitsPerChannel      = 16;

// Apply format to input of ioUnit
AudioUnitSetProperty(ioUnit,
                     kAudioUnitProperty_StreamFormat,
                     kAudioUnitScope_Input,
                     kInputBus,
                     &monoStreamFormat,
                     sizeof(monoStreamFormat));


AudioStreamBasicDescription stereoStreamFormat;
stereoStreamFormat.mSampleRate          = 44100.00;
stereoStreamFormat.mFormatID            = kAudioFormatLinearPCM;
stereoStreamFormat.mFormatFlags         = kAudioFormatFlagsAudioUnitCanonical;
stereoStreamFormat.mBytesPerPacket      = 4;
stereoStreamFormat.mBytesPerFrame       = 4;
stereoStreamFormat.mFramesPerPacket     = 1;
stereoStreamFormat.mChannelsPerFrame    = 2;
stereoStreamFormat.mBitsPerChannel      = 32;

// Apply format to output of ioUnit
AudioUnitSetProperty(ioUnit,
                     kAudioUnitProperty_StreamFormat,
                     kAudioUnitScope_Output,
                     kOutputBus,
                     &stereoStreamFormat,
                     sizeof(stereoStreamFormat));

// Set input callback
AURenderCallbackStruct callbackStruct;
callbackStruct.inputProc = inputCallback;
callbackStruct.inputProcRefCon = (__bridge void *)(self);
AudioUnitSetProperty(ioUnit,
                     kAudioUnitProperty_SetRenderCallback,
                     kAudioUnitScope_Global,
                     kInputBus,
                     &callbackStruct,
                     sizeof(callbackStruct));

// Set output callback
callbackStruct.inputProc = outputCallback;
callbackStruct.inputProcRefCon = (__bridge void *)(self);
AudioUnitSetProperty(ioUnit,
                     kAudioUnitProperty_SetRenderCallback,
                     kAudioUnitScope_Global,
                     kOutputBus,
                     &callbackStruct,
                     sizeof(callbackStruct));

但我在错误代码-50上找不到任何东西,它正在回馈,所以我没有确定它不喜欢什么。我的工作期限很紧,所以对它的帮助将不胜感激。

but I couldn't find anything on the error code -50 it's giving back so I'm not sure what it doesn't like. I'm on a deadline so any help it greatly appreciated.

推荐答案

kAudioFormatFlagsAudioUnitCanonical是32位8.24定点格式。这意味着对于单声道,mBytesPerFrame应该为4,对于立体声应该为8,对于立体声和单声道,mBitsPerChannel应该为32。将其设置为16位可能会产生此错误。

kAudioFormatFlagsAudioUnitCanonical is 32-bit 8.24 fixed point format. That means mBytesPerFrame should be 4 for mono and 8 for stereo, and mBitsPerChannel should be 32 for both stereo and mono. Setting it to 16-bits for would probably produce this error.

话说,我怀疑你想要8.24。您可能希望kAudioFormatFlagsCanonical获得标准的16位音频。或者,如果需要32位,请使用32位浮点数(kAudioFormatFlagIsFloat | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsNonInterleaved)。在处理过程中更容易处理数学。

That said, I doubt you want 8.24. You probably want kAudioFormatFlagsCanonical to get standard 16-bit audio. Or, if you want 32 bit, go with 32-bit float (kAudioFormatFlagIsFloat | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsNonInterleaved). Easier to deal with the math during your processing.

此外,您正在虚拟输入和输出而不是客户端输入和输出上设置格式,我不这样做。想不到你想要的。这里的API相当混乱,但是要设置客户端输入格式,请使用kAudioUnitScope_Input,kOutputBus。此处的逻辑是,您要设置内部核心音频 input 转换器单元的 output 的格式,从代码的角度来看,它是输入音频。令人困惑,我知道。有关更多详细信息,请参见音频单元文档。同样,要设置客户端输出格式,请使用kAudioUnitScope_Output,kInputBus。

Also, you are setting the formats on the virtual inputs and outputs rather than the client inputs and outputs, which I don't think is what you want. The API here is rather confusing, but to set client input format, use kAudioUnitScope_Input, kOutputBus. The logic here is that you're setting the format of the output of the internal Core Audio input converter unit, which, from the perspective of your code, is the input audio. Confusing, I know. See Audio Unit docs for more detail. Likewise, to set client output format, use kAudioUnitScope_Output, kInputBus.

这篇关于设置带有单声道输入和立体声输出的音频单元iOS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆