输出音频单元的失真
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 代码移植,请尝试了解差异。它们有据可查。
当我 运行 这个简单的应用程序时,我听到了非常响亮和刺耳的失真声音。我只是简单地实例化一个默认输出单元并分配一个渲染回调。并让程序 运行 在 运行 循环中。我没有检测到 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 代码移植,请尝试了解差异。它们有据可查。