How are Audio Streams handled in internal memory

Hello everyone, I got a technical question about how audio resources are loaded in Godot: :slight_smile:

Does the engine load the entire audio data into RAM before playing it, or does it “stream” chunk by chunk from disk, in order to not oversaturate the RAM for playing long musics?

The Unity Engine lets you pick a “load type” at audio clip import: Unity - Manual: Audio Clip

I haven’t found one on Godot… does this mean the engine decides by itself? Does it depends on the audio format?

Thank you in advance for the clarifications.

The files are loaded in memory and decompressed/decoded while playing:

Thank you very much for the precision, but by “memory”, you mean the RAM / the heap ?

For very long audio music, is there a way to instead cache it temporarily on something like the disk instead?

Yes, loaded in RAM

Cache what? The file is loaded in RAM as is. Decompression/decoding happens while playing them.

It depends on the format.

Decompress On Load - Audio files are decompressed as soon as they’re loaded. Use this option for smaller compressed sounds to avoid the performance overhead of decompressing on the fly. Be aware that decompressing Vorbis-encoded sounds on load will use about ten times more memory than keeping them compressed (for ADPCM encoding it’s about 3.5 times), so don’t use this option for large files.

Godot does not do this. Instead, Godot supports WAV files which are uncompressed and recommends you use them in this context for sound effects.

Compressed In Memory - Keep audio compressed in memory and decompress while playing. This option has a slight performance overhead, especially for Ogg/Vorbis compressed files. Use it only for files that consume excess memory for the Decompressed on Load. The decompression happens on the mixer thread, which can be monitored in the DSP CPU section in the Audio pane of the Profiler window.

If you use an MP3 or Ogg/Vorbis file, this is how Godot loads it.

Streaming - Decode continuous audio. This method uses a minimal amount of memory to buffer compressed data that’s incrementally read from the disk and decoded spontaneously. The decompression happens on a separate streaming thread whose CPU usage can be monitored in the Streaming CPU section in the Audio pane of the profiler window. Note: Streaming clips have an overhead of approximately 200KB, even if none of the audio data is loaded.

AFAIK, Godot does not support streaming audio.

More details with your issue might help us find you another solution. If the file is large and you want to load it before it gets called, you can just use preload().

# Load it as a const
const BIG_SOUND_FILE = preload("res://my_big_sound_file.mp3")
# Or load it as an onready variable that loads when the scene loads
@onready var big_sound_file: AudioStream = preload("res://my_big_sound_file.mp3")

Thank you very much for providing the most detailed response, you answered everything I wanted to know. :slight_smile:

That bothers me a bit, to be honest… maybe I will try to implement it myself, and propose this enhancement in a pull request.

2 Likes

You’re welcome. I’m glad I could help.

I have mixed feelings about it honestly. I’d be interested in the use-cases for streaming audio. The only real benefit I see is a web game where you’re trying to keep the package small. However my worry would be that streaming audio would break (with a TCP model) or jump (with a UDP model) in gameplay and that would be jarring to the player.

Certainly, it will have to account for that.
My concern was mainly about reducing the memory footprint for games in local (e.g. : what if I have a 30 minutes long music?).
For web however, if Unity has managed to do it, I don’t see why it shouldn’t work in Godot. :smiley:

I would say then that you would benefit from chopping it up in Audactiy, exporting it as Ogg-Vorbis, and using an AudioStreamPlaylist. To do that, you create an AudioStreamPlayer, in the Stream field you select New AudioStreamPlaylist and then drag and drop all the parts of your song in order into it.


If you were to code something in C++, making an AudioStreamBuffer class would be the best way to implement it. You would also need to code an AudioStreamPlaybackBuffer object - which is what gets called when you actually play the sound. (It looks like they are declared inside the headers for the class they support.)

Then a user would just create a new AudioStreamBuffer in the Stream of an AudioStreamPlayer, and drop their file into the Stream of the AudioStreamBuffer.

(I’ve been looking at the C++ implementation lately because I’ve been thinking about adding the ability to read headers in MP3 and Ogg-Vorbis files - which an open ticket.)

2 Likes

Thank you very much for all these great advices.

Does the AudioStreamPlayer loads and unload each streams as it plays them?

I honestly don’t know. I don’t have time to go over it now. Here’s the code: