# sound_backend.h ## Overview
This file provides an interface for low-level (raw) output of sound data to the system's speakers. We do all sound mixing, 3D positioning, etc on a higher level, so the only thing we need from the OS is a way to output that data to the individual speaker channels. The external interface of this module uses 44.1 kHz, float32 data. Internally, it may use something else, depending on the system.
## Index
`TM_SOUND_BACKEND_MAX_CHANNELS`

`struct tm_sound_backend_api`
`finish_init()`
`num_speakers()`
`channel_mask()`
`remaining_samples()`
`feed()`
`wait()`
`signal()`

`TM_SOUND_BACKEND_API_NAME`
## API
### `TM_SOUND_BACKEND_MAX_CHANNELS`
Maximum channels supported by the sound backend. ~~~c enum { TM_SOUND_BACKEND_MAX_CHANNELS = 8 }; ~~~
### `struct tm_sound_backend_api`
API for accessing the sound backend. #### `finish_init()` ~~~c void (*finish_init)(); ~~~ Call this to finish initialization of the sound backend. (Initialization starts when the audio plugin is loaded.) #### `num_speakers()` ~~~c uint32_t (*num_speakers)(void); ~~~ Returns the number of speakers in the system. Note that for a headphone setup, this will be 2, whereas for a surround sound setup it could be 6 (5.1), 7 (6.1) or 8 (7.1). The value returned by `num_speakers()` is guaranteed to be <= `TM_SOUND_BACKEND_MAX_CHANNELS`. !!! note: TODO * We need a way to detect and react to changes to the speaker configuration, for example if the user changes the output device or unplugs headphones. * Support >8 speaker setups (7.1.4, 7.1.6, 9.1, 9.1.4, ...). #### `channel_mask()` ~~~c uint32_t (*channel_mask)(void); ~~~ Channel mask for the speakers. This specifies which speakers the user has connected and can for example be used to distinguish between 6.1 and 7.0 setups. See `speakers.h` for a definition of the channel mask. It is guaranteed that `tm_uint32_count_bits(channel_mask()) == num_speakers()`. #### `remaining_samples()` ~~~c uint32_t (*remaining_samples)(void); ~~~ Returns the number of remaining samples in the play queue. If the sound output backend runs out of samples to play it will go silent, so unless you `feed()` it at regular intervals, the sound will stutter. Note that the returned value is the number of samples remaining *per channel*, not the total number remaining in all channels. I.e. `remaining_speakers() / 44100` tells you how many seconds of sound are currently queued. #### `feed()` ~~~c void (*feed)(float *samples, uint32_t num_samples); ~~~ Feeds samples to the sound output backend to play. The samples will be put at the end of the queue of samples to play. Samples should be provided as `float32` in the 0--1 range at 44.1 kHz. If you provide values outside the 0--1 range, they will be clipped. When you call `feed()`, you should provide data for all speakers interleaved in the order specified by `enum tm_speaker` in `speakers.h`. I.e. in a stereo system the data layout should be: `[ left_sample_0 right_sample_0 left_sample_1 right_sample_1 left_sample_2 ...]` `num_samples` specifies the *total* number of samples you provide, so that means each channel will get `num_samples / num_channels` samples. If you don't call `feed()` often enough, the sound backend will run out of data and sound will start stuttering. If you call `feed()` with large chunks of data, that affects your sound latency, because there is no way for your application to affect the sound data once it has been passed down to the backend with `feed()`. For these reasons, you probably want to call `feed()` from a high-priority dedicated thread that updates at around 100 Hz. The sound backend does not support queing up more than 500ms of data (typically you want much less, to avoid latency). It also doesn't support queing more than 128 blocks (individual calls to `feed()`). #### `wait()` ~~~c void (*wait)(float seconds); ~~~ Waits for an event that signals every time a `feed()` call has been fully processed by the backend. If you are using a dedicated thread for sound rendering, you can use this to sleep the thread until more sound data is needed. You should use this in combination with `remaining_samples()` to determine when you need to write more sound data. `seconds` specifies the maximum time to wait (in seconds) if no event is signalled. #### `signal()` ~~~c void (*signal)(void); ~~~ Signals threads waiting in `wait()` to wake up. This can be used if you need to wake up the dedicated thread immediately, before waiting for the last `feed()` to complete. A typical use case for this is when you want to stop sounds immediately, because you are unloading their buffer data from memory. In this case, you want to spend as little time as possible waiting for the dedicated thread to be done with the data.
### `TM_SOUND_BACKEND_API_NAME`
~~~c #define TM_SOUND_BACKEND_API_NAME "tm_sound_backend_api" ~~~