Skip to content
anthony.samms edited this page May 28, 2026 · 1 revision

This page outlines YataiDON's audio engine. It uses PortAudio to manage audio APIs, libsndfile to load audio files, and libsamplerate to resample audio to the user's device sample rate. Here is the list of supported audio file types:

.ogg
.wav
.flac
.mp3

There are other supported types but these are the primary use cases.

Why can't we use raylib's audio engine?

While raylib's audio engine is functional for this project, it's missing support for specific audio backends; IE. Windows users would be stuck with MME, and there are many that need to use ASIO or WASAPI.

enum class VolumePreset {
    NONE,
    SOUND,
    MUSIC,
    VOICE,
    HITSOUND,
    ATTRACT_MODE,
};

These are the volume presets that are defined in the config and ideally should be passed as a parameter whenever playing a sound or music stream. This allows the user to mix their audio instead of leaving the developer to do it.

Types of audio

Audio is either loaded as a sound, or as a music_stream. A sound is loaded directly into memory, all upfront. A music_stream is streamed from disk. Despite this, the rules of memory management do not apply to this system, as there are specific cases when you should use these two types:

A sound should be used when there is enough time to be loaded during a loading screen, and requires low performance to be played. For example, the player's hitsound would be loaded as a sound so it can be reused throughout the gameplay. Furthermore, the music for the chart would also be loaded as a sound, despite its high file size; you don't want to read from disk during the gameplay screen as user's disks may have a high response time.

A music stream should be used when there is not enough time to load it. Primarily this is used on the song select, where a user may quickly scroll through songs and expects the preview to be instantaneous.

The Audio Engine

bool AudioEngine::init_audio_device(const fs::path& sounds_path, const AudioConfig& audio_config, const VolumeConfig& volume_presets)

The audio engine is immediately initialized in the YataiDON. When initialized, it will automatically load the don and kat sound, and stays loaded until it is closed. This will return false if any part of initialization fails.

void  close_audio_device();

Closing the engine will immediately unload all sounds and music_streams, and disable the PortAudio stream.

bool  is_audio_device_ready() const;

Returns a boolean value if the engine has been initialized.

void  set_master_volume(float volume);

Set the master volume of the engine. This must be between 0.0 and 1.0.

float get_master_volume();

Returns the master volume of the engine. The default is 1.0.

std::string load_sound(const fs::path& file_path, const std::string& name);

Loads an audio file into the engine as a sound. This takes the file_path as a parameter, and the name to be given to the loaded file. It will return the name. If the file is at a different sample rate than the target, this file will be automatically resampled upon loading.

void unload_sound(const std::string& name);

Unloads an audio file based on the name given from the load_sound function.

void load_screen_sounds(const std::string& screen_name);

Loads all of the audio files pertaining to a particular screen in the current skin.

void unload_all_sounds();

Unloads all current sounds in the audio engine.

void play_sound(const std::string& name, VolumePreset volume_preset = VolumePreset::NONE);

Plays a sound based on the given name. A volume preset can be provided, otherwise it will play at the default volume.

void stop_sound(const std::string& name);

Stops a sound based on the given name.

bool is_sound_playing(const std::string& name);

Check if a sound is playing based on the given name.

void  set_sound_volume(const std::string& name, float volume);

Set the volume of a sound based on the given name. This will override the given volume preset.

void  set_sound_pan(const std::string& name,   float pan);

Set the pan of a sound based on the given name. The pan is a float value between 0.0 and 1.0, where 0.0 is left, 1.0 is right, and 0.5 is center.

float get_sound_time_played(const std::string& name) const;

Returns the time of a sound played based on the given name. The return value is in seconds.

void  seek_sound(const std::string& name, float position);

Seek to a specific period in time in a sound based on the given name. The position is a float value in seconds.

std::string load_music_stream(const fs::path& file_path, const std::string& name);

Loads a music_stream based on the file_path provided. Returns the given name.

std::string load_music_stream_memory(const av::AVAudioStream& audio_stream, const std::string& name);

Loads a music_stream from a memory location. This only supports loading audio from a video.

void  play_music_stream(const std::string& name, VolumePreset volume_preset = VolumePreset::NONE);

Plays a music stream based on the given name. A volume preset can be provided, otherwise it will play at the default volume.

float get_music_time_length(const std::string& name) const;

Returns the length of the music stream in seconds.

float get_music_time_played(const std::string& name) const;

Returns the current position of the music stream in seconds.

void  set_music_volume(const std::string& name, float volume);

Set the volume of a music stream based on the given name. This will override the given volume preset.

bool  is_music_stream_valid(const std::string& name) const;

Check if a music stream exists based on the given name.

bool  is_music_stream_playing(const std::string& name) const;

Check if a music stream is currently playing based on the given name.

void  stop_music_stream(const std::string& name);

Stops playback of a music stream.

void  unload_music_stream(const std::string& name);

Unloads the buffers of a music stream.

void  unload_all_music();

Unloads all music streams in the audio engine.

void  seek_music_stream(const std::string& name, float position);

Seeks a music stream to a specific position in seconds.

int port_audio_callback(const void *inputBuffer, void *outputBuffer,
                        unsigned long framesPerBuffer,
                        const PaStreamCallbackTimeInfo* timeInfo,
                        PaStreamCallbackFlags statusFlags,
                        void *userData)

This function is not accessible outside of the library but it is important to cover. This is the callback function that plays the audio from the engine to the audio API. This is called every frame on a separate thread and does the following:

  • Sets the volume and panning of currently playing sounds/music_streams
  • Looping
  • Advances the memory buffer for sounds
  • Advances the frame buffer for music_streams
  • Resamples music_streams

Clone this wiki locally