2025-01-29 10:55:49 +01:00
# pragma once
# include <kinc/global.h>
# include <stdint.h>
/*! \file audio.h
\ brief Audio2 is a low - level audio - API that allows you to directly provide a stream of audio - samples .
*/
# ifdef __cplusplus
extern " C " {
# endif
2026-06-09 12:45:01 -07:00
# define KINC_A2_MAX_CHANNELS 8
2025-01-29 10:55:49 +01:00
typedef struct kinc_a2_buffer {
2026-06-09 12:45:01 -07:00
uint8_t channel_count ;
float * channels [ KINC_A2_MAX_CHANNELS ] ;
uint32_t data_size ;
uint32_t read_location ;
uint32_t write_location ;
2025-01-29 10:55:49 +01:00
} kinc_a2_buffer_t ;
/// <summary>
/// Initializes the Audio2-API.
/// </summary>
KINC_FUNC void kinc_a2_init ( void ) ;
/// <summary>
/// Sets the callback that's used to provide audio-samples. This is the primary method of operation for Audio2. The callback is expected to write the requested
/// number of samples into the ring-buffer. The callback is typically called from the system's audio-thread to minimize audio-latency.
/// </summary>
/// <param name="kinc_a2_audio_callback">The callback to set</param>
2026-06-09 12:45:01 -07:00
/// <param name="userdata">The user data provided to the callback</param>
KINC_FUNC void kinc_a2_set_callback ( void ( * kinc_a2_audio_callback ) ( kinc_a2_buffer_t * buffer , uint32_t samples , void * userdata ) , void * userdata ) ;
2025-01-29 10:55:49 +01:00
/// <summary>
2026-06-09 12:45:01 -07:00
/// The current sample-rate of the system.
2025-01-29 10:55:49 +01:00
/// </summary>
2026-06-09 12:45:01 -07:00
KINC_FUNC uint32_t kinc_a2_samples_per_second ( void ) ;
2025-01-29 10:55:49 +01:00
/// <summary>
2026-06-09 12:45:01 -07:00
/// Sets a callback that's called when the system's sample-rate changes.
2025-01-29 10:55:49 +01:00
/// </summary>
2026-06-09 12:45:01 -07:00
/// <param name="kinc_a2_sample_rate_callback">The callback to set</param>
/// <param name="userdata">The user data provided to the callback</param>
/// <returns></returns>
KINC_FUNC void kinc_a2_set_sample_rate_callback ( void ( * kinc_a2_sample_rate_callback ) ( void * userdata ) , void * userdata ) ;
2025-01-29 10:55:49 +01:00
/// <summary>
/// kinc_a2_update should be called every frame. It is required by some systems to pump their audio-loops but on most systems it is a no-op.
/// </summary>
KINC_FUNC void kinc_a2_update ( void ) ;
/// <summary>
/// Shuts down the Audio2-API.
/// </summary>
KINC_FUNC void kinc_a2_shutdown ( void ) ;
2026-06-09 12:45:01 -07:00
void kinc_a2_internal_init ( void ) ;
bool kinc_a2_internal_callback ( kinc_a2_buffer_t * buffer , int samples ) ;
void kinc_a2_internal_sample_rate_callback ( void ) ;
2025-01-29 10:55:49 +01:00
# ifdef KINC_IMPLEMENTATION_AUDIO2
# define KINC_IMPLEMENTATION
# endif
# ifdef KINC_IMPLEMENTATION
2026-06-09 12:45:01 -07:00
# include <kinc/threads/mutex.h>
# include <memory.h>
# include <stddef.h>
static kinc_mutex_t mutex ;
static void ( * a2_callback ) ( kinc_a2_buffer_t * buffer , uint32_t samples , void * userdata ) = NULL ;
static void * a2_userdata = NULL ;
2025-01-29 10:55:49 +01:00
2026-06-09 12:45:01 -07:00
void kinc_a2_set_callback ( void ( * kinc_a2_audio_callback ) ( kinc_a2_buffer_t * buffer , uint32_t samples , void * userdata ) , void * userdata ) {
kinc_mutex_lock ( & mutex ) ;
a2_callback = kinc_a2_audio_callback ;
a2_userdata = userdata ;
kinc_mutex_unlock ( & mutex ) ;
}
static void ( * a2_sample_rate_callback ) ( void * userdata ) = NULL ;
static void * a2_sample_rate_userdata = NULL ;
void kinc_a2_set_sample_rate_callback ( void ( * kinc_a2_sample_rate_callback ) ( void * userdata ) , void * userdata ) {
kinc_mutex_lock ( & mutex ) ;
a2_sample_rate_callback = kinc_a2_sample_rate_callback ;
a2_sample_rate_userdata = userdata ;
kinc_mutex_unlock ( & mutex ) ;
}
void kinc_a2_internal_init ( void ) {
kinc_mutex_init ( & mutex ) ;
}
bool kinc_a2_internal_callback ( kinc_a2_buffer_t * buffer , int samples ) {
kinc_mutex_lock ( & mutex ) ;
bool has_callback = a2_callback ! = NULL ;
if ( has_callback ) {
a2_callback ( buffer , samples , a2_userdata ) ;
}
kinc_mutex_unlock ( & mutex ) ;
return has_callback ;
}
void kinc_a2_internal_sample_rate_callback ( void ) {
kinc_mutex_lock ( & mutex ) ;
if ( a2_sample_rate_callback ! = NULL ) {
a2_sample_rate_callback ( a2_sample_rate_userdata ) ;
}
kinc_mutex_unlock ( & mutex ) ;
}
2025-01-29 10:55:49 +01:00
# endif
# ifdef __cplusplus
}
# endif