|
@@ -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 = DEFAULT_AUDIO_BUFFER_SIZE
|
|
|
+ .Buffer.defaultSize = 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, 48000, fileName);
|
|
|
+ int result = jar_xm_create_context_from_file(&ctxXm, 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(48000, 16, 2);
|
|
|
+ music.stream = InitAudioStream(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(48000, 16, 2);
|
|
|
+ music.stream = InitAudioStream(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, 48000);
|
|
|
+ int result = jar_xm_create_context_safe(&ctxXm, (const char*)data, dataSize, 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(48000, 16, 2);
|
|
|
+ music.stream = InitAudioStream(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(48000, 16, 2);
|
|
|
+ music.stream = InitAudioStream(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
|
|
|
//----------------------------------------------------------------------------------
|