Native Audio Builder
Drop your sounds and get a complete FiveM resource that plays them as real game audio: the .awc wave bank and .dat54.rel sound data built right here (no CodeWalker step), the data_file lines, and Lua to load the bank and play sounds on the UI, on an entity or at a position, synced if you want. Based on lb-nativeaudio.
Why native audio
Most servers play custom sounds through NUI (an HTML audio tag in a hidden browser page). That works, but the game does not know the sound exists: no 3D position, no distance falloff, no game volume slider, and every client runs a browser page for it. Native audio puts your files into the game's own audio system, so PlaySoundFrontend, PlaySoundFromEntity andPlaySoundFromCoord play them like any Rockstar sound. Looking for a base game sound instead? Use theSound Browser.
Native audio needs three things, and this page builds all of them:
- An .awc bank (audio wave container) that holds the audio itself, mono 16 bit, as IMA ADPCM or plain PCM.
- A .dat54.rel with the sound data: one simple sound per wave, a sound set that maps the names you use in Lua to those sounds, and a volume variable you can change while a sound plays.
- fxmanifest data_file lines that tell FiveM to mount the wave pack and load the sound data.
How to use it
- Drop your files. Each file becomes a sound, named after the file. A dropped folder with sub folders gives one sound set per sub folder.
- Check the names. The name and sound set are the two strings you pass to the play natives. Everything is lower case, use letters, digits and
_. - Tick Loop for sounds that should repeat until you stop them (alarms, ringtones, engine hums).
- Click play to hear what the game will get: the audio after the sample rate change, the mono downmix and the codec.
- Download the zip, put the
my_soundsfolder in your resources,ensure my_soundsand run/my_sounds_testin game.
This page can not play the files in the game itself, so test the resource on your own server before you ship it.
What is in the zip
my_sounds/
fxmanifest.lua
client.lua load the bank, play, stop, free
server.lua optional, synced playback
audio/dlc_my_sounds/sounds.awc the wave bank
audio/data/my_sounds_sounds.dat54.rel
codewalker_source/ optional, for editing later
sounds.awc.xml
sounds/*.wav
my_sounds_sounds.dat54.rel.xmlThe manifest lines look like this. The sound data path drops the 54.rel part of the file name, the wave pack path is the folder around the .awc:
files {
'audio/data/my_sounds_sounds.dat54.rel',
'audio/dlc_my_sounds/sounds.awc',
}
data_file 'AUDIO_SOUNDDATA' 'audio/data/my_sounds_sounds.dat'
data_file 'AUDIO_WAVEPACK' 'audio/dlc_my_sounds'Playing the sounds from Lua
A bank has to be loaded before its sounds play. The generated client.lua does it on start and gives you these functions (also as exports):
-- load once (client.lua does this for you)
while not RequestScriptAudioBank('dlc_my_sounds/sounds', false) do Wait(0) end
PlayNative('beep', 'my_sounds_set') -- UI sound
PlayNativeOnEntity('horn', 'my_sounds_set', vehicle) -- follows the entity
PlayNativeAtCoords('alarm', 'my_sounds_set', coords, 30.0) -- heard up to 30 m
local id = PlayNative('ringtone', 'my_sounds_set', true) -- looped
SetNativeVolume(id, 0.5) -- 0.0 to 1.0
StopNative(id) -- stop and free the idFrom another resource: exports['my_sounds']:PlayNative('beep', 'my_sounds_set'). One shot sounds free their sound id when they finish. Looped sounds keep their id until you call StopNative, so keep it around.
For everyone nearby to hear a sound, the server has to tell them. server.lua checks each player's distance (OneSync) and sends the sound to the ones in range: exports['my_sounds']:PlayAtCoords('alarm', 'my_sounds_set', coords, 30.0). The play natives also have an isNetwork argument, but it does not load your bank on the other clients, so the event approach is the reliable one.
Settings that matter
- ADPCM or PCM. ADPCM is a quarter of the size and fine for effects, voice and most music. Very hard edged synth sounds (square waves) lose detail in ADPCM, use PCM for those.
- Sample rate. 32 kHz keeps banks small and is plenty for effects. Use 44.1 or 48 kHz for music. Every sound in a bank uses the same rate here.
- Bank size.
RequestScriptAudioBankloads the whole bank into memory. Keep long music or big packs in a bank of their own and load it only when you need it. - Unique names. Sound sets share one namespace with every game sound, so give them your own prefix. The page warns when a set already exists in the base game and when two names hash to the same value.
- Stereo files are mixed down to mono. Multichannel banks (the stereo format radio uses) are not built here.
Editing the bank later
To edit the bank later, open CodeWalker RPF Explorer, turn on edit mode, and drag sounds.awc.xml (with thesounds folder of WAVs next to it) and the .dat54.rel.xml into a folder. CodeWalker builds the binary files, drag them back into the resource.
Credits and sources
- lb-nativeaudio by LB Scripts, the command line tool this page is based on.
- CodeWalker by dexyfex (MIT).
- AddonCarSounds for the data_file layout, and native-audio-tool, another open tool that builds banks.
- RequestScriptAudioBank,PlaySoundFrontend and the other audio natives on docs.fivem.net.
More config & code tools
server.cfg Generator
Build a complete, working server.cfg with hostname, slots, OneSync, endpoints, tags, resources & ACE permissions.
fxmanifest.lua Generator
Scaffold a valid resource manifest: fx_version, scripts, NUI page, files, lua54 & dependencies.
Vehicle Handling Editor
Tune mass, drive force, grip and suspension from a UI, then export handling.meta or runtime Lua.
