Godot version:
3.2.2
OS/device including version:
macOS Catalina (10.15.4), 2020 MacBook Air i7 16gb RAM.
Issue description:
Godot seems to cause coreaudiod to use excessive CPU time. This happens even in the project manager and editor which don't need to be using Audio. This is an issues as it causes Godot based software to burn more battery than they need to.
Steps to reproduce:
Just start Godot editor and look at the activity monitor, the coreaudiod CPU usage will jump from 0% to ~10%
Minimal reproduction project:
N/A
On my 2013 Mac Pro, macOS 10.15.4 (19E287), Godot cause some constant (about 1.2%) coreaudiod
CPU usage, usage from the typical app playing sound is about 2 - 3%.
Audio I/O processing is started on driver init and is always running. You can disable audio completely by setting audio driver to "Dummy" (--audio-driver Dummy
command line argument) or in "Project Settings", in this case coreaudiod
CPU usage is zero.
This happens even in the project manager and editor which don't need to be using Audio.
The editor uses audio when you play back AudioStreamPlayers to preview them :slightly_smiling_face:
Still, I agree we should make the project manager use the Dummy audio driver.
Also, it might be helpful to make it easier to disable audio... It's not obvious in the project settings, a simple check box would be nice.
@h5n1xp Due to how audio driver swapping is implemented, I don't think it'd make sense to add a separate checkbox to disable audio. There would be two ways to accomplish the same thing, each with their own implementation.
I have the same problem (Godot 3.2.2, macOS Catalina, version 10.15.6). Why is Godot loading coreaudiod so much when no sound is playing / no audio player is active? It causes the computer to heat up unnecessarily.
P.S. I never noticed the same issue on my previous MacBook running macOS 10.14.
@ArdaE Can you try using a profiler?
Either way, you can start the editor with the --audio-driver Dummy
command-line argument if you don't need it to play sound. The running project should still be able to play sound if you do this.
coreaudiod so much when no sound is playing / no audio player is active?
With the current audio driver implementation, Godot is constantly outputting audio as long as driver is loaded, it's just 0-level if there's no audio stream is active. Probably we should not start output callback loop if there is no active streams, like it's done with the audio capture.
Output callback loop is activated in driver init:
https://github.com/godotengine/godot/blob/aada93afc0ecc699440805ad2574d3e94b7c0abd/servers/audio_server.cpp#L944
instead of stream start:
https://github.com/godotengine/godot/blob/aada93afc0ecc699440805ad2574d3e94b7c0abd/servers/audio/audio_stream.h#L43
Input callback loop is started in the stream start, and stopped when stream is stopped:
https://github.com/godotengine/godot/blob/aada93afc0ecc699440805ad2574d3e94b7c0abd/servers/audio/audio_stream.cpp#L194
Can you try using a profiler?
Profiler won't help much, on the Godot side audio stream usage is ~negligible~ 5-6% of Godot's CPU usage, it's coreaudiod
daemon usage getting high (probably it depends on specific audio output hardware how high it is, and caused by resampling it's doing).
Thanks for the info @Calinou.
Can you try using a profiler?
Most of the CPU activity reported by Activity Monitor
is within coreaudiod
, not Godot, as @bruvzg has mentioned. When I profile the Project Manager (no project loaded, compiled as a release_debug
build), Godot's CPU load is lower than coreaudiod
and quite insignificant (~2.5% when no mouse or keyboard input is provided). In this case most of Godot's time is spent in the main run loop, doing idle-processing. A smaller percentage of Godot's time (~3%) is spent in the AudioDriverCoreAudio::output_callback
function, which is called back by CoreAudio. The entire audio thread (CoreAudio + AudioDriverCoreAudio::output_callback
) takes about 15% of Godot's time, so the audio processing within Godot is insignificant considering this percentage is relative to an already small total CPU load.
For anyone who wants to use the --audio-driver Dummy
option: Note that the project manager launches a new instance of Godot when a project is loaded, and doesn't forward the audio-driver
option to it; so be sure to use the --editor
and --path
options too in the command line to directly launch the editor for the project you want to open. I.e. skip the project manager; otherwise the audio driver will switch back to the default CoreAudio one when you open your project in the editor.
coreaudiod so much when no sound is playing / no audio player is active?
With the current audio driver implementation, Godot is constantly outputting audio as long as driver is loaded, it's just 0-level if there's no audio stream is active. Probably we should not start output callback loop if there is no active streams, like it's done with the audio capture.
I think this is the solution to fixing the bug! Audio is a relatively demanding task, no need to start the output if there are no active streams! Well done @bruvzg 馃憤馃徎
Assuming audio would be turned off when the last active audio stream ends playing, which would be ideal, it might be worthwhile to add optional manual control over this in consideration for apps that play audio streams intermittently without any ongoing background audio.
This would be especially important when Bluetooth devices are involved, as they tend do turn on and off as needed, and can have a significant delay whenever audio starts getting streamed after some inactive period. Further, operating systems like macOS and iOS enable audio in a smooth way, which ends up cutting off the beginning of sounds if an audio session is not already active at the time audio starts getting streamed.
Therefore it would be ideal for games/apps to be able to activate the audio session when they know sounds will follow soon, and to be able to shut down the audio session when they know they won't need the audio system for awhile.
The manual control shouldn't be the default, as it would add unnecessary complexity for the average user, but should be there for proper control over the sound system for the best user experience.
Most helpful comment
With the current audio driver implementation, Godot is constantly outputting audio as long as driver is loaded, it's just 0-level if there's no audio stream is active. Probably we should not start output callback loop if there is no active streams, like it's done with the audio capture.
Output callback loop is activated in driver init:
https://github.com/godotengine/godot/blob/aada93afc0ecc699440805ad2574d3e94b7c0abd/servers/audio_server.cpp#L944
instead of stream start:
https://github.com/godotengine/godot/blob/aada93afc0ecc699440805ad2574d3e94b7c0abd/servers/audio/audio_stream.h#L43
Input callback loop is started in the stream start, and stopped when stream is stopped:
https://github.com/godotengine/godot/blob/aada93afc0ecc699440805ad2574d3e94b7c0abd/servers/audio/audio_stream.cpp#L194