输出音频单元的失真

时间:2016-04-30 23:31:54

标签: core-audio

当我运行这个简单的应用程序时,我听到一个非常响亮和刺耳的失真声音。我只是实例化一个默认输出单元并分配一个渲染回调。让程序在runloop中运行。我没有检测到Core Audio没有错误,除了这种失真外,一切正常。

#import <AudioToolbox/AudioToolbox.h>


OSStatus render1(void *inRefCon,
                 AudioUnitRenderActionFlags *ioActionFlags,
                 const AudioTimeStamp *inTimeStamp,
                 UInt32 inBusNumber,
                 UInt32 inNumberFrames,
                 AudioBufferList * ioData)
{
   return noErr;
}

int main(int argc, const char * argv[]) {
   AudioUnit timerAU;
   UInt32 propsize = 0;       

   AudioComponentDescription outputUnitDesc;
   outputUnitDesc.componentType          = kAudioUnitType_Output;
   outputUnitDesc.componentSubType       = kAudioUnitSubType_DefaultOutput;
   outputUnitDesc.componentManufacturer  = kAudioUnitManufacturer_Apple;
   outputUnitDesc.componentFlags         = 0;
   outputUnitDesc.componentFlagsMask     = 0;

   //Get RemoteIO AU from Audio Unit Component Manager
   AudioComponent outputComp = AudioComponentFindNext(NULL, &outputUnitDesc);

   if (outputComp == NULL) exit (-1);

   CheckError(AudioComponentInstanceNew(outputComp, &timerAU), "comp");       

   //Set up render callback function for the RemoteIO AU.
   AURenderCallbackStruct renderCallbackStruct;
   renderCallbackStruct.inputProc = render1;
   renderCallbackStruct.inputProcRefCon = nil;//(__bridge void *)(self);

   propsize = sizeof(renderCallbackStruct);

   CheckError(AudioUnitSetProperty(timerAU,
                                   kAudioUnitProperty_SetRenderCallback,
                                   kAudioUnitScope_Global,
                                   0,
                                   &renderCallbackStruct,
                                   propsize), "set render");

   CheckError(AudioUnitInitialize(timerAU), "init");       

  // tickMethod = completion;

   CheckError(AudioOutputUnitStart(timerAU), "start");

   CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1000, false);

}

1 个答案:

答案 0 :(得分:1)

您的问题似乎并不完整。我不知道消除输出噪声的副作用,这可能只是未定义的行为。我也不知道你的代码会用于什么。 kAudioUnitSubType_DefaultOutput上有一个未完成的渲染回调,它什么都不做(生成静音!)。我知道有两种方法可以使它沉默。

在回调中,ioData缓冲区必须用零显式填充,因为无法保证它们将被初始化为空:

Float32 * lBuffer0;
Float32 * lBuffer1;
lBuffer0 = (Float32 *)ioData->mBuffers[0].mData;
lBuffer1 = (Float32 *)ioData->mBuffers[1].mData;
memset(lBuffer0,  0, inNumberFrames*sizeof(Float32));
memset(lBuffer1,  0, inNumberFrames*sizeof(Float32));

其他可能性是保留未完成的回调,但声明timerAUoutputUnitDesc.componentSubType = kAudioUnitSubType_HALOutput;而不是
outputUnitDesc.componentSubType = kAudioUnitSubType_DefaultOutput;
和explicity在通过以下代码设置渲染回调之前禁用I / O:

UInt32 lEnableIO = 0;
CheckError(AudioUnitSetProperty(timerAU,
                            kAudioOutputUnitProperty_EnableIO,
                            kAudioUnitScope_Output,
                            0,   //output element
                            &lEnableIO,
                            sizeof(lEnableIO)),
"couldn't disable output");

我强烈建议彻底研究CoreAudio API并了解如何设置音频单元。这对于理解这个问题至关重要。我在你的代码中看到了一个提到RemoteIO AU的评论。在OSX中没有像RemoteIO AU这样的东西。如果您正在尝试从iOS代码中获取端口,请尝试了解差异。他们有很好的文件记录。