没有声音播放时核心音频 CPU 使用率高
Posted
技术标签:
【中文标题】没有声音播放时核心音频 CPU 使用率高【英文标题】:Core audio high CPU usage when no sound playing 【发布时间】:2011-07-08 23:42:27 【问题描述】:我刚刚开始学习 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);
发生了什么事?我该如何解决这个问题?
谢谢。
【问题讨论】:
第一个想法 - 检查繁忙的循环。顺便说一句 - 在这个档案中找不到源代码 - 只有树和目录树:) 什么是忙循环以及如何检查它们?嗯...当我单击链接时,它会下载一个zip
文件。这就是项目中的所有代码。唯一的其他东西是 UI、xcodeproj 等。
您的代码是否在线程中运行?如果是 - 当您不播放音频时的情况是什么。当它不播放时,尝试在那里添加一些睡眠代码。另一方面 - 检查您是否正确关闭所有句柄并停止播放机制。
@spudwaffle:繁忙的循环只是代码中的一个循环(例如for
或while
),尤其是一个运行大量时间的循环,它会消耗 CPU 时间并让你从快速返回运行循环。
您应该使用 Instruments 的 Time Profiler 工具来分析您的应用程序,并查看您的应用程序在其消耗的所有 CPU 时间中正在做什么。
【参考方案1】:
好吧,我想通了!
基本上,我只是忘了停止弹奏这些音符,尽管它们逐渐变得安静,但它们仍在弹奏并使计算机正常工作。
这可以通过将力度设置为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
【讨论】:
您实际上不应该发送停止消息吗? 0x80 ? MusicDeviceMIDIEvent(synthUnit, 0x80, 60, 127, 0); @drewish 那会更有意义!谢谢。 速度为 0 的 MIDI Note Off (0x80) 和 MIDI Note On (0x90) 都是停止 MIDI 音符的有效方法。【参考方案2】:您的代码中 CPU 最重的部分是 AudioUnit 处理过程。尝试为用于播放媒体的硬件设置相同的采样率,以减少 CPU 负载。
AudiosessionSetProperty (kAudioSessionProperty_PreferredHardwareSampleRate, size, &float64);
只有一种方法可以阻止 AudioUnit 处理 - AUGraphStop。
我尝试了一切,退出活动监视器,关闭所有系统声音,只有帮助的是:
-
Shift on 启动(安全启动)
打开 iTunes
如果您有时间,或者完全重新格式化 HD 并重新安装 Lion。
【讨论】:
我忘了说我在 Mac 上。这看起来只适用于 iOS。以上是关于没有声音播放时核心音频 CPU 使用率高的主要内容,如果未能解决你的问题,请参考以下文章
播放音乐时,我的音频应用程序中没有收到通知或消息的声音 | AV音频播放器
使用 Python 录制或播放音频无法在 Mac 上运行:没有错误和没有声音