2025-02-18 19:09:51 +01:00
#pragma once
2025-03-09 17:02:12 +01:00
#ifdef IRON_A1
2025-02-18 19:09:51 +01:00
2025-02-26 08:47:09 +01:00
#include <iron_global.h>
2025-02-18 19:09:51 +01:00
#include <stdbool.h>
/*! \file audio.h
\brief Audio1 is a high-level audio-API that lets you directly play audio-files. Depending on the target-system it either sits directly on a high-level
system audio-API or is implemented based on Audio2.
*/
2025-03-09 17:02:12 +01:00
struct iron_internal_video_sound_stream ;
2025-02-18 19:09:51 +01:00
2025-03-09 17:02:12 +01:00
struct iron_a1_channel ;
typedef struct iron_a1_channel iron_a1_channel_t ;
2025-02-18 19:09:51 +01:00
2025-03-09 17:02:12 +01:00
struct iron_a1_stream_channel ;
typedef struct iron_a1_stream_channel iron_a1_stream_channel_t ;
2025-02-18 19:09:51 +01:00
2025-03-09 17:02:12 +01:00
struct iron_internal_video_channel ;
typedef struct iron_internal_video_channel iron_internal_video_channel_t ;
2025-02-18 19:09:51 +01:00
2025-03-09 17:02:12 +01:00
void iron_a1_init ( void );
iron_a1_channel_t * iron_a1_play_sound ( iron_a1_sound_t * sound , bool loop , float pitch , bool unique );
void iron_a1_stop_sound ( iron_a1_sound_t * sound );
void iron_a1_play_sound_stream ( iron_a1_sound_stream_t * stream );
void iron_a1_stop_sound_stream ( iron_a1_sound_stream_t * stream );
float iron_a1_channel_get_volume ( iron_a1_channel_t * channel );
void iron_a1_channel_set_volume ( iron_a1_channel_t * channel , float volume );
void iron_a1_channel_set_pitch ( iron_a1_channel_t * channel , float pitch );
void iron_a1_mix ( iron_a2_buffer_t * buffer , uint32_t samples );
2025-02-18 19:09:51 +01:00
2025-03-09 17:02:12 +01:00
void iron_internal_play_video_sound_stream ( struct iron_internal_video_sound_stream * stream );
void iron_internal_stop_video_sound_stream ( struct iron_internal_video_sound_stream * stream );
2025-02-18 19:09:51 +01:00
2025-03-09 17:02:12 +01:00
typedef struct iron_a1_sound {
2025-02-18 19:09:51 +01:00
uint8_t channel_count ;
uint8_t bits_per_sample ;
uint32_t samples_per_second ;
int16_t * left ;
int16_t * right ;
int size ;
float sample_rate_pos ;
float volume ;
bool in_use ;
2025-03-09 17:02:12 +01:00
} iron_a1_sound_t ;
2025-02-18 19:09:51 +01:00
2025-03-09 17:02:12 +01:00
iron_a1_sound_t * iron_a1_sound_create ( const char * filename );
void iron_a1_sound_destroy ( iron_a1_sound_t * sound );
float iron_a1_sound_volume ( iron_a1_sound_t * sound );
void iron_a1_sound_set_volume ( iron_a1_sound_t * sound , float value );
2025-02-18 19:09:51 +01:00
struct stb_vorbis ;
2025-03-09 17:02:12 +01:00
typedef struct iron_a1_sound_stream {
2025-02-18 19:09:51 +01:00
struct stb_vorbis * vorbis ;
int chans ;
int rate ;
bool myLooping ;
float myVolume ;
bool rateDecodedHack ;
bool end ;
float samples [ 2 ];
uint8_t * buffer ;
2025-03-09 17:02:12 +01:00
} iron_a1_sound_stream_t ;
iron_a1_sound_stream_t * iron_a1_sound_stream_create ( const char * filename , bool looping );
float * iron_a1_sound_stream_next_frame ( iron_a1_sound_stream_t * stream );
int iron_a1_sound_stream_channels ( iron_a1_sound_stream_t * stream );
int iron_a1_sound_stream_sample_rate ( iron_a1_sound_stream_t * stream );
bool iron_a1_sound_stream_looping ( iron_a1_sound_stream_t * stream );
void iron_a1_sound_stream_set_looping ( iron_a1_sound_stream_t * stream , bool loop );
bool iron_a1_sound_stream_ended ( iron_a1_sound_stream_t * stream );
float iron_a1_sound_stream_length ( iron_a1_sound_stream_t * stream );
float iron_a1_sound_stream_position ( iron_a1_sound_stream_t * stream );
void iron_a1_sound_stream_reset ( iron_a1_sound_stream_t * stream );
float iron_a1_sound_stream_volume ( iron_a1_sound_stream_t * stream );
void iron_a1_sound_stream_set_volume ( iron_a1_sound_stream_t * stream , float value );
2025-02-18 19:09:51 +01:00
#endif
2025-02-26 08:47:09 +01:00
2025-03-09 17:02:12 +01:00
#ifdef IRON_A2
2025-02-26 08:47:09 +01:00
#include <iron_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.
*/
2025-03-09 17:02:12 +01:00
#define IRON_A2_MAX_CHANNELS 8
2025-02-26 08:47:09 +01:00
2025-03-09 17:02:12 +01:00
typedef struct iron_a2_buffer {
2025-02-26 08:47:09 +01:00
uint8_t channel_count ;
2025-03-09 17:02:12 +01:00
float * channels [ IRON_A2_MAX_CHANNELS ];
2025-02-26 08:47:09 +01:00
uint32_t data_size ;
uint32_t read_location ;
uint32_t write_location ;
2025-03-09 17:02:12 +01:00
} iron_a2_buffer_t ;
2025-02-26 08:47:09 +01:00
2025-03-09 17:02:12 +01:00
void iron_a2_init ( void );
void iron_a2_set_callback ( void ( * iron_a2_audio_callback )( iron_a2_buffer_t * buffer , uint32_t samples , void * userdata ), void * userdata );
uint32_t iron_a2_samples_per_second ( void );
void iron_a2_set_sample_rate_callback ( void ( * iron_a2_sample_rate_callback )( void * userdata ), void * userdata );
void iron_a2_update ( void );
void iron_a2_shutdown ( void );
2025-02-26 08:47:09 +01:00
2025-03-09 17:02:12 +01:00
void iron_a2_internal_init ( void );
bool iron_a2_internal_callback ( iron_a2_buffer_t * buffer , int samples );
void iron_a2_internal_sample_rate_callback ( void );
2025-02-26 08:47:09 +01:00
2025-03-09 17:02:12 +01:00
#ifdef IRON_IMPLEMENTATION_AUDIO2
#define IRON_IMPLEMENTATION
2025-02-26 08:47:09 +01:00
#endif
2025-03-09 17:02:12 +01:00
#ifdef IRON_IMPLEMENTATION
2025-02-26 08:47:09 +01:00
#include <iron_thread.h>
#include <memory.h>
#include <stddef.h>
2025-03-09 17:02:12 +01:00
static iron_mutex_t mutex ;
2025-02-26 08:47:09 +01:00
2025-03-09 17:02:12 +01:00
static void ( * a2_callback )( iron_a2_buffer_t * buffer , uint32_t samples , void * userdata ) = NULL ;
2025-02-26 08:47:09 +01:00
static void * a2_userdata = NULL ;
2025-03-09 17:02:12 +01:00
void iron_a2_set_callback ( void ( * iron_a2_audio_callback )( iron_a2_buffer_t * buffer , uint32_t samples , void * userdata ), void * userdata ) {
iron_mutex_lock ( & mutex );
a2_callback = iron_a2_audio_callback ;
2025-02-26 08:47:09 +01:00
a2_userdata = userdata ;
2025-03-09 17:02:12 +01:00
iron_mutex_unlock ( & mutex );
2025-02-26 08:47:09 +01:00
}
static void ( * a2_sample_rate_callback )( void * userdata ) = NULL ;
static void * a2_sample_rate_userdata = NULL ;
2025-03-09 17:02:12 +01:00
void iron_a2_set_sample_rate_callback ( void ( * iron_a2_sample_rate_callback )( void * userdata ), void * userdata ) {
iron_mutex_lock ( & mutex );
a2_sample_rate_callback = iron_a2_sample_rate_callback ;
2025-02-26 08:47:09 +01:00
a2_sample_rate_userdata = userdata ;
2025-03-09 17:02:12 +01:00
iron_mutex_unlock ( & mutex );
2025-02-26 08:47:09 +01:00
}
2025-03-09 17:02:12 +01:00
void iron_a2_internal_init ( void ) {
iron_mutex_init ( & mutex );
2025-02-26 08:47:09 +01:00
}
2025-03-09 17:02:12 +01:00
bool iron_a2_internal_callback ( iron_a2_buffer_t * buffer , int samples ) {
iron_mutex_lock ( & mutex );
2025-02-26 08:47:09 +01:00
bool has_callback = a2_callback != NULL ;
if ( has_callback ) {
a2_callback ( buffer , samples , a2_userdata );
}
2025-03-09 17:02:12 +01:00
iron_mutex_unlock ( & mutex );
2025-02-26 08:47:09 +01:00
return has_callback ;
}
2025-03-09 17:02:12 +01:00
void iron_a2_internal_sample_rate_callback ( void ) {
iron_mutex_lock ( & mutex );
2025-02-26 08:47:09 +01:00
if ( a2_sample_rate_callback != NULL ) {
a2_sample_rate_callback ( a2_sample_rate_userdata );
}
2025-03-09 17:02:12 +01:00
iron_mutex_unlock ( & mutex );
2025-02-26 08:47:09 +01:00
}
#endif
#endif