|
Banjo API 1.0.0-rc.2
Low-level C99 game development API
|
Data Structures | |
| struct | bj_audio_properties |
| struct | bj_audio_play_note_data |
Macros | |
| #define | BJ_AUDIO_FORMAT_WIDTH(x) |
| #define | BJ_AUDIO_FORMAT_FLOAT(x) |
| #define | BJ_AUDIO_FORMAT_INT(x) |
| #define | BJ_AUDIO_FORMAT_BIG_ENDIAN(x) |
| #define | BJ_AUDIO_FORMAT_SIGNED(x) |
Typedefs | |
| typedef enum bj_audio_format | bj_audio_format |
| typedef void(* | bj_audio_callback_fn) (void *buffer, unsigned frames, const struct bj_audio_properties *audio, void *user_data, uint64_t base_sample_index) |
Enumerations | |
| enum | bj_audio_format { BJ_AUDIO_FORMAT_UNKNOWN = 0x0000 , BJ_AUDIO_FORMAT_INT16 = 0x8010 , BJ_AUDIO_FORMAT_F32 = 0x8120 } |
Functions | |
| struct bj_audio_device * | bj_open_audio_device (const struct bj_audio_properties *properties, bj_audio_callback_fn callback, void *callback_user_data, struct bj_error **error) |
| void | bj_close_audio_device (struct bj_audio_device *device) |
| void | bj_play_audio_device (struct bj_audio_device *device) |
| void | bj_pause_audio_device (struct bj_audio_device *device) |
| void | bj_reset_audio_device (struct bj_audio_device *device) |
| void | bj_stop_audio_device (struct bj_audio_device *device) |
| bj_bool | bj_audio_playing (const struct bj_audio_device *device) |
| void | bj_play_audio_note (void *buffer, unsigned frames, const struct bj_audio_properties *audio, void *user_data, uint64_t base_sample_index) |
Generate and play sound samples from your application.
This subsystem lets your program produce sound. The model is simple: you tell Banjo "open a connection to the speakers, and call this function of mine whenever you need more sound to play." Banjo then runs your function in the background, asking for the next batch of numbers (samples) each time the speaker is about to drain.
Sound on a computer is just a stream of numbers (one number per time slice) that describes the position of the speaker cone at that instant. Play back tens of thousands of those per second (44 100 / s is the CD-quality standard) and the ear hears continuous sound. This format is called PCM (Pulse-Code Modulation) and it's the lingua franca every audio system uses. Banjo gives you raw PCM in and out: no music files, no streaming containers, just numbers.
The common beginner mistake is to imagine "I write some samples into a buffer, and the speakers play them." That works for recorded clips, but for live or generated audio it has too much latency: by the time you finished filling the buffer the sound is already delayed by however long the buffer holds.
Banjo follows the standard real-time pattern: you give the subsystem a function of yours (your audio callback, bj_audio_callback_fn) and the audio subsystem calls it from a separate background thread whenever the speaker's playback buffer needs refilling. Each call gives you a buffer to write the next handful of samples into.
Two practical consequences:
printf, no slow work, just compute samples and return.bj_play_audio_note is a ready-made callback that generates continuous sine, square, triangle, or sawtooth waveforms. Hand it to bj_open_audio_device along with a bj_audio_play_note_data describing the frequency and shape, then change data.frequency from your main thread whenever you want the pitch to move. The audio thread picks up the new value on the next sample. No custom callback needed.
The audio_pcm.c tutorial walks through that approach; pong.c shows how to write your own callback for short triggered beeps instead of a continuous tone.
Audio works on Linux, Windows, macOS, and WebAssembly. You don't pick the platform: bj_begin (called with BJ_AUDIO_SYSTEM) probes each one in priority order at startup and uses the first that initialises. A no-op fallback (the fake backend) means bj_open_audio_device returns a valid handle even on a headless host with no sound card; in that case bj_audio_playing reports BJ_FALSE and the callback simply isn't invoked. On success, startup logs "audio \c selected: \c <name>"; on total failure bj_begin returns BJ_FALSE with BJ_ERROR_INITIALIZE.
Open a device with bj_open_audio_device (passing your callback). Control playback with bj_play_audio_device, bj_pause_audio_device, bj_stop_audio_device, bj_reset_audio_device, and bj_audio_playing. Close with bj_close_audio_device as it joins the audio thread before returning, so by the time the call completes your callback is guaranteed to have stopped (you can free any state it was reading).
| struct bj_audio_properties |
Describe properties of an audio device.
This structure is passed to audio callbacks to inform them about the format and limits of the current playback device.
| Data Fields | ||
|---|---|---|
| int16_t | amplitude | Maximum amplitude of the output samples. |
| unsigned int | channels | Number of interleaved channels (1 = mono, 2 = stereo, ...). The opened device may negotiate a different value. |
| enum bj_audio_format | format | Sampling format. |
| unsigned int | sample_rate | Number of samples per second (Hz). |
| #define BJ_AUDIO_FORMAT_BIG_ENDIAN | ( | x | ) |
Test whether the audio format uses big-endian byte order.
| x | Audio format code (enum bj_audio_format). |
| #define BJ_AUDIO_FORMAT_FLOAT | ( | x | ) |
Test whether the audio format is floating point.
| x | Audio format code (enum bj_audio_format). |
| #define BJ_AUDIO_FORMAT_INT | ( | x | ) |
Test whether the audio format is integer PCM.
| x | Audio format code (enum bj_audio_format). |
| #define BJ_AUDIO_FORMAT_SIGNED | ( | x | ) |
Test whether integer samples are signed.
| x | Audio format code (enum bj_audio_format). |
| #define BJ_AUDIO_FORMAT_WIDTH | ( | x | ) |
Extract the sample width (in bits) from an audio format code.
| x | Audio format code (enum bj_audio_format). |
| typedef void(* bj_audio_callback_fn) (void *buffer, unsigned frames, const struct bj_audio_properties *audio, void *user_data, uint64_t base_sample_index) |
Define a callback for generating audio samples.
This callback is called periodically from a dedicated audio thread to generate PCM audio data.
| buffer | Output buffer to write int16_t samples into. |
| frames | Number of audio frames to generate. |
| audio | Pointer to audio device properties (read-only). |
| user_data | User-defined pointer passed at device creation. |
| base_sample_index | Index of the first sample in the current buffer. |
| typedef enum bj_audio_format bj_audio_format |
| enum bj_audio_format |
Audio sample format descriptor.
Encodes sample width, sign, float/integer, and endianness flags. Use the helper macros to inspect properties.
| Enumerator | |
|---|---|
| BJ_AUDIO_FORMAT_UNKNOWN | Unknown/unspecified format. |
| BJ_AUDIO_FORMAT_INT16 | 16-bit signed integer PCM. |
| BJ_AUDIO_FORMAT_F32 | 32-bit IEEE-754 float PCM. |
| bj_bool bj_audio_playing | ( | const struct bj_audio_device * | device | ) |
Query whether the device is currently playing audio.
| device | Pointer to the audio device. |
| void bj_close_audio_device | ( | struct bj_audio_device * | device | ) |
Close an audio device and release all associated resources.
Stops playback and joins the audio thread before cleanup.
| device | Pointer to the audio device to close. |
Referenced by teardown().
| struct bj_audio_device * bj_open_audio_device | ( | const struct bj_audio_properties * | properties, |
| bj_audio_callback_fn | callback, | ||
| void * | callback_user_data, | ||
| struct bj_error ** | error ) |
Open the default audio device for playback.
Initializes the audio backend and starts playback immediately using the provided callback.
| properties | Optional pointer to requested properties, or NULL. The opened device may differ from the request. |
| callback | User audio callback used to produce samples. |
| callback_user_data | Opaque pointer passed to the callback on each call. |
| error | Optional pointer to receive error information on failure. |
Referenced by setup().
| void bj_pause_audio_device | ( | struct bj_audio_device * | device | ) |
Pause audio playback.
While paused, the audio thread continues running and outputs silence.
| device | Pointer to the audio device. |
| void bj_play_audio_device | ( | struct bj_audio_device * | device | ) |
Resume audio playback.
Playback resumes from where it was previously paused.
| device | Pointer to the audio device. |
Referenced by setup().
| void bj_play_audio_note | ( | void * | buffer, |
| unsigned | frames, | ||
| const struct bj_audio_properties * | audio, | ||
| void * | user_data, | ||
| uint64_t | base_sample_index ) |
Generate a basic waveform tone using a built-in callback.
Can be used as a bj_audio_callback_fn and uses struct bj_audio_play_note_data.
| buffer | Output buffer to write samples into. |
| frames | Number of frames to generate. |
| audio | Audio device properties. |
| user_data | Pointer to a struct bj_audio_play_note_data instance. |
| base_sample_index | Starting sample index (for phase computation). |
Referenced by setup().
| void bj_reset_audio_device | ( | struct bj_audio_device * | device | ) |
Reset the playback stream sample index to 0.
Does not stop or pause playback. Only resets timing.
| device | Pointer to the audio device. |
| void bj_stop_audio_device | ( | struct bj_audio_device * | device | ) |
Stop playback and reset the sample stream.
Equivalent to calling pause followed by reset.
| device | Pointer to the audio device. |