summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorRay <[email protected]>2024-04-20 20:30:35 +0200
committerRay <[email protected]>2024-04-20 20:30:35 +0200
commitc1943f0f7c253cd839c7633e02d3d7f3aa3a6833 (patch)
treeec1718839ed8f6f2a18babf3498b457ab3b1fb3b /src
parentd80a622972deaaa1185d2c37d82cb21f0c16e697 (diff)
downloadraylib-c1943f0f7c253cd839c7633e02d3d7f3aa3a6833.tar.gz
raylib-c1943f0f7c253cd839c7633e02d3d7f3aa3a6833.zip
REVIEWED: Move some functions, made them static
Diffstat (limited to 'src')
-rw-r--r--src/raudio.c212
1 files changed, 108 insertions, 104 deletions
diff --git a/src/raudio.c b/src/raudio.c
index 6f7e9a72..b3874dbe 100644
--- a/src/raudio.c
+++ b/src/raudio.c
@@ -410,9 +410,18 @@ static AudioData AUDIO = { // Global AUDIO context
// Module specific Functions Declaration
//----------------------------------------------------------------------------------
static void OnLog(void *pUserData, ma_uint32 level, const char *pMessage);
+
+// Reads audio data from an AudioBuffer object in internal/device formats
+static ma_uint32 ReadAudioBufferFramesInInternalFormat(AudioBuffer *audioBuffer, void *framesOut, ma_uint32 frameCount);
+static ma_uint32 ReadAudioBufferFramesInMixingFormat(AudioBuffer *audioBuffer, float *framesOut, ma_uint32 frameCount);
+
static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const void *pFramesInput, ma_uint32 frameCount);
static void MixAudioFrames(float *framesOut, const float *framesIn, ma_uint32 frameCount, AudioBuffer *buffer);
+static bool IsAudioBufferPlayingInLockedState(AudioBuffer *buffer);
+static void StopAudioBufferInLockedState(AudioBuffer *buffer);
+static void UpdateAudioStreamInLockedState(AudioStream stream, const void *data, int frameCount);
+
#if defined(RAUDIO_STANDALONE)
static bool IsFileExtension(const char *fileName, const char *ext); // Check file extension
static const char *GetFileExtension(const char *fileName); // Get pointer to extension for a filename string (includes the dot: .png)
@@ -431,10 +440,8 @@ static bool SaveFileText(const char *fileName, char *text); // Save text
AudioBuffer *LoadAudioBuffer(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, ma_uint32 sizeInFrames, int usage);
void UnloadAudioBuffer(AudioBuffer *buffer);
-bool IsAudioBufferPlayingInLockedState(AudioBuffer *buffer);
bool IsAudioBufferPlaying(AudioBuffer *buffer);
void PlayAudioBuffer(AudioBuffer *buffer);
-void StopAudioBufferInLockedState(AudioBuffer *buffer);
void StopAudioBuffer(AudioBuffer *buffer);
void PauseAudioBuffer(AudioBuffer *buffer);
void ResumeAudioBuffer(AudioBuffer *buffer);
@@ -444,10 +451,6 @@ void SetAudioBufferPan(AudioBuffer *buffer, float pan);
void TrackAudioBuffer(AudioBuffer *buffer);
void UntrackAudioBuffer(AudioBuffer *buffer);
-//----------------------------------------------------------------------------------
-// AudioStream management functions declaration
-//----------------------------------------------------------------------------------
-void UpdateAudioStreamInLockedState(AudioStream stream, const void *data, int frameCount);
//----------------------------------------------------------------------------------
// Module Functions Definition - Audio Device initialization and Closing
@@ -467,12 +470,12 @@ void InitAudioDevice(void)
}
// Init audio device
- // NOTE: Using the default device. Format is floating point because it simplifies mixing.
+ // NOTE: Using the default device. Format is floating point because it simplifies mixing
ma_device_config config = ma_device_config_init(ma_device_type_playback);
- config.playback.pDeviceID = NULL; // NULL for the default playback AUDIO.System.device.
+ config.playback.pDeviceID = NULL; // NULL for the default playback AUDIO.System.device
config.playback.format = AUDIO_DEVICE_FORMAT;
config.playback.channels = AUDIO_DEVICE_CHANNELS;
- config.capture.pDeviceID = NULL; // NULL for the default capture AUDIO.System.device.
+ config.capture.pDeviceID = NULL; // NULL for the default capture AUDIO.System.device
config.capture.format = ma_format_s16;
config.capture.channels = 1;
config.sampleRate = AUDIO_DEVICE_SAMPLE_RATE;
@@ -488,7 +491,7 @@ void InitAudioDevice(void)
}
// Mixing happens on a separate thread which means we need to synchronize. I'm using a mutex here to make things simple, but may
- // want to look at something a bit smarter later on to keep everything real-time, if that's necessary.
+ // want to look at something a bit smarter later on to keep everything real-time, if that's necessary
if (ma_mutex_init(&AUDIO.System.lock) != MA_SUCCESS)
{
TRACELOG(LOG_WARNING, "AUDIO: Failed to create mutex for mixing");
@@ -498,7 +501,7 @@ void InitAudioDevice(void)
}
// Keep the device running the whole time. May want to consider doing something a bit smarter and only have the device running
- // while there's at least one sound being played.
+ // while there's at least one sound being played
result = ma_device_start(&AUDIO.System.device);
if (result != MA_SUCCESS)
{
@@ -626,17 +629,7 @@ void UnloadAudioBuffer(AudioBuffer *buffer)
}
}
-// Check if an audio buffer is playing, assuming the audio system mutex has been locked.
-bool IsAudioBufferPlayingInLockedState(AudioBuffer *buffer)
-{
- bool result = false;
-
- if (buffer != NULL) result = (buffer->playing && !buffer->paused);
-
- return result;
-}
-
-// Check if an audio buffer is playing from a program state without lock.
+// Check if an audio buffer is playing from a program state without lock
bool IsAudioBufferPlaying(AudioBuffer *buffer)
{
bool result = false;
@@ -647,8 +640,8 @@ bool IsAudioBufferPlaying(AudioBuffer *buffer)
}
// Play an audio buffer
-// NOTE: Buffer is restarted to the start.
-// Use PauseAudioBuffer() and ResumeAudioBuffer() if the playback position should be maintained.
+// NOTE: Buffer is restarted to the start
+// Use PauseAudioBuffer() and ResumeAudioBuffer() if the playback position should be maintained
void PlayAudioBuffer(AudioBuffer *buffer)
{
if (buffer != NULL)
@@ -661,24 +654,7 @@ void PlayAudioBuffer(AudioBuffer *buffer)
}
}
-// Stop an audio buffer, assuming the audio system mutex has been locked.
-void StopAudioBufferInLockedState(AudioBuffer *buffer)
-{
- if (buffer != NULL)
- {
- if (IsAudioBufferPlayingInLockedState(buffer))
- {
- buffer->playing = false;
- buffer->paused = false;
- buffer->frameCursorPos = 0;
- buffer->framesProcessed = 0;
- buffer->isSubBufferProcessed[0] = true;
- buffer->isSubBufferProcessed[1] = true;
- }
- }
-}
-
-// Stop an audio buffer from a program state without lock.
+// Stop an audio buffer from a program state without lock
void StopAudioBuffer(AudioBuffer *buffer)
{
ma_mutex_lock(&AUDIO.System.lock);
@@ -725,7 +701,7 @@ void SetAudioBufferPitch(AudioBuffer *buffer, float pitch)
if ((buffer != NULL) && (pitch > 0.0f))
{
ma_mutex_lock(&AUDIO.System.lock);
- // Pitching is just an adjustment of the sample rate.
+ // Pitching is just an adjustment of the sample rate
// Note that this changes the duration of the sound:
// - higher pitches will make the sound faster
// - lower pitches make it slower
@@ -951,15 +927,15 @@ Sound LoadSoundFromWave(Wave wave)
if (wave.data != NULL)
{
- // When using miniaudio we need to do our own mixing.
+ // When using miniaudio we need to do our own mixing
// To simplify this we need convert the format of each sound to be consistent with
// the format used to open the playback AUDIO.System.device. We can do this two ways:
//
- // 1) Convert the whole sound in one go at load time (here).
- // 2) Convert the audio data in chunks at mixing time.
+ // 1) Convert the whole sound in one go at load time (here)
+ // 2) Convert the audio data in chunks at mixing time
//
- // First option has been selected, format conversion is done on the loading stage.
- // The downside is that it uses more memory if the original sound is u8 or s16.
+ // First option has been selected, format conversion is done on the loading stage
+ // The downside is that it uses more memory if the original sound is u8 or s16
ma_format formatIn = ((wave.sampleSize == 8)? ma_format_u8 : ((wave.sampleSize == 16)? ma_format_s16 : ma_format_f32));
ma_uint32 frameCountIn = wave.frameCount;
@@ -2167,55 +2143,6 @@ void UpdateAudioStream(AudioStream stream, const void *data, int frameCount)
ma_mutex_unlock(&AUDIO.System.lock);
}
-void UpdateAudioStreamInLockedState(AudioStream stream, const void *data, int frameCount)
-{
- if (stream.buffer != NULL)
- {
- if (stream.buffer->isSubBufferProcessed[0] || stream.buffer->isSubBufferProcessed[1])
- {
- ma_uint32 subBufferToUpdate = 0;
-
- if (stream.buffer->isSubBufferProcessed[0] && stream.buffer->isSubBufferProcessed[1])
- {
- // Both buffers are available for updating.
- // Update the first one and make sure the cursor is moved back to the front.
- subBufferToUpdate = 0;
- stream.buffer->frameCursorPos = 0;
- }
- else
- {
- // Just update whichever sub-buffer is processed.
- subBufferToUpdate = (stream.buffer->isSubBufferProcessed[0])? 0 : 1;
- }
-
- ma_uint32 subBufferSizeInFrames = stream.buffer->sizeInFrames/2;
- unsigned char *subBuffer = stream.buffer->data + ((subBufferSizeInFrames*stream.channels*(stream.sampleSize/8))*subBufferToUpdate);
-
- // Total frames processed in buffer is always the complete size, filled with 0 if required
- stream.buffer->framesProcessed += subBufferSizeInFrames;
-
- // Does this API expect a whole buffer to be updated in one go?
- // Assuming so, but if not will need to change this logic.
- if (subBufferSizeInFrames >= (ma_uint32)frameCount)
- {
- ma_uint32 framesToWrite = (ma_uint32)frameCount;
-
- ma_uint32 bytesToWrite = framesToWrite*stream.channels*(stream.sampleSize/8);
- memcpy(subBuffer, data, bytesToWrite);
-
- // Any leftover frames should be filled with zeros.
- ma_uint32 leftoverFrameCount = subBufferSizeInFrames - framesToWrite;
-
- if (leftoverFrameCount > 0) memset(subBuffer + bytesToWrite, 0, leftoverFrameCount*stream.channels*(stream.sampleSize/8));
-
- stream.buffer->isSubBufferProcessed[subBufferToUpdate] = false;
- }
- else TRACELOG(LOG_WARNING, "STREAM: Attempting to write too many frames to buffer");
- }
- else TRACELOG(LOG_WARNING, "STREAM: Buffer not available for updating");
- }
-}
-
// Check if any audio stream buffers requires refill
bool IsAudioStreamProcessed(AudioStream stream)
{
@@ -2246,7 +2173,7 @@ void ResumeAudioStream(AudioStream stream)
ResumeAudioBuffer(stream.buffer);
}
-// Check if audio stream is playing.
+// Check if audio stream is playing
bool IsAudioStreamPlaying(AudioStream stream)
{
return IsAudioBufferPlaying(stream.buffer);
@@ -2293,9 +2220,9 @@ void SetAudioStreamCallback(AudioStream stream, AudioCallback callback)
}
}
-// Add processor to audio stream. Contrary to buffers, the order of processors is important.
+// Add processor to audio stream. Contrary to buffers, the order of processors is important
// The new processor must be added at the end. As there aren't supposed to be a lot of processors attached to
-// a given stream, we iterate through the list to find the end. That way we don't need a pointer to the last element.
+// a given stream, we iterate through the list to find the end. That way we don't need a pointer to the last element
void AttachAudioStreamProcessor(AudioStream stream, AudioCallback process)
{
ma_mutex_lock(&AUDIO.System.lock);
@@ -2410,7 +2337,7 @@ static void OnLog(void *pUserData, ma_uint32 level, const char *pMessage)
TRACELOG(LOG_WARNING, "miniaudio: %s", pMessage); // All log messages from miniaudio are errors
}
-// Reads audio data from an AudioBuffer object in internal format.
+// Reads audio data from an AudioBuffer object in internal format
static ma_uint32 ReadAudioBufferFramesInInternalFormat(AudioBuffer *audioBuffer, void *framesOut, ma_uint32 frameCount)
{
// Using audio buffer callback
@@ -2498,20 +2425,20 @@ static ma_uint32 ReadAudioBufferFramesInInternalFormat(AudioBuffer *audioBuffer,
// 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 a non-looping sound has finished playback.
+ // to know whether a non-looping sound has finished playback
if (audioBuffer->usage != AUDIO_BUFFER_USAGE_STATIC) framesRead += totalFramesRemaining;
}
return framesRead;
}
-// Reads audio data from an AudioBuffer object in device format. Returned data will be in a format appropriate for mixing.
+// Reads audio data from an AudioBuffer object in device format, returned data will be in a format appropriate for mixing
static ma_uint32 ReadAudioBufferFramesInMixingFormat(AudioBuffer *audioBuffer, float *framesOut, ma_uint32 frameCount)
{
// What's going on here is that we're continuously converting data from the AudioBuffer's internal format to the mixing format, which
// should be defined by the output format of the data converter. We do this until frameCount frames have been output. The important
// detail to remember here is that we never, ever attempt to read more input data than is required for the specified number of output
- // frames. This can be achieved with ma_data_converter_get_required_input_frame_count().
+ // frames. This can be achieved with ma_data_converter_get_required_input_frame_count()
ma_uint8 inputBuffer[4096] = { 0 };
ma_uint32 inputBufferFrameCap = sizeof(inputBuffer)/ma_get_bytes_per_frame(audioBuffer->converter.formatIn, audioBuffer->converter.channelsIn);
@@ -2693,6 +2620,83 @@ static void MixAudioFrames(float *framesOut, const float *framesIn, ma_uint32 fr
}
}
+// Check if an audio buffer is playing, assuming the audio system mutex has been locked
+static bool IsAudioBufferPlayingInLockedState(AudioBuffer *buffer)
+{
+ bool result = false;
+
+ if (buffer != NULL) result = (buffer->playing && !buffer->paused);
+
+ return result;
+}
+
+// Stop an audio buffer, assuming the audio system mutex has been locked
+static void StopAudioBufferInLockedState(AudioBuffer *buffer)
+{
+ if (buffer != NULL)
+ {
+ if (IsAudioBufferPlayingInLockedState(buffer))
+ {
+ buffer->playing = false;
+ buffer->paused = false;
+ buffer->frameCursorPos = 0;
+ buffer->framesProcessed = 0;
+ buffer->isSubBufferProcessed[0] = true;
+ buffer->isSubBufferProcessed[1] = true;
+ }
+ }
+}
+
+// Update audio stream, assuming the audio system mutex has been locked
+static void UpdateAudioStreamInLockedState(AudioStream stream, const void *data, int frameCount)
+{
+ if (stream.buffer != NULL)
+ {
+ if (stream.buffer->isSubBufferProcessed[0] || stream.buffer->isSubBufferProcessed[1])
+ {
+ ma_uint32 subBufferToUpdate = 0;
+
+ if (stream.buffer->isSubBufferProcessed[0] && stream.buffer->isSubBufferProcessed[1])
+ {
+ // Both buffers are available for updating
+ // Update the first one and make sure the cursor is moved back to the front
+ subBufferToUpdate = 0;
+ stream.buffer->frameCursorPos = 0;
+ }
+ else
+ {
+ // Just update whichever sub-buffer is processed
+ subBufferToUpdate = (stream.buffer->isSubBufferProcessed[0])? 0 : 1;
+ }
+
+ ma_uint32 subBufferSizeInFrames = stream.buffer->sizeInFrames/2;
+ unsigned char *subBuffer = stream.buffer->data + ((subBufferSizeInFrames*stream.channels*(stream.sampleSize/8))*subBufferToUpdate);
+
+ // Total frames processed in buffer is always the complete size, filled with 0 if required
+ stream.buffer->framesProcessed += subBufferSizeInFrames;
+
+ // Does this API expect a whole buffer to be updated in one go?
+ // Assuming so, but if not will need to change this logic
+ if (subBufferSizeInFrames >= (ma_uint32)frameCount)
+ {
+ ma_uint32 framesToWrite = (ma_uint32)frameCount;
+
+ ma_uint32 bytesToWrite = framesToWrite*stream.channels*(stream.sampleSize/8);
+ memcpy(subBuffer, data, bytesToWrite);
+
+ // Any leftover frames should be filled with zeros
+ ma_uint32 leftoverFrameCount = subBufferSizeInFrames - framesToWrite;
+
+ if (leftoverFrameCount > 0) memset(subBuffer + bytesToWrite, 0, leftoverFrameCount*stream.channels*(stream.sampleSize/8));
+
+ stream.buffer->isSubBufferProcessed[subBufferToUpdate] = false;
+ }
+ else TRACELOG(LOG_WARNING, "STREAM: Attempting to write too many frames to buffer");
+ }
+ else TRACELOG(LOG_WARNING, "STREAM: Buffer not available for updating");
+ }
+}
+
// Some required functions for audio standalone module version
#if defined(RAUDIO_STANDALONE)
// Check file extension