输出音频单元的失真

Distortion from output Audio Unit

当我 运行 这个简单的应用程序时,我听到了非常响亮和刺耳的失真声音。我只是简单地实例化一个默认输出单元并分配一个渲染回调。并让程序 运行 在 运行 循环中。我没有检测到 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);

}

您的问题似乎不完整。我不知道消除输出噪声的副作用,这可能只是未定义的行为。我也不知道您的代码将起到什么作用。 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));

另一种可能性是保留未完成的回调,但将 timerAU 声明为 outputUnitDesc.componentSubType = kAudioUnitSubType_HALOutput;
而不是
outputUnitDesc.componentSubType = kAudioUnitSubType_DefaultOutput;
并在通过以下代码设置渲染回调之前明确禁用 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 代码移植,请尝试了解差异。它们有据可查。