CoreAudio:AudioUnit 既不能停止也不能未初始化
Posted
技术标签:
【中文标题】CoreAudio:AudioUnit 既不能停止也不能未初始化【英文标题】:CoreAudio: AudioUnit can neither be stopped nor uninitialized 【发布时间】:2016-06-03 14:00:08 【问题描述】:我编写了一个命令行 c 工具,生成一个正弦波并在默认音频输出上使用 CoreAudio 播放它。我正在初始化一个
AURenderCallbackStruct
并使用 AudioUnitInitialize
初始化 AudioUnit(如本论坛中已讨论的那样)。所有这些都按预期工作,但是在关闭程序时,我无法关闭 AudioUnit,既不使用 AudioOutputUnitStop(player.outputUnit);
也不使用 AudioOutputUnitStop(player.outputUnit);
也不
AudioComponentInstanceDispose(player.outputUnit);
这些调用在代码中的出现顺序不会改变行为。 该程序编译后没有错误消息,但只要程序的其余部分正在运行,正弦信号仍然可以听到。
这是我用于初始化 AudioUnit 的代码:
void CreateAndConnectOutputUnit (ToneGenerator *player)
AudioComponentDescription outputcd = 0;
outputcd.componentType = kAudioUnitType_Output;
outputcd.componentSubType = kAudioUnitSubType_DefaultOutput;
outputcd.componentManufacturer = kAudioUnitManufacturer_Apple;
AudioComponent comp = AudioComponentFindNext (NULL, &outputcd);
if (comp == NULL)
printf ("can't get output unit");
exit (-1);
AudioComponentInstanceNew(comp, &player->outputUnit);
// register render callback
AURenderCallbackStruct input;
input.inputProc = SineWaveRenderCallback;
input.inputProcRefCon = player;
AudioUnitSetProperty(player->outputUnit,
kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Output,
0,
&input,
sizeof(input);
// initialize unit
AudioUnitInitialize(player->outputUnit);
在我的主程序中,我正在启动 AudioUnit 和正弦波。
void main
// code for doing various things
ToneGenerator player = 0; // create a sound object
CreateAndConnectOutputUnit (&player);
AudioOutputUnitStart(player.outputUnit);
// waiting to listen to the sine wave
sleep(3);
// attempt to stop the sound output
AudioComponentInstanceDispose(player.outputUnit);
AudioUnitUninitialize(player.outputUnit);
AudioOutputUnitStop(player.outputUnit);
//additional code that should be executed without sine wave being audible
由于我对这两个论坛以及 Xcode 编程都是新手,我希望我能以一种您可以帮助我的方式来解释这个问题,我希望我没有错过某个地方的答案论坛,同时寻找解决方案。
提前感谢您的时间和投入,
斯蒂芬
【问题讨论】:
我会首先确保事情以相反的顺序发生:InstanceNew;Initialize;Start --> Stop;Uninitialize;InstanceDispose,并检查所有函数的返回值。 (它们返回错误代码是有原因的,而不是应该忽略它们。) 非常感谢您的回答 molbdnilo。更改顺序似乎合乎逻辑,但不会改变行为。这些函数抛出错误 -2147450879。我没有找到有关这些错误的有用信息。我正在使用这个函数来捕捉错误:link. 【参考方案1】:您应该按逻辑顺序管理和取消管理您的音频单元。在已经未初始化的音频单元上停止播放是没有意义的,实际上之前在播放过程中处理了。而不是这样,请尝试以下顺序:
AudioOutputUnitStop(player.outputUnit); //first stops playback
AudioUnitUninitialize(player.outputUnit); //then deallocates unit's resources
AudioComponentInstanceDispose(player.outputUnit); //finally disposes of the AU itself
您所追求的正弦波命令行应用程序是this textbook 中精心设计的课程。请逐步阅读。
最后但并非最不重要的一点是,您的问题与 C++ 无关,CoreAudio 是一个纯 C API,因此您的标题和标签中的 C++ 都是错误且具有误导性的。
【讨论】:
非常感谢您的反馈。如上所述,我确实改变了调用函数的顺序,没有改变。我的代码实际上是基于链接的教科书。如果我运行原始代码,它似乎可以工作,因此我希望问题出现在附加代码中。我会深入研究这个。我还更正了指向 c++ 的链接。 为陡峭的学习曲线和最大的阅读集中度做好准备。这个 API 非常冗长。在我看来,您正在尝试设计控制单元寿命的方法,比sleep(3)
更有意义。重要的是,您不要在您的 AU 仍在播放时“断开”程序的其余部分。【参考方案2】:
音频单元在异步线程中运行,当您调用 AudioOutputUnitStop 时,该线程实际上可能不会立即停止。因此,在可能仍在运行的音频单元上调用 AudioUnitUninitialize 和 AudioComponentInstanceDispose 之前等待几分之一秒(至少几个音频回调缓冲区持续时间)可能会更好。
此外,请检查以确保您的 player.outputUnit 值在您停止单元时是有效的单元(而不是未初始化或已丢弃的变量)。
【讨论】:
以上是关于CoreAudio:AudioUnit 既不能停止也不能未初始化的主要内容,如果未能解决你的问题,请参考以下文章
无法设置 MultiChanelMixer AudioUnit 总线的输入音量