Expand description
Audio as data: screens ask for sounds and music through
Ctx::audio; Game hands the
requests, and the MusicState’s commands, to the platform in each
FrameOutput. Nothing here plays anything, so
screens stay testable without a sound card.
Voice clips are asked for by dialogue line id, through
Ctx::play_voice, which knows which lines
have a clip that may be played. V is the game’s
ClipVariant: which of a line’s clips plays.
The engine’s widgets and screens play the same few sounds for the same
things on every screen (MenuSound); which cues those are is the
game’s (AudioConfig, from GameData::audio_config).
A sound that must be stopped (rain, a hum, a cue that loops) is started
with a handle: AudioQueue::start_sound gives its SoundId, which
stop_sound, with or without a fade, and
set_sound_volume take. It belongs to
the screen that started it: when that screen leaves the stack, its
sounds stop, so a loop can’t outlive it. A loop meant to outlive a
screen is started by the screen below it, or is music.
A game can make a sound at run time, from samples (Samples) rather than
a file: AudioQueue::add_sound makes them a cue, played from then on
as a cue of the manifest is, within ADDED_SECONDS_MAX and
ADDED_BYTES_MAX, and AudioQueue::remove_sound frees it.
let mut audio = AudioQueue::<()>::default();
audio.play_sound("menu_beep");
audio.play_music("theme");
assert_eq!(audio.pending()[1], AudioRequest::play_music("theme", None));Structs§
- Audio
Config - Which of the game’s sound cues the engine’s widgets and screens play
(
MenuSound, and the cursor’s tick): the game’s (GameData::audio_config). The default names them after what they are (ui_move,ui_select,ui_cancel,ui_cursor), with Denied playingui_cancel. - Audio
Queue - The requests screens made this frame.
Gameempties it every frame. It knows which cues theMenuSounds are (AudioConfig), and the sounds started with a handle that haven’t stopped. - Music
Clock - Where the music is in its track, for a screen that keeps time with it,
read from
Ctx::music_clock. The platform reports what really sounds (a track starts only once its file has loaded);Game::set_music_playingturns that into this. - Music
State - Which tracks play, and how one gives way to the next (ADR-0054): each
switch is a
MusicSwitch, the request’s own or the default one. The old track fades out; the new one starts once it has stopped, or as it begins to fade (a crossfade), and may fade in. A cue already playing doesn’t restart, and at most two tracks are loaded at once. A fade-in, and an old track’s fade in a crossfade, wait until the new track sounds (heard), orLOAD_WAIT_SECS. Pure: feed it requests, time and what sounds, read the commands. - Music
Switch - How one music track gives way to the next (ADR-0054): the old one
fades out over
out_ms, and the new one fades in overin_ms, starting as the old one begins to fade (overlap, a crossfade) or once it has stopped. Build it withnew,after_fadeorcrossfade(ADR-0039). - Samples
- A sound made at run time: 16-bit samples, interleaved (left first in
stereo), at a rate. Any rate from 1 to
Self::MAX_RATE: a backend plays it at its own. - SoundId
- A sound started with a handle (
AudioQueue::start_sound): the queue’s count of them, from 1, so the same calls give the same ids on every run.
Enums§
- AddSound
Error - Why
AudioQueue::add_soundrefused a sound. The game’s log says it too. - Audio
Request - Something a screen wants heard. Cue ids are the ones in the game’s
audio manifest (
AudioManifest). - Menu
Sound - The sounds the engine’s widgets and screens play: the same cue means the same thing on every screen.
- Music
Command - What the platform must do to the music this frame. A track is loaded, started, has its volume changed and is stopped, which also unloads it.
- Samples
Error - Why
Samplescouldn’t be made.
Constants§
- ADDED_
BYTES_ MAX - The most bytes of samples the sounds added hold at once, all together: 32 MiB, two bytes a sample.
- ADDED_
SECONDS_ MAX - The longest a sound added may play, in seconds.
Functions§
- pick_
from_ pool - The music cue pool
poolyields forseed: the same seed always gives the same cue.Noneif the manifest has no such pool or it is empty. This is not a game’s simulation RNG, so a pick never changes a battle or its replay. - splitmix64
- One step of splitmix64: spreads nearby seeds (e.g. a counter) over the whole range.
Type Aliases§
- Shared
Samples Samplesthat the queue and whatever plays them share, never copied on their way.