aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay <raysan5@gmail.com>2018-02-11 01:12:16 +0100
committerRay <raysan5@gmail.com>2018-02-11 01:12:16 +0100
commit7bf6becc94ee18f782e6ef176745bc8d50b19944 (patch)
tree75b86b5cf2c927998b9eee0d9dc3d24cb86b30ad
parent6d922b3e1f7fa14194b2e912240de8607ceec0f2 (diff)
downloadraylib-7bf6becc94ee18f782e6ef176745bc8d50b19944.tar.gz
raylib-7bf6becc94ee18f782e6ef176745bc8d50b19944.zip
Reviewed mini_al implementation
- Some functions renamed - Comments reviewed - Functions reorganized
-rw-r--r--src/audio.c383
1 files changed, 207 insertions, 176 deletions
diff --git a/src/audio.c b/src/audio.c
index 052d4d3c..55b43bea 100644
--- a/src/audio.c
+++ b/src/audio.c
@@ -225,9 +225,10 @@ void TraceLog(int msgType, const char *text, ...); // Show trace lo
#endif
//----------------------------------------------------------------------------------
-// Module Functions Definition - Audio Device initialization and Closing
+// mini_al AudioBuffer Functionality
//----------------------------------------------------------------------------------
#if USE_MINI_AL
+
#define DEVICE_FORMAT mal_format_f32
#define DEVICE_CHANNELS 2
#define DEVICE_SAMPLE_RATE 44100
@@ -235,15 +236,16 @@ void TraceLog(int msgType, const char *text, ...); // Show trace lo
typedef enum { AUDIO_BUFFER_USAGE_STATIC = 0, AUDIO_BUFFER_USAGE_STREAM } AudioBufferUsage;
// Audio buffer structure
+// NOTE: Slightly different logic is used when feeding data to the playback device depending on whether or not data is streamed
typedef struct AudioBuffer AudioBuffer;
struct AudioBuffer {
- mal_dsp dsp; // For format conversion.
+ mal_dsp dsp; // Required for format conversion
float volume;
float pitch;
bool playing;
bool paused;
- bool looping; // Always true for AudioStreams.
- AudioBufferUsage usage; // Slightly different logic is used when feeding data to the playback device depending on whether or not data is streamed.
+ bool looping; // Always true for AudioStreams
+ int usage; // AudioBufferUsage type
bool isSubBufferProcessed[2];
unsigned int frameCursorPos;
unsigned int bufferSizeInFrames;
@@ -252,76 +254,48 @@ struct AudioBuffer {
unsigned char buffer[1];
};
-void StopAudioBuffer(AudioBuffer *audioBuffer);
-
+// mini_al global variables
static mal_context context;
static mal_device device;
-static mal_bool32 isAudioInitialized = MAL_FALSE;
-static float masterVolume = 1;
static mal_mutex audioLock;
-static AudioBuffer *firstAudioBuffer = NULL; // Audio buffers are tracked in a linked list.
-static AudioBuffer *lastAudioBuffer = NULL;
-
-static void TrackAudioBuffer(AudioBuffer* audioBuffer)
-{
- mal_mutex_lock(&audioLock);
-
- {
- if (firstAudioBuffer == NULL) firstAudioBuffer = audioBuffer;
- else
- {
- lastAudioBuffer->next = audioBuffer;
- audioBuffer->prev = lastAudioBuffer;
- }
+static bool isAudioInitialized = MAL_FALSE;
+static float masterVolume = 1.0f;
- lastAudioBuffer = audioBuffer;
- }
-
- mal_mutex_unlock(&audioLock);
-}
-
-static void UntrackAudioBuffer(AudioBuffer* audioBuffer)
-{
- mal_mutex_lock(&audioLock);
-
- {
- if (audioBuffer->prev == NULL) firstAudioBuffer = audioBuffer->next;
- else audioBuffer->prev->next = audioBuffer->next;
+// Audio buffers are tracked in a linked list
+static AudioBuffer *firstAudioBuffer = NULL;
+static AudioBuffer *lastAudioBuffer = NULL;
- if (audioBuffer->next == NULL) lastAudioBuffer = audioBuffer->prev;
- else audioBuffer->next->prev = audioBuffer->prev;
+// mini_al functions declaration
+static void OnLog(mal_context *pContext, mal_device *pDevice, const char *message);
+static mal_uint32 OnSendAudioDataToDevice(mal_device *pDevice, mal_uint32 frameCount, void *pFramesOut);
+static mal_uint32 OnAudioBufferDSPRead(mal_dsp *pDSP, mal_uint32 frameCount, void *pFramesOut, void *pUserData);
+static void MixAudioFrames(float *framesOut, const float *framesIn, mal_uint32 frameCount, float localVolume);
+
+// AudioBuffer management functions declaration
+// NOTE: Those functions are not exposed by raylib... for the moment
+AudioBuffer *CreateAudioBuffer(mal_format format, mal_uint32 channels, mal_uint32 sampleRate, mal_uint32 bufferSizeInFrames, AudioBufferUsage usage);
+void DeleteAudioBuffer(AudioBuffer *audioBuffer);
+bool IsAudioBufferPlaying(AudioBuffer *audioBuffer);
+void PlayAudioBuffer(AudioBuffer *audioBuffer);
+void StopAudioBuffer(AudioBuffer *audioBuffer);
+void PauseAudioBuffer(AudioBuffer *audioBuffer);
+void ResumeAudioBuffer(AudioBuffer *audioBuffer);
+void SetAudioBufferVolume(AudioBuffer *audioBuffer, float volume);
+void SetAudioBufferPitch(AudioBuffer *audioBuffer, float pitch);
+void TrackAudioBuffer(AudioBuffer *audioBuffer);
+void UntrackAudioBuffer(AudioBuffer *audioBuffer);
- audioBuffer->prev = NULL;
- audioBuffer->next = NULL;
- }
-
- mal_mutex_unlock(&audioLock);
-}
-static void OnLog_MAL(mal_context *pContext, mal_device *pDevice, const char *message)
+// Log callback function
+static void OnLog(mal_context *pContext, mal_device *pDevice, const char *message)
{
(void)pContext;
(void)pDevice;
- TraceLog(LOG_ERROR, message); // All log messages from mini_al are errors.
-}
-
-// This is the main mixing function. Mixing is pretty simple in this project - it's just an accumulation.
-//
-// framesOut is both an input and an output. It will be initially filled with zeros outside of this function.
-static void MixFrames(float* framesOut, const float* framesIn, mal_uint32 frameCount, float localVolume)
-{
- for (mal_uint32 iFrame = 0; iFrame < frameCount; ++iFrame)
- {
- for (mal_uint32 iChannel = 0; iChannel < device.channels; ++iChannel)
- {
- float *frameOut = framesOut + (iFrame*device.channels);
- const float *frameIn = framesIn + (iFrame*device.channels);
-
- frameOut[iChannel] += frameIn[iChannel]*masterVolume*localVolume;
- }
- }
+
+ TraceLog(LOG_ERROR, message); // All log messages from mini_al are errors
}
+// Sending audio data to device callback function
static mal_uint32 OnSendAudioDataToDevice(mal_device *pDevice, mal_uint32 frameCount, void *pFramesOut)
{
// This is where all of the mixing takes place.
@@ -334,7 +308,7 @@ static mal_uint32 OnSendAudioDataToDevice(mal_device *pDevice, mal_uint32 frameC
// want to consider how you might want to avoid this.
mal_mutex_lock(&audioLock);
{
- for (AudioBuffer* audioBuffer = firstAudioBuffer; audioBuffer != NULL; audioBuffer = audioBuffer->next)
+ for (AudioBuffer *audioBuffer = firstAudioBuffer; audioBuffer != NULL; audioBuffer = audioBuffer->next)
{
// Ignore stopped or paused sounds.
if (!audioBuffer->playing || audioBuffer->paused) continue;
@@ -364,14 +338,14 @@ static mal_uint32 OnSendAudioDataToDevice(mal_device *pDevice, mal_uint32 frameC
// If we're not looping, we need to make sure we flush the internal buffers of the DSP pipeline to ensure we get the
// last few samples.
- mal_bool32 flushDSP = !audioBuffer->looping;
+ bool flushDSP = !audioBuffer->looping;
mal_uint32 framesJustRead = mal_dsp_read_frames_ex(&audioBuffer->dsp, framesToReadRightNow, tempBuffer, flushDSP);
if (framesJustRead > 0)
{
float *framesOut = (float *)pFramesOut + (framesRead*device.channels);
float *framesIn = tempBuffer;
- MixFrames(framesOut, framesIn, framesJustRead, audioBuffer->volume);
+ MixAudioFrames(framesOut, framesIn, framesJustRead, audioBuffer->volume);
framesToRead -= framesJustRead;
framesRead += framesJustRead;
@@ -387,15 +361,16 @@ static mal_uint32 OnSendAudioDataToDevice(mal_device *pDevice, mal_uint32 frameC
}
else
{
- // Should never get here, but just for safety, move the cursor position back to the start and continue the loop.
+ // Should never get here, but just for safety,
+ // move the cursor position back to the start and continue the loop.
audioBuffer->frameCursorPos = 0;
continue;
}
}
}
- // If for some reason we weren't able to read every frame we'll need to break from the loop. Not doing this could
- // theoretically put us into an infinite loop.
+ // If for some reason we weren't able to read every frame we'll need to break from the loop.
+ // Not doing this could theoretically put us into an infinite loop.
if (framesToRead > 0) break;
}
}
@@ -405,14 +380,122 @@ static mal_uint32 OnSendAudioDataToDevice(mal_device *pDevice, mal_uint32 frameC
return frameCount; // We always output the same number of frames that were originally requested.
}
+
+// DSP read from audio buffer callback function
+static mal_uint32 OnAudioBufferDSPRead(mal_dsp *pDSP, mal_uint32 frameCount, void *pFramesOut, void *pUserData)
+{
+ AudioBuffer *audioBuffer = (AudioBuffer *)pUserData;
+
+ mal_uint32 subBufferSizeInFrames = audioBuffer->bufferSizeInFrames/2;
+ mal_uint32 currentSubBufferIndex = audioBuffer->frameCursorPos/subBufferSizeInFrames;
+
+ if (currentSubBufferIndex > 1)
+ {
+ TraceLog(LOG_DEBUG, "Frame cursor position moved too far forward in audio stream");
+ return 0;
+ }
+
+ // Another thread can update the processed state of buffers so we just take a copy here to try and avoid potential synchronization problems.
+ bool isSubBufferProcessed[2];
+ isSubBufferProcessed[0] = audioBuffer->isSubBufferProcessed[0];
+ isSubBufferProcessed[1] = audioBuffer->isSubBufferProcessed[1];
+
+ mal_uint32 frameSizeInBytes = mal_get_sample_size_in_bytes(audioBuffer->dsp.config.formatIn)*audioBuffer->dsp.config.channelsIn;
+
+ // Fill out every frame until we find a buffer that's marked as processed. Then fill the remainder with 0.
+ mal_uint32 framesRead = 0;
+ for (;;)
+ {
+ // We break from this loop differently depending on the buffer's usage. For static buffers, we simply fill as much data as we can. For
+ // streaming buffers we only fill the halves of the buffer that are processed. Unprocessed halves must keep their audio data in-tact.
+ if (audioBuffer->usage == AUDIO_BUFFER_USAGE_STATIC)
+ {
+ if (framesRead >= frameCount) break;
+ }
+ else
+ {
+ if (isSubBufferProcessed[currentSubBufferIndex]) break;
+ }
+
+ mal_uint32 totalFramesRemaining = (frameCount - framesRead);
+ if (totalFramesRemaining == 0) break;
+
+ mal_uint32 framesRemainingInOutputBuffer;
+ if (audioBuffer->usage == AUDIO_BUFFER_USAGE_STATIC)
+ {
+ framesRemainingInOutputBuffer = audioBuffer->bufferSizeInFrames - audioBuffer->frameCursorPos;
+ }
+ else
+ {
+ mal_uint32 firstFrameIndexOfThisSubBuffer = subBufferSizeInFrames * currentSubBufferIndex;
+ framesRemainingInOutputBuffer = subBufferSizeInFrames - (audioBuffer->frameCursorPos - firstFrameIndexOfThisSubBuffer);
+ }
+
+ mal_uint32 framesToRead = totalFramesRemaining;
+ if (framesToRead > framesRemainingInOutputBuffer) framesToRead = framesRemainingInOutputBuffer;
+
+ memcpy((unsigned char *)pFramesOut + (framesRead*frameSizeInBytes), audioBuffer->buffer + (audioBuffer->frameCursorPos*frameSizeInBytes), framesToRead*frameSizeInBytes);
+ audioBuffer->frameCursorPos = (audioBuffer->frameCursorPos + framesToRead) % audioBuffer->bufferSizeInFrames;
+ framesRead += framesToRead;
+
+ // If we've read to the end of the buffer, mark it as processed.
+ if (framesToRead == framesRemainingInOutputBuffer)
+ {
+ audioBuffer->isSubBufferProcessed[currentSubBufferIndex] = true;
+ isSubBufferProcessed[currentSubBufferIndex] = true;
+
+ currentSubBufferIndex = (currentSubBufferIndex + 1)%2;
+
+ // We need to break from this loop if we're not looping.
+ if (!audioBuffer->looping)
+ {
+ StopAudioBuffer(audioBuffer);
+ break;
+ }
+ }
+ }
+
+ // Zero-fill excess.
+ mal_uint32 totalFramesRemaining = (frameCount - framesRead);
+ if (totalFramesRemaining > 0)
+ {
+ memset((unsigned char*)pFramesOut + (framesRead*frameSizeInBytes), 0, totalFramesRemaining*frameSizeInBytes);
+
+ // For static buffers we can fill the remaining frames with silence for safety, but we don't want
+ // to report those frames as "read". The reason for this is that the caller uses the return value
+ // to know whether or not a non-looping sound has finished playback.
+ if (audioBuffer->usage != AUDIO_BUFFER_USAGE_STATIC) framesRead += totalFramesRemaining;
+ }
+
+ return framesRead;
+}
+
+// This is the main mixing function. Mixing is pretty simple in this project - it's just an accumulation.
+// NOTE: framesOut is both an input and an output. It will be initially filled with zeros outside of this function.
+static void MixAudioFrames(float *framesOut, const float *framesIn, mal_uint32 frameCount, float localVolume)
+{
+ for (mal_uint32 iFrame = 0; iFrame < frameCount; ++iFrame)
+ {
+ for (mal_uint32 iChannel = 0; iChannel < device.channels; ++iChannel)
+ {
+ float *frameOut = framesOut + (iFrame*device.channels);
+ const float *frameIn = framesIn + (iFrame*device.channels);
+
+ frameOut[iChannel] += frameIn[iChannel]*masterVolume*localVolume;
+ }
+ }
+}
#endif
+//----------------------------------------------------------------------------------
+// Module Functions Definition - Audio Device initialization and Closing
+//----------------------------------------------------------------------------------
// Initialize audio device
void InitAudioDevice(void)
{
#if USE_MINI_AL
// Context.
- mal_context_config contextConfig = mal_context_config_init(OnLog_MAL);
+ mal_context_config contextConfig = mal_context_config_init(OnLog);
mal_result result = mal_context_init(NULL, 0, &contextConfig, &context);
if (result != MAL_SUCCESS)
{
@@ -556,100 +639,11 @@ void SetMasterVolume(float volume)
#endif
}
-
//----------------------------------------------------------------------------------
-// Audio Buffer
+// Module Functions Definition - Audio Buffer management
//----------------------------------------------------------------------------------
#if USE_MINI_AL
-static mal_uint32 AudioBuffer_OnDSPRead(mal_dsp* pDSP, mal_uint32 frameCount, void* pFramesOut, void* pUserData)
-{
- AudioBuffer *audioBuffer = (AudioBuffer *)pUserData;
-
- mal_uint32 subBufferSizeInFrames = audioBuffer->bufferSizeInFrames/2;
- mal_uint32 currentSubBufferIndex = audioBuffer->frameCursorPos/subBufferSizeInFrames;
-
- if (currentSubBufferIndex > 1)
- {
- TraceLog(LOG_DEBUG, "Frame cursor position moved too far forward in audio stream");
- return 0;
- }
-
- // Another thread can update the processed state of buffers so we just take a copy here to try and avoid potential synchronization problems.
- bool isSubBufferProcessed[2];
- isSubBufferProcessed[0] = audioBuffer->isSubBufferProcessed[0];
- isSubBufferProcessed[1] = audioBuffer->isSubBufferProcessed[1];
-
- mal_uint32 frameSizeInBytes = mal_get_sample_size_in_bytes(audioBuffer->dsp.config.formatIn)*audioBuffer->dsp.config.channelsIn;
-
- // Fill out every frame until we find a buffer that's marked as processed. Then fill the remainder with 0.
- mal_uint32 framesRead = 0;
- for (;;)
- {
- // We break from this loop differently depending on the buffer's usage. For static buffers, we simply fill as much data as we can. For
- // streaming buffers we only fill the halves of the buffer that are processed. Unprocessed halves must keep their audio data in-tact.
- if (audioBuffer->usage == AUDIO_BUFFER_USAGE_STATIC)
- {
- if (framesRead >= frameCount) break;
- }
- else
- {
- if (isSubBufferProcessed[currentSubBufferIndex]) break;
- }
-
- mal_uint32 totalFramesRemaining = (frameCount - framesRead);
- if (totalFramesRemaining == 0) break;
-
- mal_uint32 framesRemainingInOutputBuffer;
- if (audioBuffer->usage == AUDIO_BUFFER_USAGE_STATIC)
- {
- framesRemainingInOutputBuffer = audioBuffer->bufferSizeInFrames - audioBuffer->frameCursorPos;
- }
- else
- {
- mal_uint32 firstFrameIndexOfThisSubBuffer = subBufferSizeInFrames * currentSubBufferIndex;
- framesRemainingInOutputBuffer = subBufferSizeInFrames - (audioBuffer->frameCursorPos - firstFrameIndexOfThisSubBuffer);
- }
-
- mal_uint32 framesToRead = totalFramesRemaining;
- if (framesToRead > framesRemainingInOutputBuffer) framesToRead = framesRemainingInOutputBuffer;
-
- memcpy((unsigned char *)pFramesOut + (framesRead*frameSizeInBytes), audioBuffer->buffer + (audioBuffer->frameCursorPos*frameSizeInBytes), framesToRead*frameSizeInBytes);
- audioBuffer->frameCursorPos = (audioBuffer->frameCursorPos + framesToRead) % audioBuffer->bufferSizeInFrames;
- framesRead += framesToRead;
-
- // If we've read to the end of the buffer, mark it as processed.
- if (framesToRead == framesRemainingInOutputBuffer)
- {
- audioBuffer->isSubBufferProcessed[currentSubBufferIndex] = true;
- isSubBufferProcessed[currentSubBufferIndex] = true;
-
- currentSubBufferIndex = (currentSubBufferIndex + 1) % 2;
-
- // We need to break from this loop if we're not looping.
- if (!audioBuffer->looping)
- {
- StopAudioBuffer(audioBuffer);
- break;
- }
- }
- }
-
- // Zero-fill excess.
- mal_uint32 totalFramesRemaining = (frameCount - framesRead);
- if (totalFramesRemaining > 0)
- {
- memset((unsigned char*)pFramesOut + (framesRead*frameSizeInBytes), 0, totalFramesRemaining*frameSizeInBytes);
-
- // For static buffers we can fill the remaining frames with silence for safety, but we don't want
- // to report those frames as "read". The reason for this is that the caller uses the return value
- // to know whether or not a non-looping sound has finished playback.
- if (audioBuffer->usage != AUDIO_BUFFER_USAGE_STATIC) framesRead += totalFramesRemaining;
- }
-
- return framesRead;
-}
-
-// Create a new audio buffer. Initially filled with silence.
+// Create a new audio buffer. Initially filled with silence
AudioBuffer *CreateAudioBuffer(mal_format format, mal_uint32 channels, mal_uint32 sampleRate, mal_uint32 bufferSizeInFrames, AudioBufferUsage usage)
{
AudioBuffer *audioBuffer = (AudioBuffer *)calloc(sizeof(*audioBuffer) + (bufferSizeInFrames*channels*mal_get_sample_size_in_bytes(format)), 1);
@@ -668,7 +662,7 @@ AudioBuffer *CreateAudioBuffer(mal_format format, mal_uint32 channels, mal_uint3
dspConfig.channelsOut = DEVICE_CHANNELS;
dspConfig.sampleRateIn = sampleRate;
dspConfig.sampleRateOut = DEVICE_SAMPLE_RATE;
- mal_result resultMAL = mal_dsp_init(&dspConfig, AudioBuffer_OnDSPRead, audioBuffer, &audioBuffer->dsp);
+ mal_result resultMAL = mal_dsp_init(&dspConfig, OnAudioBufferDSPRead, audioBuffer, &audioBuffer->dsp);
if (resultMAL != MAL_SUCCESS)
{
TraceLog(LOG_ERROR, "LoadSoundFromWave() : Failed to create data conversion pipeline");
@@ -694,7 +688,7 @@ AudioBuffer *CreateAudioBuffer(mal_format format, mal_uint32 channels, mal_uint3
return audioBuffer;
}
-// Delete an audio buffer.
+// Delete an audio buffer
void DeleteAudioBuffer(AudioBuffer *audioBuffer)
{
if (audioBuffer == NULL)
@@ -707,7 +701,7 @@ void DeleteAudioBuffer(AudioBuffer *audioBuffer)
free(audioBuffer);
}
-// Check if an audio buffer is playing.
+// Check if an audio buffer is playing
bool IsAudioBufferPlaying(AudioBuffer *audioBuffer)
{
if (audioBuffer == NULL)
@@ -719,10 +713,9 @@ bool IsAudioBufferPlaying(AudioBuffer *audioBuffer)
return audioBuffer->playing && !audioBuffer->paused;
}
-// Play an audio buffer.
-//
-// This will restart the buffer from the start. Use PauseAudioBuffer() and ResumeAudioBuffer() if the playback position
-// should be maintained.
+// Play an audio buffer
+// NOTE: Buffer is restarted to the start.
+// Use PauseAudioBuffer() and ResumeAudioBuffer() if the playback position should be maintained.
void PlayAudioBuffer(AudioBuffer *audioBuffer)
{
if (audioBuffer == NULL)
@@ -736,7 +729,7 @@ void PlayAudioBuffer(AudioBuffer *audioBuffer)
audioBuffer->frameCursorPos = 0;
}
-// Stop an audio buffer.
+// Stop an audio buffer
void StopAudioBuffer(AudioBuffer *audioBuffer)
{
if (audioBuffer == NULL)
@@ -755,7 +748,7 @@ void StopAudioBuffer(AudioBuffer *audioBuffer)
audioBuffer->isSubBufferProcessed[1] = true;
}
-// Pause an audio buffer.
+// Pause an audio buffer
void PauseAudioBuffer(AudioBuffer *audioBuffer)
{
if (audioBuffer == NULL)
@@ -767,7 +760,7 @@ void PauseAudioBuffer(AudioBuffer *audioBuffer)
audioBuffer->paused = true;
}
-// Resume an audio buffer.
+// Resume an audio buffer
void ResumeAudioBuffer(AudioBuffer *audioBuffer)
{
if (audioBuffer == NULL)
@@ -779,7 +772,7 @@ void ResumeAudioBuffer(AudioBuffer *audioBuffer)
audioBuffer->paused = false;
}
-// Set volume for an audio buffer.
+// Set volume for an audio buffer
void SetAudioBufferVolume(AudioBuffer *audioBuffer, float volume)
{
if (audioBuffer == NULL)
@@ -791,7 +784,7 @@ void SetAudioBufferVolume(AudioBuffer *audioBuffer, float volume)
audioBuffer->volume = volume;
}
-// Set pitch for an audio buffer.
+// Set pitch for an audio buffer
void SetAudioBufferPitch(AudioBuffer *audioBuffer, float pitch)
{
if (audioBuffer == NULL)
@@ -807,6 +800,44 @@ void SetAudioBufferPitch(AudioBuffer *audioBuffer, float pitch)
mal_uint32 newOutputSampleRate = (mal_uint32)((((float)audioBuffer->dsp.config.sampleRateOut / (float)audioBuffer->dsp.config.sampleRateIn) / pitch) * audioBuffer->dsp.config.sampleRateIn);
mal_dsp_set_output_sample_rate(&audioBuffer->dsp, newOutputSampleRate);
}
+
+// Track audio buffer to linked list next position
+void TrackAudioBuffer(AudioBuffer *audioBuffer)
+{
+ mal_mutex_lock(&audioLock);
+
+ {
+ if (firstAudioBuffer == NULL) firstAudioBuffer = audioBuffer;
+ else
+ {
+ lastAudioBuffer->next = audioBuffer;
+ audioBuffer->prev = lastAudioBuffer;
+ }
+
+ lastAudioBuffer = audioBuffer;
+ }
+
+ mal_mutex_unlock(&audioLock);
+}
+
+// Untrack audio buffer from linked list
+void UntrackAudioBuffer(AudioBuffer *audioBuffer)
+{
+ mal_mutex_lock(&audioLock);
+
+ {
+ if (audioBuffer->prev == NULL) firstAudioBuffer = audioBuffer->next;
+ else audioBuffer->prev->next = audioBuffer->next;
+
+ if (audioBuffer->next == NULL) lastAudioBuffer = audioBuffer->prev;
+ else audioBuffer->next->prev = audioBuffer->prev;
+
+ audioBuffer->prev = NULL;
+ audioBuffer->next = NULL;
+ }
+
+ mal_mutex_unlock(&audioLock);
+}
#endif
//----------------------------------------------------------------------------------
@@ -883,13 +914,13 @@ Sound LoadSoundFromWave(Wave wave)
mal_uint32 frameCountIn = wave.sampleCount; // Is wave->sampleCount actually the frame count? That terminology needs to change, if so.
mal_uint32 frameCount = mal_convert_frames(NULL, DEVICE_FORMAT, DEVICE_CHANNELS, DEVICE_SAMPLE_RATE, NULL, formatIn, wave.channels, wave.sampleRate, frameCountIn);
- if (frameCount == 0) TraceLog(LOG_ERROR, "LoadSoundFromWave() : Failed to get frame count for format conversion");
+ if (frameCount == 0) TraceLog(LOG_WARNING, "LoadSoundFromWave() : Failed to get frame count for format conversion");
AudioBuffer* audioBuffer = CreateAudioBuffer(DEVICE_FORMAT, DEVICE_CHANNELS, DEVICE_SAMPLE_RATE, frameCount, AUDIO_BUFFER_USAGE_STATIC);
- if (audioBuffer == NULL) TraceLog(LOG_ERROR, "LoadSoundFromWave() : Failed to create audio buffer");
+ if (audioBuffer == NULL) TraceLog(LOG_WARNING, "LoadSoundFromWave() : Failed to create audio buffer");
frameCount = mal_convert_frames(audioBuffer->buffer, audioBuffer->dsp.config.formatIn, audioBuffer->dsp.config.channelsIn, audioBuffer->dsp.config.sampleRateIn, wave.data, formatIn, wave.channels, wave.sampleRate, frameCountIn);
- if (frameCount == 0) TraceLog(LOG_ERROR, "LoadSoundFromWave() : Format conversion failed");
+ if (frameCount == 0) TraceLog(LOG_WARNING, "LoadSoundFromWave() : Format conversion failed");
sound.audioBuffer = audioBuffer;
#else
@@ -1853,7 +1884,7 @@ void CloseAudioStream(AudioStream stream)
void UpdateAudioStream(AudioStream stream, const void *data, int samplesCount)
{
#if USE_MINI_AL
- AudioBuffer* audioBuffer = (AudioBuffer*)stream.audioBuffer;
+ AudioBuffer *audioBuffer = (AudioBuffer *)stream.audioBuffer;
if (audioBuffer == NULL)
{
TraceLog(LOG_ERROR, "UpdateAudioStream() : No audio buffer");