sound
Load and play WAV, MP3, OGG and QOA sounds, with volume, pitch, pan, pause and seeking.
import "std:sound"std:sound plays audio. Load a sound from a file, bytes or a URL, then play, pause, seek and change its volume, pitch and stereo position while it plays. It works on its own or beside a raylib window, and supports WAV, MP3, OGG Vorbis and QOA.
Playing needs an audio device, so the playing examples are marked compile-only. Loading and inspecting a sound doesn't, so that example runs here. To have a sound to load, it makes a half-second beep in memory with a small helper in tone.osl.
Load a sound#
sound.decode(bytes) reads a sound from bytes and sound.decodeFile(path) from a file. Both return a result. A sound knows how long it is, in milliseconds. A new one has volume 1, pitch 1 (normal speed) and pan 0 (centre), and its setters take effect at once, even while it plays:
import "std:sound"
import "./tone.osl"
*sound.Sound beep = sound.decode(tone(500)).unwrap()
log beep.duration()
log beep.volume() beep.pitch() beep.pan()
beep.setVolume(0.5)
beep.setPitch(2)
beep.setPan(-1)
log beep.volume() beep.pitch() beep.pan()
log beep.isPlaying() beep.isPaused() beep.position()
beep.seek(250).unwrap()
log beep.position() beep.progress()Change tone(500) to tone(1200) and run it again.
Play it#
play() starts the sound, or resumes it if it was paused. It fails with an IOError when there is no audio device, so it returns a result:
import "std:sound"
*sound.Sound jump = sound.decodeFile("jump.wav").unwrap()
jump.play().unwrap()The program ends when main ends, so a short program that plays a sound needs to stay alive, for instance with thread.sleep(jump.duration()). A game keeps running anyway.
Volume, pitch and pan#
Volume is 0 (silent) to 1. Pitch is the playback speed, so 2 is twice as fast and an octave higher, and 0.5 an octave lower. Pan runs from -1 (left) to 1 (right). A value out of range throws a ValueError. sound.setGlobalVolume scales every sound at once, like a master volume knob.
You call beep.setPitch(0.5). What do you hear?
Pause, stop and seek#
A sound has a position in milliseconds. pause keeps it, stop rewinds to the start, and seek(ms) jumps anywhere, playing or not. progress() is the position as a fraction from 0 to 1, so a progress bar is progress() times the bar's width.
Sound effects and music#
Sound effects are loaded once and played often. Each Sound plays one voice, and play() on one that is already playing does nothing, so for overlapping effects (many gunshots) load the file more than once. Music is one long sound with isPlaying() checked each frame:
import "std:raylib"
import "std:sound"
*sound.Sound music = sound.decodeFile("theme.ogg").unwrap()
*sound.Sound click = sound.decodeFile("click.wav").unwrap()
music.setVolume(0.4)
music.play().unwrap()
raylib.runWindow(def(ms) (
if raylib.isKeyPressed("space") (
click.stop()
click.play().unwrap()
)
if !music.isPlaying() (
music.seek(0).unwrap()
music.play().unwrap()
)
), {background: "#181825"})click.stop() rewinds it first, so a quick second press restarts the sound.
From a URL, and cleaning up#
sound.fetch(url) downloads and decodes a sound from an http or https address. sound.isReady() opens the audio device and tells you whether there is one, which is how a program checks before it relies on sound. sound.close() stops everything and releases the device, and a sound's own close() frees it. Using a closed sound throws a StateError.
Reject bad data
Decode the bytes [1, 2, 3, 4]. They aren't a sound, so the result is an error. Print its kind.
ParseError
API reference#
45 members, generated from the std:sound source of OSL 9.3.0.
Functions
sound.clear(any id) booleanDeprecated. Deprecated: use snd.close() on a *sound.Sound instead.
clear frees the sound with this ID.
sound.close()close stops every sound and releases the audio device until a sound plays again. Sounds stay loaded.
sound.currentTime(any id) numberDeprecated. Deprecated: use snd.position() on a *sound.Sound instead; it returns milliseconds.
currentTime returns the playback position of the sound with this ID in seconds, or 0.
sound.decode(byte[] data) result<*sound.Sound, error>decode reads a WAV, MP3, OGG Vorbis or QOA sound from bytes, recognising the format from the data rather than a file name. Fails with ParseError when the bytes aren't a sound it can decode.
sound.decodeFile(string path) result<*sound.Sound, error>decodeFile reads a sound file (WAV, MP3, OGG Vorbis or QOA, up to 64 MiB). Fails with NotFoundError or IOError when the file can't be read, UnsupportedError when it is too large, and ParseError when it isn't a sound it can decode.
sound.duration(any id) numberDeprecated. Deprecated: use snd.duration() on a *sound.Sound instead; it returns milliseconds.
duration returns the length of the sound with this ID in seconds, or 0.
sound.fetch(string url, object? options) result<*sound.Sound, error>fetch downloads a sound from an http or https URL and decodes it. Options: timeout (milliseconds, default 10000). Fails with NetworkError, TimeoutError, NotFoundError (404 or 410), PermissionError (401 or 403), UnsupportedError for more than 64 MiB, and ParseError when the response isn't a sound it can decode.
sound.globalVolume() numberglobalVolume returns the volume applied to every sound, from 0 to 1.
sound.info(string id, string field) numberDeprecated. Deprecated: use the *sound.Sound methods instead.
info returns one numeric field of the sound with this ID ("loaded", "playing", "volume", "pitch", "pan", "duration" or "current_time"), or 0.
sound.isReady() booleanisReady reports whether an audio output device is available, opening it if needed. Playing a sound opens it too.
sound.load(any url) stringDeprecated. Deprecated: use sound.decodeFile(path) or sound.fetch(url) instead; they return a *sound.Sound.
load loads a sound and returns its ID, or "" when it can't be loaded.
sound.loaded(any id) booleanDeprecated. Deprecated: use snd.isClosed() on a *sound.Sound instead.
loaded reports whether a sound with this ID is loaded.
sound.masterVolume(number value)Deprecated. Deprecated: use sound.setGlobalVolume(volume) instead.
masterVolume sets the volume of every sound, clamped to 0 to 1.
sound.new(any url) stringDeprecated. Deprecated: use sound.decodeFile(path) or sound.fetch(url) instead; they return a *sound.Sound.
new loads a sound from a path, file:// URL or http(s) URL and returns its ID, or "" when it can't be loaded.
sound.pan(any id, number value) booleanDeprecated. Deprecated: use snd.setPan(pan) on a *sound.Sound instead.
pan sets the stereo position of the sound with this ID, clamped to -1 to 1.
sound.pause(any id) booleanDeprecated. Deprecated: use snd.pause() on a *sound.Sound instead.
pause pauses the sound with this ID and returns false when it wasn't playing.
sound.percent(any id) numberDeprecated. Deprecated: use snd.progress() on a *sound.Sound instead.
percent returns how far through the sound with this ID playback is, from 0 to 1, or 0.
sound.pitch(any id, number value) booleanDeprecated. Deprecated: use snd.setPitch(pitch) on a *sound.Sound instead.
pitch sets the playback speed of the sound with this ID and returns false for a speed that isn't positive.
sound.play(any id) booleanDeprecated. Deprecated: use snd.play() on a *sound.Sound instead.
play starts or resumes the sound with this ID and returns false when the ID is unknown or no audio device is available.
sound.playing(any id) booleanDeprecated. Deprecated: use snd.isPlaying() or snd.isPaused() on a *sound.Sound instead.
playing reports whether the sound with this ID is playing or paused.
sound.ready() booleanDeprecated. Deprecated: use sound.isReady() instead.
ready reports whether an audio output device is available.
sound.setGlobalVolume(number volume)setGlobalVolume sets the volume applied to every sound, from 0 to 1. Throws ValueError outside that range.
sound.start(any id) booleanDeprecated. Deprecated: use snd.play() on a *sound.Sound instead.
start starts or resumes the sound with this ID.
sound.stop(any id) booleanDeprecated. Deprecated: use snd.stop() on a *sound.Sound instead.
stop stops the sound with this ID and returns false when it wasn't playing.
sound.unload(any id) booleanDeprecated. Deprecated: use snd.close() on a *sound.Sound instead.
unload frees the sound with this ID and returns false when the ID is unknown.
sound.unpause(any id) booleanDeprecated. Deprecated: use snd.resume() on a *sound.Sound instead.
unpause resumes the sound with this ID and returns false when it wasn't paused.
sound.volume(any id, number value) booleanDeprecated. Deprecated: use snd.setVolume(volume) on a *sound.Sound instead.
volume sets the volume of the sound with this ID, clamped to 0 to 1.
*sound.Sound
sound.close()close stops the sound and frees it. Closing it again does nothing; any other use afterwards throws StateError.
sound.duration() numberduration returns the sound's length in milliseconds.
sound.isClosed() booleanisClosed reports whether close has been called on the sound.
sound.isPaused() booleanisPaused reports whether the sound was paused part way through.
sound.isPlaying() booleanisPlaying reports whether the sound is playing and not paused. A closed sound isn't playing.
sound.pan() numberpan returns the sound's stereo position, from -1 (left) to 1 (right).
sound.pause()pause pauses the sound where it is, if it is playing. Throws StateError when the sound is closed.
sound.pitch() numberpitch returns the sound's playback speed (default 1).
sound.play() result<unit, error>play starts the sound from its position, or resumes it when paused. Playing a sound that is already playing does nothing. Fails with IOError when no audio output device can be opened; throws StateError when the sound is closed.
sound.position() numberposition returns how far into the sound playback is, in milliseconds. Throws StateError when the sound is closed.
sound.progress() numberprogress returns how far through the sound playback is, from 0 to 1. Throws StateError when the sound is closed.
sound.resume()resume continues a paused sound. Throws StateError when the sound is closed.
sound.seek(number ms) result<unit, error>seek moves playback to ms milliseconds from the start, whether or not the sound is playing. Throws ValueError outside 0 to duration() and StateError when the sound is closed.
sound.setPan(number pan)setPan sets the stereo position from -1 (left) through 0 (centre) to 1 (right). Throws ValueError outside that range and StateError when the sound is closed.
sound.setPitch(number pitch)setPitch sets the playback speed: 2 plays twice as fast and an octave higher, 0.5 half as fast and an octave lower. Throws ValueError unless it is more than 0, and StateError when the sound is closed.
sound.setVolume(number volume)setVolume sets the sound's volume from 0 (silent) to 1 (full). Throws ValueError outside that range and StateError when the sound is closed.
sound.stop()stop ends playback and rewinds the sound to the start. Throws StateError when the sound is closed.
sound.volume() numbervolume returns the sound's volume, from 0 to 1 (default 1).