ServerAudio¶
server.audio: sounds from client files
(MP3, WAV, FLAC) on players' games. A sound with a place is heard from it,
fading out with distance, and turning with the player's camera, at their
sound effects volume.
play(file, options?)¶
| Option | Type | Description |
|---|---|---|
at |
Vector3 | Ped | Player | Vehicle |
Heard from this spot, or from them (following). Left out: everywhere, as is (music, a jingle). |
range |
number |
How far it carries (m). Default 30. |
loop |
boolean |
Plays until stop(). |
volume |
number |
0-1. Default 1. |
to |
Player[] |
Who hears it. Default everyone, players joining later too (while it loops). |
speech |
boolean |
Dialogue or a phone call: the radio goes quiet while it plays near enough to hear. |
effects |
AudioEffects |
Through audio effects: a preset ("phone", "hall"...) or stages layered. |
realism |
boolean |
Positioned: its highs fade with distance, and it's muffled with a building between it and the listener. See Realism. Default server.audio.realism. |
Returns a Sound:
| Member | Description |
|---|---|
duration |
How long the file plays (ms), read from the server's copy in clientFiles; undefined if it can't be read. |
done |
A promise that resolves when it's over: played through (by its duration, from when the server sent it) or stopped. A looping one, when stopped. |
playing |
False once it has played through or been stopped. |
stop() |
Stops it. |
await server.audio.play("audio/caller.mp3", { to: [player], effects: "phone" }).done;
player.subtitle("The line goes dead.");
const ring = server.audio.play("audio/payphone-ring.mp3", { at: { x: 2069, y: -1766.7, z: 13.2 }, loop: true, range: 30 });
server.audio.play("audio/stinger.mp3", { to: [player] });
ring.stop();
Client scripts play their own with sagl.audio.play().
speak(file, options?)¶
speak(file: string, options?: SoundOptions & { subtitle?: string | string[]; subtitleTo?: Player[]; prefix?: string; muffled?: boolean }): Speech
A recorded line with its subtitles timed to it, as speech (the radio
ducks under it). A string subtitle is split into sentence-sized
subtitles (splitSubtitles); each shows for its share of the recording.
They show to subtitleTo, else to, else everyone within range of
at. muffled with at a vehicle: from inside it, through the glass.
Returns { sound, done, stop() }; done resolves when it's been
said. In a mission, m.say is the same,
for the party.
await server.audio.speak("audio/benny-my-car.mp3", { at: benny, subtitle: "My car! That's my car!" }).done;
duration(file)¶
How long a client file plays (ms), from the server's copy; undefined if
it isn't there or isn't a sound.
playGame(sound, options?)¶
One of the game's own sounds, no file needed: a frontend sound (heard by
the player, from nowhere: GameSound has the
pickups', the Pay 'n' Spray's...), or, with at, one of the mission
script's sounds at a spot. to picks who hears it (default everyone).
Pickups play the game's pickup sounds themselves.
playMission(id, options?)¶
playMission(id: number, options?: { at?: Vector3 | Player | Ped | Vehicle; range?: number; to?: Player[]; effects?: AudioEffects }): void
One of the game's mission audio, by its audio id: the recordings and
effects its missions and machines load (a vending machine's clunk is
42600, a snack machine's 42601). From a player, ped or vehicle
(following them, heard up to range m, default 30), a spot, or (no
at) as is. to picks who hears it (default everyone). Each player's
game reads the recording from its own copy of the game and plays it as
the server's sounds are, so effects work on it too.
Audio effects¶
Sounds of the server's and client scripts' (files, the game's mission audio, dialogue lines) can go through effects: filters, distortion, echo, reverb, layered in order, each as strong as you like. The game's own world sounds (engines, guns, footsteps) aren't affected.
effects takes a preset, or a list of presets and stages:
server.audio.play("audio/caller.mp3", { to: [player], effects: "phone" });
server.audio.play("audio/announce.mp3", { at: speaker, effects: ["megaphone", { type: "echo", delay: 0.4, mix: 0.3 }] });
server.audio.play("audio/choir.mp3", { at: church, effects: [{ preset: "hall", strength: 0.5 }] });
| Preset | |
|---|---|
phone |
A phone line: thin, a little crackly. |
radio |
A two-way radio, a police scanner. |
megaphone |
A megaphone, a PA. |
muffled |
Through a wall or a closed door. |
underwater |
Underwater. |
room |
A small room. |
hall |
A large hall, a warehouse. |
cave |
A cave. |
tunnel |
A tunnel, a car park. |
canyon |
A long, clear echo. |
{ preset, strength } is a preset at a strength (0-1). AudioPresets
has each preset's stages, to start your own from.
A stage is one of these; mix (0-1) is how much of it you hear, the rest
being the sound as it came in:
| Stage | Settings |
|---|---|
{ type: "lowpass", cutoff, mix? } |
Cuts the highs above cutoff Hz: muffled. |
{ type: "highpass", cutoff, mix? } |
Cuts the lows below cutoff Hz: thin, tinny. |
{ type: "bandpass", low, high, mix? } |
Keeps only low-high Hz: a phone, a radio. |
{ type: "distortion", drive, mix? } |
Clipping, harsher with drive (0-1). |
{ type: "echo", delay, decay?, mix? } |
Repeats after delay s, each decay (0-1, default 0.4) as loud. Default mix 0.4. |
{ type: "reverb", size?, damping?, mix? } |
A room's reverb: size (0-1) small room to cathedral, damping (0-1) bright to dull. Default mix 0.35. |
{ type: "gain", volume } |
Louder or quieter (1: as is, up to 4). |
Up to 8 stages a sound (a preset counts its own). Echo and reverb ring on after the sound ends.
Realism¶
server.audio.realism = true; // the default for every positioned sound
server.audio.play("audio/payphone-ring.mp3", { at: phone, range: 30, realism: true });
Off by default. With it on, a positioned sound reaches each listener as
it would: duller the further away it is (its highs fade, all the way down
at its range, as well as its volume), and muffled and quieter as a
building comes between it and them (a phone ringing round the corner):
gradually, as more of it is hidden, so rounding a corner fades it rather
than cutting it. Checked a few times a second as they move. For sounds from files and the game's
mission audio (playMission, realism there too); client scripts' take
realism as well.
setEnvironment(player, effects)¶
Effects every sound of ours passes through for this player now, on top of
each sound's own: where they are (a hall's reverb, a tunnel's echo).
null: none.
setZoneEnvironment(zone, effects)¶
An environment for everyone inside a zone while they're in it
(where zones overlap, the one entered last). One set with setEnvironment
wins.