# Native audio in FiveM: AWC wave packs, dat54 sound data and custom soundsets

> Stream custom GTA-native sounds in FiveM: .awc wave packs, dat54.rel soundsets, AUDIO_WAVEPACK data files, RequestScriptAudioBank and PlaySoundFromEntity.

Source: https://fam-tools.com/guides/fivem-native-audio-banks · FAM Tools · published 2026-09-19 · updated 2026-09-19 · about 8 min

**Short answer.** Native audio needs two things streamed from a resource: an `.awc` wave pack holding the audio, and a `.dat54.rel` sound-data file that defines named sounds and a soundset pointing at that wave pack. Declare them with `data_file 'AUDIO_WAVEPACK'` (the folder) and `data_file 'AUDIO_SOUNDDATA'` (the path without `54.rel`), load the bank in a script with `RequestScriptAudioBank('folder/bank', false)`, then play sounds with `PlaySoundFromEntity`, `PlaySoundFromCoord` or `PlaySoundFrontend` using the sound name and soundset name.

## Key points

- `.awc` holds the audio; `.dat54.rel` names the sounds and groups them into soundsets.
- `AUDIO_WAVEPACK` points at a folder, `AUDIO_SOUNDDATA` at the `.dat` path without the `54.rel` suffix.
- Scripts load the wave pack with `RequestScriptAudioBank('folder/bankname', false)`.
- Play with the sound name plus the soundset name, exactly as defined in the sound data.
- Do not wait on `RequestScriptAudioBank` returning true in an endless loop; use a timeout.
- For other players to hear a sound, trigger it on their clients rather than relying on network sounds.

Most custom sounds on FiveM servers play through NUI: an HTML audio element in a browser layer, with volume faked from distance. It works, but it is not the game's audio engine. It ignores reverb in tunnels, does not duck under explosions, cannot attach to a moving vehicle properly and is heard at full clarity through walls. Native audio uses the real engine: your sound is packed into the same container format Rockstar uses and played with the same natives as a vanilla siren or door buzzer. It takes more setup, and this guide walks through every piece of it.

## Native audio versus NUI audio

|  | NUI audio | Native audio |
| --- | --- | --- |
| Setup | Drop an .ogg in the resource | Build .awc and .dat54.rel files |
| Positional | Faked with distance maths | Real 3D, attached to entities |
| Environment | None | Reverb, occlusion, game volume sliders |
| Follows a moving car | Only with constant updates | Yes, when played from the entity |
| Best for | UI sounds, music, simple effects | Sirens, vehicle and weapon sounds, world effects |

If you only need a phone ringtone or a notification ping, NUI audio is simpler and entirely adequate; the basics are in [custom sounds in FiveM](https://fam-tools.com/guides/fivem-custom-sounds). Native audio pays off when the sound belongs in the world: a siren that fades behind buildings, a door alarm that sounds like it is coming from the door, an engine note.

## The files involved

| File | What it is | Declared as |
| --- | --- | --- |
| `mybank.awc` | Audio Wave Container holding one or more waves | Inside the `AUDIO_WAVEPACK` folder |
| `mysounds.dat54.rel` | Sound data: sounds, soundsets, references to waves | `AUDIO_SOUNDDATA` |
| `mygame.dat151.rel` | Game data: vehicle, radio and other game objects | `AUDIO_GAMEDATA`, only when needed |

A simple custom sound only needs the first two. Game data (`dat151`) is used for vehicle engine sounds, radio stations and similar game objects, and is not needed for sounds a script triggers by name.

Inside the sound data, two kinds of entries do the work for scripted sounds. A **simple sound** points at one wave inside a container, identified by the container name (the wave-pack folder and `.awc` name) and the wave name. A **soundset** maps script-facing names to those sounds. Scripts refer to the soundset name and the sound name inside it, never to the wave directly. More elaborate sound types exist for loops, randomised variations and crossfades, but a simple sound per wave covers alarms, sirens and one-shot effects.

## Building the audio

1. Prepare mono, 16-bit WAV files. 32 kHz or 48 kHz sample rates are the safe choices; 48 kHz is expected for radio content.
2. Trim silence and normalise loudness. Native sounds are mixed with the game, so a file mastered as loud as possible will clip next to gunfire.
3. Pack the waves into an `.awc`. CodeWalker can import and export `.awc` via XML, and community tools such as native-audio-tool and AWCMaster automate the conversion and generate the matching sound data.
4. Create the `.dat54.rel` with a simple sound per wave and a soundset listing them. Generating it with a tool avoids hand-editing hashes.
5. Choose PCM for quality or ADPCM for roughly a quarter of the size. ADPCM is fine for most effects.

> **Names must match everywhere** — The container name inside the sound data must match the wave-pack folder and `.awc` name you stream, and the wave names must match the names inside the `.awc`. A single mismatch gives silence with no error, which is the most common native-audio failure.

## The resource layout and manifest

*resource layout*

```text
my_audio/
├─ fxmanifest.lua
├─ client.lua
├─ audiodirectory/
│  └─ my_sounds.awc
└─ data/
   └─ my_sounds.dat54.rel
```

*fxmanifest.lua*

```lua
fx_version 'cerulean'
game 'gta5'

client_script 'client.lua'

files {
    'audiodirectory/my_sounds.awc',
    'data/my_sounds.dat54.rel',
}

data_file 'AUDIO_WAVEPACK' 'audiodirectory'
data_file 'AUDIO_SOUNDDATA' 'data/my_sounds.dat'
```

Two details trip almost everyone. `AUDIO_WAVEPACK` points at the **folder**, not the `.awc` file. `AUDIO_SOUNDDATA` points at the sound-data file **without** the `54.rel` part: the file on disk is `my_sounds.dat54.rel`, the manifest says `data/my_sounds.dat`. Audio data files cannot be globbed, so each needs its own `data_file` line, and both files must also be listed in `files` so clients download them.

Some resources place these files under `stream/` instead; that works too, as long as the `files` and `data_file` paths match. Keeping audio out of `stream/` makes it clearer which files are loaded through data-file entries.

## Loading the bank and playing sounds

*client.lua*

```lua
local BANK = 'audiodirectory/my_sounds'
local SOUNDSET = 'my_soundset'
local bankReady = false

CreateThread(function()
    local deadline = GetGameTimer() + 5000
    while GetGameTimer() < deadline do
        if RequestScriptAudioBank(BANK, false) then break end
        Wait(100)
    end
    bankReady = true
end)

local function playOnEntity(name, entity)
    if not bankReady then return end
    local id = GetSoundId()
    PlaySoundFromEntity(id, name, entity, SOUNDSET, false, 0)
    return id
end

local function stop(id)
    if not id then return end
    StopSound(id)
    ReleaseSoundId(id)
end

AddEventHandler('onResourceStop', function(res)
    if res == GetCurrentResourceName() then
        ReleaseNamedScriptAudioBank(BANK)
    end
end)
```

The bank name is the wave-pack folder and the `.awc` name without extension, joined with a slash. Some resources write it with a backslash, as in `DLC_MYSIRENS\\SIRENPACK_ONE` in Lua source; both forms refer to the same bank.

The deadline loop matters. `RequestScriptAudioBank` is documented to return true once the bank is loaded, but there is an open FiveM issue where it keeps returning false even though the bank loaded and sounds play. A `while not RequestScriptAudioBank(...) do Wait(0) end` loop can therefore spin forever. Retry for a few seconds, then carry on.

| Native | Use |
| --- | --- |
| `PlaySoundFrontend(-1, name, soundset, true)` | Non-positional UI sound |
| `PlaySoundFromEntity(id, name, entity, soundset, false, 0)` | Attached to a ped, vehicle or object |
| `PlaySoundFromCoord(id, name, x, y, z, soundset, false, range, false)` | Fixed world position with a range |
| `GetSoundId()` / `ReleaseSoundId(id)` | Allocate and free a handle for stoppable sounds |
| `StopSound(id)`, `HasSoundFinished(id)` | Stop a looping sound, check completion |

Pass -1 as the sound id for fire-and-forget sounds. Anything that loops, such as a siren or an alarm, needs a real id from `GetSoundId` so you can stop it, and the id must be released afterwards or you slowly run out of sound slots.

## Making other players hear it

The `isNetwork` flag on the play natives exists, but it relies on every client having the same bank loaded at the same time, and it gives you no control over who hears what. The dependable pattern is to let the server fan the event out and have each nearby client play the sound locally from the right entity.

*server.lua*

```lua
RegisterNetEvent('my_audio:alarm', function(netId)
    local src = source
    local entity = NetworkGetEntityFromNetworkId(netId)
    if entity == 0 then return end
    local origin = GetEntityCoords(entity)
    for _, id in ipairs(GetPlayers()) do
        local ped = GetPlayerPed(id)
        if ped ~= 0 and #(GetEntityCoords(ped) - origin) < 120.0 then
            TriggerClientEvent('my_audio:playAlarm', id, netId)
        end
    end
end)
```

*client.lua*

```lua
RegisterNetEvent('my_audio:playAlarm', function(netId)
    local entity = NetToEnt(netId)
    if not DoesEntityExist(entity) then return end
    playOnEntity('alarm_loop', entity)
end)
```

Validate on the server who may trigger a sound; an event that any client can fire at everyone within 120 metres is an invitation to abuse. Because each client plays from the entity, the engine handles distance, occlusion and Doppler on its own.

## Vehicle and siren sounds

Add-on engine sounds use the same wave-pack mechanism plus game data. A typical vehicle sound resource streams `.awc` files, a `dat54.rel` and a `dat151.rel`, and declares `AUDIO_WAVEPACK`, `AUDIO_SOUNDDATA` and `AUDIO_GAMEDATA`. The car then points at the sound through `<audioNameHash>` in its `vehicles.meta`, as described in [vehicle meta files](https://fam-tools.com/guides/fivem-vehicle-meta-files).

- Start the sound resource before the vehicle resources that reference it.
- Keep the original file names from the sound pack; the names are baked into the data files.
- Test a sound on any car with `ForceUseAudioGameObject(vehicle, 'soundname')` before editing metas.
- Siren resources usually expose a soundset and sound names, and your emergency-lighting script plays them with `PlaySoundFromEntity`.

## Troubleshooting silence

| Check | How |
| --- | --- |
| Files downloaded | Both listed in `files`, resource started, no errors in F8 |
| Data-file paths | Folder for `AUDIO_WAVEPACK`, `.dat` without `54.rel` for `AUDIO_SOUNDDATA` |
| Bank name | `folder/awcname` with no extension |
| Sound and soundset names | Exactly as in the sound data; open the `.rel` as XML in CodeWalker to confirm |
| Wave format | Mono 16-bit; re-export stereo files |
| Game volume | The SFX slider affects native sounds, unlike NUI audio |

Native audio adds download size for every player. Keep effects short, prefer ADPCM, and group related sounds into one bank rather than one bank per sound. A bank only occupies memory while it is loaded, so resources with many situational sounds, such as a heist script, can request their bank when the activity starts and release it with `ReleaseNamedScriptAudioBank` when it ends.

## Questions

### What is an .awc file in FiveM?

An Audio Wave Container, the game's own format for audio data. It is streamed through an `AUDIO_WAVEPACK` data file and played through soundsets defined in a `.dat54.rel`.

### Why is AUDIO_SOUNDDATA path missing the 54.rel?

The data-file entry names the `.dat` path and the game appends the type suffix itself, so `data/my_sounds.dat54.rel` is declared as `data/my_sounds.dat`.

### What bank name do I pass to RequestScriptAudioBank?

The wave-pack folder and the `.awc` name without extension, for example `audiodirectory/my_sounds`.

### Why does RequestScriptAudioBank always return false?

There is a reported FiveM issue where it returns false even when the bank loaded. Retry with a timeout rather than looping until it returns true.

### How do other players hear my native sound?

Send a server event to nearby players and have each client play the sound from the same entity.

## Related

- https://fam-tools.com/guides/fivem-custom-sounds
- https://fam-tools.com/guides/fivem-streaming-assets
- https://fam-tools.com/guides/fivem-vehicle-meta-files
- https://fam-tools.com/guides/fivem-fxmanifest
