Sound_Player module

replace_sound_data

procedure · 1 overloadsince 0.31.0Source

Swaps in a new sound for data without moving it: the streams playing the old one are stopped, its bytes are freed and replacement takes its place. Anything that holds the *Sound_Data keeps a valid pointer and gets the new sound from the next make_stream on. This is how to hot-reload a sound.

The old sound goes as in release_sound_data: its streams end (a stream that was playing does not carry on with the new data; start a new one), Sound_Player_Config.release_asset is called for each, and the old buffer is freed with context.allocator. replacement is typically load_audio_file(path) or load_audio_data(name, bytes); one that did not load (loaded is false) is refused with false and data is left playing as it was, so a bad file on disk does not silence a good sound. A replacement that was refused still owns its bytes: free them.

Example
first := load_audio_data("first", copy_string("not audio"));
assert(!first.loaded); // too short to be a sound; its bytes are still ours
free(first.buffer.data);

samples: [64] s16;
data := Sound_Data.{ loaded = true, type = .LINEAR_SAMPLE_ARRAY, samples = samples.data, nsamples_times_nchannels = samples.count };
data.buffer = copy_string("old bytes");

louder: [64] s16;
louder[0] = 100;
replacement := Sound_Data.{ loaded = true, type = .LINEAR_SAMPLE_ARRAY, samples = louder.data, nsamples_times_nchannels = louder.count };
replacement.buffer = copy_string("new bytes");

assert(replace_sound_data(*data, replacement));
assert(data.samples == louder.data && data.buffer == "new bytes");
release_sound_data(*data);

Doesn't run in the browser (skipped on wasm).

replace_sound_data :: (data: *Sound_Data, replacement: Sound_Data) -> bool

Swaps in a new sound for data without moving it: the streams playing the old one are stopped, its bytes are freed and replacement takes its place. Anything that holds the *Sound_Data keeps a valid pointer and gets the new sound from the next make_stream on. This is how to hot-reload a sound.

The old sound goes as in release_sound_data: its streams end (a stream that was playing does not carry on with the new data; start a new one), Sound_Player_Config.release_asset is called for each, and the old buffer is freed with context.allocator. replacement is typically load_audio_file(path) or load_audio_data(name, bytes); one that did not load (loaded is false) is refused with false and data is left playing as it was, so a bad file on disk does not silence a good sound. A replacement that was refused still owns its bytes: free them.

Parameters

data: *Sound_Data
replacement: Sound_Data

Returns

bool
Example
first := load_audio_data("first", copy_string("not audio"));
assert(!first.loaded); // too short to be a sound; its bytes are still ours
free(first.buffer.data);

samples: [64] s16;
data := Sound_Data.{ loaded = true, type = .LINEAR_SAMPLE_ARRAY, samples = samples.data, nsamples_times_nchannels = samples.count };
data.buffer = copy_string("old bytes");

louder: [64] s16;
louder[0] = 100;
replacement := Sound_Data.{ loaded = true, type = .LINEAR_SAMPLE_ARRAY, samples = louder.data, nsamples_times_nchannels = louder.count };
replacement.buffer = copy_string("new bytes");

assert(replace_sound_data(*data, replacement));
assert(data.samples == louder.data && data.buffer == "new bytes");
release_sound_data(*data);

Doesn't run in the browser (skipped on wasm).

See also