← Paracosm·Docs/Handbook
Contents · Sound

Sound

How much sound to build

1. Keep continual ambient sound light

The SL-style viewer's audio engine renders spatial loops crudely: no occlusion, loops that sum across a region until each has a radius, a "digital blurble" from grainy layers at distance, and audible loop seams. An evening of mix tuning bought modest returns; the visual and interactive world repaid the effort far better. The advice recorded in this project is to keep a few beds (water, fire, wind, waves) and otherwise add sound as short EVENT one-shots tied to an interaction (a latch, a creak), not new continual ambience. The later build logs did add more loops (wind, rain, a corona hiss); CONFLICTS.md notes the tension. The techniques below are what made the loops that exist work.

Making and uploading

2. Sounds are OGG Vorbis, played by UUID

Encode with ffmpeg -c:a libvorbis, upload with WorldBridge upload_sound (the file must start OggS), and play by the returned UUID (llLoopSound, llPlaySound, llTriggerSound). Keep each clip under ten seconds.

3. A looped noise buffer must be seamless

Loop seams are audible. The ambient beds were built as seamless loops (the wind from soft band-limited noise in layers). A pitched carrier under bubbles read as a "digital blurble"; band-limited noise replaced it.

4. Fade a clip where its sound ends, not where its buffer ends

A clip compressed to carry its tail must be faded where the sound actually ends, and trimmed; the lifted tail of a thunder roll otherwise stopped dead.

5. Verify a sound offline by its spectrogram and envelope, not by playing it aloud

Check spectrogram and envelope sheets of the WAV. A speech-to-text transcriber run on a WAV file is a device-free first ear: its labels are hints (a gull cry pitched near 600 Hz with a vocal buzz was transcribed as "(crying)", which is a baby's range).

Placing sound in the world

6. Sounds carry far and sum: give every voice a radius

With no limit, nine brook emitters were heard across the whole island. Give every ambient voice llSetSoundRadius(r), a hard audible edge (about 10-16 m for water).

7. Mind the room

A loud source 2-5 m outside a wall is loud indoors too; there is no occlusion. Put outdoor voices away from the house and raise the indoor one.

8. Put emitters at the listener's head

A triggered sound from 6 m overhead is quietened by the viewer's distance rolloff. Weather sounds ride an emitter that follows the nearest visitor. A sound triggered at the harbour faded out in the viewer by about 60 m, so a "far voice" at the visitor's head plays the distant version (low-passed, with echoes) instead.

9. Balance by crest factor, not by peak

A noise loop normalised to full scale is far louder ON AVERAGE than a one-shot like thunder (mostly a quiet roll under one crack). Wind loops at 1.0 buried the thunder; 0.12-0.45 let it stand about 20 dB out.

10. llPlaySound stops the previous sound; llTriggerSound overlaps

For a bell whose strokes should ring on under the next, use llTriggerSound.

11. Make a loop one breath long to breathe with a light

To make a sound swell with a glow, make the loop exactly one breath period long and start it on the shared clock's rising edge.

One setting for every sound

12. Every sound script obeys one mode

A small object (a bell) holds the region's sound mode: on, proximity (a sound plays only while someone is near it, and carries less far) or off. It remembers the mode in its description, announces it region-wide, re-announces it every five minutes, and answers scripts that start later and ask. Every sound script carries the shared snippet: sound_mode.LOOP_LSL for loops (loop_setup(sound, volume, radius) plus LOOP_EVENTS) or EVENT_LSL for one-shots (guard each play with may_sound(radius)). A new sound script without it is a bug: nobody can silence it.

13. Clear the restored loop before applying a mode

A prim restores its last looping sound from the region database at startup, before its script runs. loop_setup calls llStopSound() first, or a silenced region plays again after a restart.

What is really playing

14. The region database is not the live truth

The database's LoopedSound column goes stale: a prim whose only change is its sound is never marked changed. Read the live sound with WorldBridge inspect (sound: asset, gain, flags where 1 = looping, radius).

15. Listen to what the viewer actually plays

Record the host's audio output (loopback capture) while the viewer is in the world. That is the true in-world listen, and it catches what offline checks cannot.