我刚刚开始学习Core Audio,并做了一个简单的测试应用程序,可以播放三个不同的钢琴音符。除了一件小事之外,看起来还不错。
起初,应用程序使用大约7%左右的CPU(在活动监视器中可见),我认为这是正常的,因为它正在运行一个活动的AUGraph
。然而,随着越来越多的音符被播放,CPU的使用不断增加,即使当时可能没有播放声音。
时间线如下:
- 启动应用程序。低到无CPU占用率。
- 播放音符,中等CPU使用率
- 注释结束&没有声音播放,中等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。
我尝试了所有方法,退出活动监视器,关闭所有系统声音,唯一有用的是:
- boot with shift on(安全启动)
- 打开iTunes
如果你有时间,也可以完全重新格式化并重新安装Lion。