核心音频高CPU使用率时,没有声音播放



我刚刚开始学习Core Audio,并做了一个简单的测试应用程序,可以播放三个不同的钢琴音符。除了一件小事之外,看起来还不错。

起初,应用程序使用大约7%左右的CPU(在活动监视器中可见),我认为这是正常的,因为它正在运行一个活动的AUGraph。然而,随着越来越多的音符被播放,CPU的使用不断增加,即使当时可能没有播放声音。

时间线如下:

  1. 启动应用程序。低到无CPU占用率。
  2. 播放音符,中等CPU使用率
  3. 注释结束&没有声音播放,中等CPU占用率。

代码:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    // Insert code here to initialize your application
    NewAUGraph(&audioGraph);
    AudioComponentDescription cd;
    AUNode outputNode;
    AudioUnit outputUnit;
    cd.componentManufacturer = kAudioUnitManufacturer_Apple;
    cd.componentFlags = 0;
    cd.componentFlagsMask = 0;
    cd.componentType = kAudioUnitType_Output;
    cd.componentSubType = kAudioUnitSubType_DefaultOutput;
    //AUGraphNewNode(audioGraph, &cd, 0, NULL, &outputNode);
    AUGraphAddNode(audioGraph, &cd, &outputNode);
    //AUGraphGetNodeInfo(audioGraph, outputNode, 0, 0, 0, &outputUnit);
    AUGraphNodeInfo(audioGraph, outputNode, &cd, &outputUnit);
    AUNode mixerNode;
    AudioUnit mixerUnit;
    cd.componentManufacturer = kAudioUnitManufacturer_Apple;
    cd.componentFlags = 0;
    cd.componentFlagsMask = 0;
    cd.componentType = kAudioUnitType_Mixer;
    cd.componentSubType = kAudioUnitSubType_StereoMixer;
    AUGraphAddNode(audioGraph, &cd, &mixerNode);
    AUGraphNodeInfo(audioGraph, mixerNode, &cd, &mixerUnit);
    AUGraphConnectNodeInput(audioGraph, mixerNode, 0, outputNode, 0);
    AUGraphOpen(audioGraph);
    AUGraphInitialize(audioGraph);
    AUGraphStart(audioGraph);
    AUNode synthNode;

    cd.componentManufacturer = kAudioUnitManufacturer_Apple;
    cd.componentFlags = 0;
    cd.componentFlagsMask = 0;
    cd.componentType = kAudioUnitType_MusicDevice;
    cd.componentSubType = kAudioUnitSubType_DLSSynth;
    AUGraphAddNode(audioGraph, &cd, &synthNode);
    AUGraphNodeInfo(audioGraph, synthNode, &cd, &synthUnit);
    AUGraphConnectNodeInput(audioGraph, synthNode, 0, mixerNode, 0);
    AUGraphUpdate(audioGraph, NULL);
    CAShow(audioGraph);
}
- (IBAction)playMusic:(id)sender {
    MusicDeviceMIDIEvent(synthUnit, 0x90, 60, 127, 0);
    sleep(1);
    MusicDeviceMIDIEvent(synthUnit, 0x90, 62, 127, 0);
    sleep(1);
    MusicDeviceMIDIEvent(synthUnit, 0x90, 64, 127, 0);
}
- (void)one:(id)sender {
    MusicDeviceMIDIEvent(synthUnit, 0x90, 60, 127, 0);
}
- (void)two:(id)sender {
    MusicDeviceMIDIEvent(synthUnit, 0x90, 62, 127, 0);
}
- (void)three:(id)sender {
    MusicDeviceMIDIEvent(synthUnit, 0x90, 64, 127, 0);
}

怎么回事?我该如何解决这个问题?

谢谢。

好吧,我明白了!

基本上,我只是忘记了停止演奏音符,尽管它们逐渐消失,但它们仍然在演奏,使计算机工作。

这可以通过再次播放速度设置为0的音符来修复。因此,代码看起来像这样:

- (IBAction)playMusic:(id)sender {
    MusicDeviceMIDIEvent(synthUnit, 0x90, 60, 127, 0);
    MusicDeviceMIDIEvent(synthUnit, 0x90, 60, 0, 0);
    sleep(1);
    MusicDeviceMIDIEvent(synthUnit, 0x90, 62, 127, 0);
    MusicDeviceMIDIEvent(synthUnit, 0x90, 62, 0, 0);
    sleep(1);
    MusicDeviceMIDIEvent(synthUnit, 0x90, 64, 127, 0);
    MusicDeviceMIDIEvent(synthUnit, 0x90, 64, 0, 0);
}
- (void)one:(id)sender {
    MusicDeviceMIDIEvent(synthUnit, 0x90, 60, 127, 0);
    MusicDeviceMIDIEvent(synthUnit, 0x90, 60, 0, 0);
}
- (void)two:(id)sender {
    MusicDeviceMIDIEvent(synthUnit, 0x90, 62, 127, 0);
    MusicDeviceMIDIEvent(synthUnit, 0x90, 62, 0, 0);
}
- (void)three:(id)sender {
    MusicDeviceMIDIEvent(synthUnit, 0x90, 64, 127, 0);
    MusicDeviceMIDIEvent(synthUnit, 0x90, 64, 0, 0);
}

我想如果我想让音符演奏得更长,我可以在开始和停止音符之间等待。

感谢所有的帮助:@user757808 @Peter Hosey @mbykov

代码中最繁重的CPU部分是AudioUnit处理过程。尝试为播放媒体所用的硬件设置相同的采样率,以减少CPU负载。

AudioSessionSetProperty (kAudioSessionProperty_PreferredHardwareSampleRate, size, &float64);

只有一种方法可以阻止AudioUnit的处理- AUGraphStop。

我尝试了所有方法,退出活动监视器,关闭所有系统声音,唯一有用的是:

  1. boot with shift on(安全启动)
  2. 打开iTunes

如果你有时间,也可以完全重新格式化并重新安装Lion。

最新更新