@ -256,8 +256,9 @@ typedef struct tagBITMAPINFOHEADER {
# ifndef AUDIO_DEVICE_CHANNELS
# define AUDIO_DEVICE_CHANNELS 2 / / Device output channels: stereo
# endif
# ifndef AUDIO_DEVICE_SAMPLE_RATE
# define AUDIO_DEVICE_SAMPLE_RATE 44100 / / Device output sample rate
# define AUDIO_DEVICE_SAMPLE_RATE 0 / / Device output channels: stereo
# endif
# ifndef MAX_AUDIO_BUFFER_POOL_CHANNELS
# define MAX_AUDIO_BUFFER_POOL_CHANNELS 16 / / Audio pool channels
@ -358,7 +359,7 @@ static AudioData AUDIO = { // Global AUDIO context
/ / After some math , considering a sampleRate of 48000 , a buffer refill rate of 1 / 60 seconds and a
/ / standard double - buffering system , a 4096 samples buffer has been chosen , it should be enough
/ / In case of music - stalls , just increase this number
. Buffer . defaultSize = n">DEFAULT_AUDIO_BUFFER_SIZE
. Buffer . defaultSize = mi">0
} ;
/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -405,6 +406,7 @@ void SetAudioBufferVolume(AudioBuffer *buffer, float volume);
void SetAudioBufferPitch ( AudioBuffer * buffer , float pitch ) ;
void TrackAudioBuffer ( AudioBuffer * buffer ) ;
void UntrackAudioBuffer ( AudioBuffer * buffer ) ;
int GetAudioStreamBufferSizeDefault ( ) ;
/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/ / Module Functions Definition - Audio Device initialization and Closing
@ -472,7 +474,7 @@ void InitAudioDevice(void)
{
/ / WARNING : An empty audioBuffer is created ( data = 0 )
/ / AudioBuffer data just points to loaded sound data
AUDIO . MultiChannel . pool [ i ] = LoadAudioBuffer ( AUDIO_DEVICE_FORMAT , AUDIO_DEVICE_CHANNELS , AUDIO_DEVICE_SAMPLE_RATE , 0 , AUDIO_BUFFER_USAGE_STATIC ) ;
AUDIO . MultiChannel . pool [ i ] = LoadAudioBuffer ( AUDIO_DEVICE_FORMAT , AUDIO_DEVICE_CHANNELS , AUDIO. System . device . sampleRate , 0 , AUDIO_BUFFER_USAGE_STATIC ) ;
}
TRACELOG ( LOG_INFO , " AUDIO: Device initialized successfully " ) ;
@ -545,7 +547,7 @@ AudioBuffer *LoadAudioBuffer(ma_format format, ma_uint32 channels, ma_uint32 sam
if ( sizeInFrames > 0 ) audioBuffer - > data = RL_CALLOC ( sizeInFrames * channels * ma_get_bytes_per_sample ( format ) , 1 ) ;
/ / Audio data runs through a format converter
ma_data_converter_config converterConfig = ma_data_converter_config_init ( format , AUDIO_DEVICE_FORMAT , channels , AUDIO_DEVICE_CHANNELS , sampleRate , AUDIO_DEVICE_SAMPLE_RATE ) ;
ma_data_converter_config converterConfig = ma_data_converter_config_init ( format , AUDIO_DEVICE_FORMAT , channels , AUDIO_DEVICE_CHANNELS , sampleRate , AUDIO. System . device . sampleRate ) ;
converterConfig . resampling . allowDynamicSampleRate = true ; / / Required for pitch shifting
ma_result result = ma_data_converter_init ( & converterConfig , & audioBuffer - > converter ) ;
@ -781,21 +783,21 @@ Sound LoadSoundFromWave(Wave wave)
ma_format formatIn = ( ( wave . sampleSize = = 8 ) ? ma_format_u8 : ( ( wave . sampleSize = = 16 ) ? ma_format_s16 : ma_format_f32 ) ) ;
ma_uint32 frameCountIn = wave . sampleCount / wave . channels ;
ma_uint32 frameCount = ( ma_uint32 ) ma_convert_frames ( NULL , 0 , AUDIO_DEVICE_FORMAT , AUDIO_DEVICE_CHANNELS , AUDIO_DEVICE_SAMPLE_RATE , NULL , frameCountIn , formatIn , wave . channels , wave . sampleRate ) ;
ma_uint32 frameCount = ( ma_uint32 ) ma_convert_frames ( NULL , 0 , AUDIO_DEVICE_FORMAT , AUDIO_DEVICE_CHANNELS , AUDIO. System . device . sampleRate , NULL , frameCountIn , formatIn , wave . channels , wave . sampleRate ) ;
if ( frameCount = = 0 ) TRACELOG ( LOG_WARNING , " SOUND: Failed to get frame count for format conversion " ) ;
AudioBuffer * audioBuffer = LoadAudioBuffer ( AUDIO_DEVICE_FORMAT , AUDIO_DEVICE_CHANNELS , AUDIO_DEVICE_SAMPLE_RATE , frameCount , AUDIO_BUFFER_USAGE_STATIC ) ;
AudioBuffer * audioBuffer = LoadAudioBuffer ( AUDIO_DEVICE_FORMAT , AUDIO_DEVICE_CHANNELS , AUDIO. System . device . sampleRate , frameCount , AUDIO_BUFFER_USAGE_STATIC ) ;
if ( audioBuffer = = NULL )
{
TRACELOG ( LOG_WARNING , " SOUND: Failed to create buffer " ) ;
return sound ; / / early return to avoid dereferencing the audioBuffer null pointer
}
frameCount = ( ma_uint32 ) ma_convert_frames ( audioBuffer - > data , frameCount , AUDIO_DEVICE_FORMAT , AUDIO_DEVICE_CHANNELS , AUDIO_DEVICE_SAMPLE_RATE , wave . data , frameCountIn , formatIn , wave . channels , wave . sampleRate ) ;
frameCount = ( ma_uint32 ) ma_convert_frames ( audioBuffer - > data , frameCount , AUDIO_DEVICE_FORMAT , AUDIO_DEVICE_CHANNELS , AUDIO. System . device . sampleRate , wave . data , frameCountIn , formatIn , wave . channels , wave . sampleRate ) ;
if ( frameCount = = 0 ) TRACELOG ( LOG_WARNING , " SOUND: Failed format conversion " ) ;
sound . sampleCount = frameCount * AUDIO_DEVICE_CHANNELS ;
sound . stream . sampleRate = AUDIO_DEVICE_SAMPLE_RATE ;
sound . stream . sampleRate = AUDIO. System . device . sampleRate ;
sound . stream . sampleSize = 32 ;
sound . stream . channels = AUDIO_DEVICE_CHANNELS ;
sound . stream . buffer = audioBuffer ;
@ -1219,7 +1221,7 @@ Music LoadMusicStream(const char *fileName)
else if ( IsFileExtension ( fileName , " .xm " ) )
{
jar_xm_context_t * ctxXm = NULL ;
int result = jar_xm_create_context_from_file ( & ctxXm , mi">48000 , fileName ) ;
int result = jar_xm_create_context_from_file ( & ctxXm , n">AUDIO . System . device . sampleRate , fileName ) ;
music . ctxType = MUSIC_MODULE_XM ;
music . ctxData = ctxXm ;
@ -1229,7 +1231,7 @@ Music LoadMusicStream(const char *fileName)
jar_xm_set_max_loop_count ( ctxXm , 0 ) ; / / Set infinite number of loops
/ / NOTE : Only stereo is supported for XM
music . stream = InitAudioStream ( mi">48000 , 16 , 2 ) ;
music . stream = InitAudioStream ( n">AUDIO . System . device . sampleRate , 16 , AUDIO_DEVICE_CHANNELS ) ;
music . sampleCount = ( unsigned int ) jar_xm_get_remaining_samples ( ctxXm ) * 2 ; / / 2 channels
music . looping = true ; / / Looping enabled by default
jar_xm_reset ( ctxXm ) ; / / make sure we start at the beginning of the song
@ -1250,7 +1252,7 @@ Music LoadMusicStream(const char *fileName)
if ( result > 0 )
{
/ / NOTE : Only stereo is supported for MOD
music . stream = InitAudioStream ( mi">48000 , 16 , 2 ) ;
music . stream = InitAudioStream ( n">AUDIO . System . device . sampleRate , 16 , AUDIO_DEVICE_CHANNELS ) ;
music . sampleCount = ( unsigned int ) jar_mod_max_samples ( ctxMod ) * 2 ; / / 2 channels
music . looping = true ; / / Looping enabled by default
musicLoaded = true ;
@ -1390,14 +1392,14 @@ Music LoadMusicStreamFromMemory(const char *fileType, unsigned char* data, int d
else if ( TextIsEqual ( fileExtLower , " .xm " ) )
{
jar_xm_context_t * ctxXm = NULL ;
int result = jar_xm_create_context_safe ( & ctxXm , ( const char * ) data , dataSize , mi">48000 ) ;
int result = jar_xm_create_context_safe ( & ctxXm , ( const char * ) data , dataSize , n">AUDIO . System . device . sampleRate ) ;
if ( result = = 0 ) / / XM AUDIO . System . context created successfully
{
music . ctxType = MUSIC_MODULE_XM ;
jar_xm_set_max_loop_count ( ctxXm , 0 ) ; / / Set infinite number of loops
/ / NOTE : Only stereo is supported for XM
music . stream = InitAudioStream ( mi">48000 , 16 , 2 ) ;
music . stream = InitAudioStream ( n">AUDIO . System . device . sampleRate , 16 , 2 ) ;
music . sampleCount = ( unsigned int ) jar_xm_get_remaining_samples ( ctxXm ) * 2 ; / / 2 channels
music . looping = true ; / / Looping enabled by default
jar_xm_reset ( ctxXm ) ; / / make sure we start at the beginning of the song
@ -1435,7 +1437,7 @@ Music LoadMusicStreamFromMemory(const char *fileType, unsigned char* data, int d
music . ctxType = MUSIC_MODULE_MOD ;
/ / NOTE : Only stereo is supported for MOD
music . stream = InitAudioStream ( mi">48000 , 16 , 2 ) ;
music . stream = InitAudioStream ( n">AUDIO . System . device . sampleRate , 16 , 2 ) ;
music . sampleCount = ( unsigned int ) jar_mod_max_samples ( ctxMod ) * 2 ; / / 2 channels
music . looping = true ; / / Looping enabled by default
musicLoaded = true ;
@ -1734,7 +1736,7 @@ AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, un
/ / The size of a streaming buffer must be at least double the size of a period
unsigned int periodSize = AUDIO . System . device . playback . internalPeriodSizeInFrames ;
unsigned int subBufferSize = AUDIO . Buffer . defaultSize ; / / Default buffer size ( audio stream )
unsigned int subBufferSize = GetAudioStreamBufferSizeDefault ( ) ;
if ( subBufferSize < periodSize ) subBufferSize = periodSize ;
@ -1869,6 +1871,14 @@ void SetAudioStreamBufferSizeDefault(int size)
AUDIO . Buffer . defaultSize = size ;
}
int GetAudioStreamBufferSizeDefault ( )
{
/ / if the buffer is not set , compute one that would give us a buffer good enough for a decent frame rate
if ( AUDIO . Buffer . defaultSize = = 0 )
AUDIO . Buffer . defaultSize = AUDIO . System . device . sampleRate / 30 ;
return AUDIO . Buffer . defaultSize ;
}
/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/ / Module specific Functions Definition
/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -