# SoundPlayer

The Sound System allows for the creation, manipulation, and synchronization of 2D and 3D audio within the game world. It supports NUI-based audio playback, spatialization, occlusion, looping, and global networking.

### 🎵 Accessing the API

You can access the sound system from any other resource using the export:

```lua
local SoundSystem = exports['ak47_lib']:CreateSound(data)
-- or 
local SoundSystem = Lib47.CreateSound(data)
```

***

### 🛠 Constructor

#### `CreateSound(data)`

Creates a new sound instance. This is the main entry point for the API.

**Parameters (`data` table)**

| **Property**     | **Type** | **Default**              | **Description**                                                                                                        |
| ---------------- | -------- | ------------------------ | ---------------------------------------------------------------------------------------------------------------------- |
| `url`            | String   | Required                 | The direct URL or file path to the audio file (mp3, ogg, wav).                                                         |
| `coords`         | vector3  | `nil`                    | The coordinates for 3D audio. If omitted, the sound defaults to 2D (global UI sound).                                  |
| `soundId`        | String   | Generated                | A unique identifier. Provide one if you need to reference it strictly.                                                 |
| `is3d`           | Boolean  | `true` (if coords exist) | Forces the sound to be 3D or 2D.                                                                                       |
| `volume`         | Number   | `0.5`                    | The initial volume of the sound (0.0 to 1.0).                                                                          |
| `maxDistance`    | Number   | `20.0`                   | The distance at which the sound ceases to be heard (for 3D sounds).                                                    |
| `rate`           | Number   | `1.0`                    | The playback speed. `1.0` is normal, `0.5` is half speed, `2.0` is double speed.                                       |
| `loop`           | Boolean  | `false`                  | New: If `true`, the audio will restart automatically when it finishes.                                                 |
| `interiorEffect` | Boolean  | `false`                  | If `true`, the sound will be occluded (muffled/silent) if the player is in a different interior than the sound source. |
| `global`         | Boolean  | `false`                  | If `true`, the sound creation and state will be synchronized to all clients via the server.                            |

**Returns**

Returns a Sound Object (Wrapper) containing methods to control the audio.

***

### 🧬 Sound Object Methods

Once you have created a sound object, you can use the following methods to control it.

#### `:play()`

Starts or resumes the audio playback.

* Returns: `Sound Object`

#### `:pause()`

Pauses the audio playback.

* Returns: `Sound Object`

#### `:destroy()`

Stops the sound, removes it from the internal tracker, and cleans up NUI resources.

* Returns: `nil`
* Note: It is recommended to assign your variable to the result of this function to clear your local variable (e.g., `mySound = mySound:destroy()`).

#### `:setVolume(volume)`

Updates the volume dynamically.

* volume (Number): 0.0 to 1.0.
* Returns: `Sound Object`

#### `:setRate(rate)`

Updates the playback speed dynamically.

* rate (Number): Playback rate (e.g., 0.5, 1.0, 1.5).
* Returns: `Sound Object`

#### `:setMaxDistance(distance)`

Updates the max hearing distance for 3D sounds.

* distance (Number): The new radius.
* Returns: `Sound Object`

#### `:updateCoords(coords)`

Updates the location of the sound source. Useful for attaching sounds to moving entities.

* coords (vector3): The new coordinates.
* Returns: `Sound Object`

#### `:getInfo()`

Asynchronously retrieves the current state of the audio from the NUI.

* Returns: Table `{ duration: number, currentTime: number }`
* Note: This uses `Citizen.Await`. It is non-blocking to the game thread but will yield the coroutine until data is received.

***

### 📚 Examples

#### Example 1: Looping Background Ambience

This plays a 2D sound that repeats forever. Perfect for weather effects or background music.

```lua
local rain = exports['ak47_lib']:CreateSound({
    url = "sounds/rain_loop.ogg",
    volume = 0.2,
    is3d = false,
    loop = true -- Audio will restart immediately upon ending
})

rain:play()
```

#### Example 2: Looping 3D Machine Sound

A generator placed on the ground that hums continuously.

```lua
local generator = exports['ak47_lib']:CreateSound({
    soundId = "gen_01",
    url = "sounds/generator_hum.mp3",
    coords = vector3(250.0, -50.0, 30.0),
    maxDistance = 15.0,
    volume = 0.6,
    loop = true, -- Repeats forever
    interiorEffect = true -- Muffles if you enter a nearby building
})

generator:play()
```

#### Example 3: Global Siren (Syncs to all players)

A loud alarm that loops and is heard by everyone on the server.

```lua
local alarm = exports['ak47_lib']:CreateSound({
    soundId = "prison_alarm",
    url = "https://mysounds.com/alarm.mp3",
    coords = vector3(1800.0, 2600.0, 45.0),
    maxDistance = 300.0,
    volume = 1.0,
    global = true, -- Synced to all players
    loop = true    -- Loops for all players
})

alarm:play()

-- Stop it after 30 seconds
SetTimeout(30000, function()
    if alarm then alarm:destroy() end
end)
```

#### Example 4: The "All Variables" Configuration

An example utilizing every possible configuration option available in the API.

```lua
local complexSound = exports['ak47_lib']:CreateSound({
    soundId = "custom_event_01",       -- Custom ID
    url = "sounds/weird_effect.ogg",   -- File path
    coords = vector3(100.5, 200.5, 30.0), -- 3D Location
    is3d = true,                       -- Enforce 3D
    volume = 0.8,                      -- 80% Volume
    maxDistance = 50.0,                -- Heard up to 50m
    rate = 0.5,                        -- Slow motion (half speed)
    loop = true,                       -- Keep playing
    interiorEffect = true,             -- Occlude walls/interiors
    global = true                      -- Sync to network
})

complexSound:play()
```

#### Example 5: Moving Entity Sound

Attaching a looping engine sound to a vehicle or player.

```lua
local ped = PlayerPedId()
local engine = exports['ak47_lib']:CreateSound({
    url = "sounds/engine_idle.wav",
    coords = GetEntityCoords(ped),
    maxDistance = 40.0,
    loop = true
})

engine:play()

Citizen.CreateThread(function()
    while engine do
        local coords = GetEntityCoords(ped)
        engine:updateCoords(coords)
        Wait(100)
    end
end)
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.menanak47.com/plugins/ak47_lib/interface/soundplayer.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
