From a6f9cc5629841b7adf3d9ff21eaa2aaabb3e4bc1 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 11 Dec 2017 11:55:02 +0100 Subject: Remove rres support Let the user choose if using rres external library --- src/audio.c | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'src/audio.c') diff --git a/src/audio.c b/src/audio.c index d397b064..15f50a24 100644 --- a/src/audio.c +++ b/src/audio.c @@ -812,19 +812,6 @@ Wave LoadWave(const char *fileName) #endif #if defined(SUPPORT_FILEFORMAT_FLAC) else if (IsFileExtension(fileName, ".flac")) wave = LoadFLAC(fileName); -#endif -#if !defined(AUDIO_STANDALONE) - else if (IsFileExtension(fileName, ".rres")) - { - RRES rres = LoadResource(fileName, 0); - - // NOTE: Parameters for RRES_TYPE_WAVE are: sampleCount, sampleRate, sampleSize, channels - - if (rres[0].type == RRES_TYPE_WAVE) wave = LoadWaveEx(rres[0].data, rres[0].param1, rres[0].param2, rres[0].param3, rres[0].param4); - else TraceLog(LOG_WARNING, "[%s] Resource file does not contain wave data", fileName); - - UnloadResource(rres); - } #endif else TraceLog(LOG_WARNING, "[%s] Audio fileformat not supported, it can't be loaded", fileName); -- cgit v1.2.3 From b63ffcfa0f7dcedac190a49ec48fd71d7fe2faf1 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 20 Dec 2017 00:34:31 +0100 Subject: Some code tweaks Audio module requires a complete formatting review.... --- src/audio.c | 31 +++++++++++++++++-------------- src/audio.h | 25 ++++++++++++++++--------- src/raylib.h | 32 ++++++++++---------------------- 3 files changed, 43 insertions(+), 45 deletions(-) (limited to 'src/audio.c') diff --git a/src/audio.c b/src/audio.c index 15f50a24..7a8e185b 100644 --- a/src/audio.c +++ b/src/audio.c @@ -153,7 +153,12 @@ // Types and Structures Definition //---------------------------------------------------------------------------------- -typedef enum { MUSIC_AUDIO_OGG = 0, MUSIC_AUDIO_FLAC, MUSIC_MODULE_XM, MUSIC_MODULE_MOD } MusicContextType; +typedef enum { + MUSIC_AUDIO_OGG = 0, + MUSIC_AUDIO_FLAC, + MUSIC_MODULE_XM, + MUSIC_MODULE_MOD +} MusicContextType; // Music type (file streaming from memory) typedef struct MusicData { @@ -179,7 +184,13 @@ typedef struct MusicData { } MusicData; #if defined(AUDIO_STANDALONE) -typedef enum { LOG_INFO = 0, LOG_ERROR, LOG_WARNING, LOG_DEBUG, LOG_OTHER } TraceLogType; +typedef enum { + LOG_INFO = 0, + LOG_ERROR, + LOG_WARNING, + LOG_DEBUG, + LOG_OTHER +} TraceLogType; #endif //---------------------------------------------------------------------------------- @@ -215,9 +226,8 @@ void TraceLog(int msgType, const char *text, ...); // Show trace lo typedef enum { AUDIO_BUFFER_USAGE_STATIC = 0, AUDIO_BUFFER_USAGE_STREAM } AudioBufferUsage; -typedef struct AudioBuffer AudioBuffer; -struct AudioBuffer -{ +// Audio buffer structure +typedef struct AudioBuffer { mal_dsp dsp; // For format conversion. float volume; float pitch; @@ -231,10 +241,9 @@ struct AudioBuffer AudioBuffer* next; AudioBuffer* prev; unsigned char buffer[1]; -}; - -void StopAudioBuffer(AudioBuffer* audioBuffer); +} AudioBuffer; +void StopAudioBuffer(AudioBuffer *audioBuffer); static mal_context context; static mal_device device; @@ -400,12 +409,6 @@ void InitAudioDevice(void) // Device. Using the default device. Format is floating point because it simplifies mixing. mal_device_config deviceConfig = mal_device_config_init(DEVICE_FORMAT, DEVICE_CHANNELS, DEVICE_SAMPLE_RATE, NULL, OnSendAudioDataToDevice); - // Special case for PLATFORM_RPI. -//#if defined(PLATFORM_RPI) -// deviceConfig.alsa.noMMap = MAL_TRUE; -// deviceConfig.bufferSizeInFrames = 2048; -//#endif - result = mal_device_init(&context, mal_device_type_playback, NULL, &deviceConfig, NULL, &device); if (result != MAL_SUCCESS) { diff --git a/src/audio.h b/src/audio.h index 48ef7403..4c9faf25 100644 --- a/src/audio.h +++ b/src/audio.h @@ -81,9 +81,11 @@ typedef struct Wave { // Sound source type typedef struct Sound { - unsigned int source; // OpenAL audio source id - unsigned int buffer; // OpenAL audio buffer id - int format; // OpenAL audio format specifier + void *audioBuffer; // Pointer to internal data used by the audio system + + unsigned int source; // Audio source id + unsigned int buffer; // Audio buffer id + int format; // Audio format specifier } Sound; // Music type (file streaming from memory) @@ -97,9 +99,11 @@ typedef struct AudioStream { unsigned int sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported) unsigned int channels; // Number of channels (1-mono, 2-stereo) - int format; // OpenAL audio format specifier - unsigned int source; // OpenAL audio source id - unsigned int buffers[2]; // OpenAL audio buffers (double buffering) + void *audioBuffer; // Pointer to internal data used by the audio system. + + int format; // Audio format specifier + unsigned int source; // Audio source id + unsigned int buffers[2]; // Audio buffers (double buffering) } AudioStream; #ifdef __cplusplus @@ -147,12 +151,12 @@ void ResumeMusicStream(Music music); // Resume playin bool IsMusicPlaying(Music music); // Check if music is playing void SetMusicVolume(Music music, float volume); // Set volume for music (1.0 is max level) void SetMusicPitch(Music music, float pitch); // Set pitch for a music (1.0 is base level) -void SetMusicLoopCount(Music music, float count); // Set music loop count (loop repeats) +void SetMusicLoopCount(Music music, int count); // Set music loop count (loop repeats) float GetMusicTimeLength(Music music); // Get music time length (in seconds) float GetMusicTimePlayed(Music music); // Get current music time played (in seconds) -// Raw audio stream functions -AudioStream InitAudioStream(unsigned int sampleRate, +// AudioStream management functions +AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels); // Init audio stream (to stream raw audio pcm data) void UpdateAudioStream(AudioStream stream, const void *data, int samplesCount); // Update audio stream buffers with data @@ -161,7 +165,10 @@ bool IsAudioBufferProcessed(AudioStream stream); // Check if any void PlayAudioStream(AudioStream stream); // Play audio stream void PauseAudioStream(AudioStream stream); // Pause audio stream void ResumeAudioStream(AudioStream stream); // Resume audio stream +bool IsAudioStreamPlaying(AudioStream stream); // Check if audio stream is playing void StopAudioStream(AudioStream stream); // Stop audio stream +void SetAudioStreamVolume(AudioStream stream, float volume); // Set volume for audio stream (1.0 is max level) +void SetAudioStreamPitch(AudioStream stream, float pitch); // Set pitch for audio stream (1.0 is base level) #ifdef __cplusplus } diff --git a/src/raylib.h b/src/raylib.h index 4100cee1..b0ff1fc1 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -470,11 +470,11 @@ typedef struct Wave { // Sound source type typedef struct Sound { - void* audioBuffer; // A pointer to internal data used by the audio system. + void *audioBuffer; // Pointer to internal data used by the audio system - unsigned int source; // OpenAL audio source id - unsigned int buffer; // OpenAL audio buffer id - int format; // OpenAL audio format specifier + unsigned int source; // Audio source id + unsigned int buffer; // Audio buffer id + int format; // Audio format specifier } Sound; // Music type (file streaming from memory) @@ -488,11 +488,11 @@ typedef struct AudioStream { unsigned int sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported) unsigned int channels; // Number of channels (1-mono, 2-stereo) - void* audioBuffer; // A pointer to internal data used by the audio system. + void *audioBuffer; // Pointer to internal data used by the audio system. - int format; // OpenAL audio format specifier - unsigned int source; // OpenAL audio source id - unsigned int buffers[2]; // OpenAL audio buffers (double buffering) + int format; // Audio format specifier + unsigned int source; // Audio source id + unsigned int buffers[2]; // Audio buffers (double buffering) } AudioStream; // Head-Mounted-Display device parameters @@ -656,18 +656,6 @@ typedef enum { HMD_SONY_PSVR } VrDeviceType; -// RRESData type -typedef enum { - RRES_TYPE_RAW = 0, - RRES_TYPE_IMAGE, - RRES_TYPE_WAVE, - RRES_TYPE_VERTEX, - RRES_TYPE_TEXT, - RRES_TYPE_FONT_IMAGE, - RRES_TYPE_FONT_CHARDATA, // CharInfo data array - RRES_TYPE_DIRECTORY -} RRESDataType; - #ifdef __cplusplus extern "C" { // Prevents name mangling of functions #endif @@ -1131,8 +1119,8 @@ RLAPI void PauseAudioStream(AudioStream stream); // Pause a RLAPI void ResumeAudioStream(AudioStream stream); // Resume audio stream RLAPI bool IsAudioStreamPlaying(AudioStream stream); // Check if audio stream is playing RLAPI void StopAudioStream(AudioStream stream); // Stop audio stream -RLAPI void SetAudioStreamVolume(AudioStream stream, float volume); // Set volume for audio stream (1.0 is max level) -RLAPI void SetAudioStreamPitch(AudioStream stream, float pitch); // Set pitch for audio stream (1.0 is base level) +RLAPI void SetAudioStreamVolume(AudioStream stream, float volume); // Set volume for audio stream (1.0 is max level) +RLAPI void SetAudioStreamPitch(AudioStream stream, float pitch); // Set pitch for audio stream (1.0 is base level) #ifdef __cplusplus } -- cgit v1.2.3 From 1320044e94126a527e8ebe0b3833cce487566925 Mon Sep 17 00:00:00 2001 From: Ray San Date: Wed, 20 Dec 2017 11:37:43 +0100 Subject: Review code formatting --- src/audio.c | 280 +++++++++++++++++++++++++++++------------------------------- 1 file changed, 135 insertions(+), 145 deletions(-) (limited to 'src/audio.c') diff --git a/src/audio.c b/src/audio.c index 7a8e185b..4855333f 100644 --- a/src/audio.c +++ b/src/audio.c @@ -227,7 +227,8 @@ 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 -typedef struct AudioBuffer { +typedef struct AudioBuffer AudioBuffer; +struct AudioBuffer { mal_dsp dsp; // For format conversion. float volume; float pitch; @@ -238,10 +239,10 @@ typedef struct AudioBuffer { bool isSubBufferProcessed[2]; unsigned int frameCursorPos; unsigned int bufferSizeInFrames; - AudioBuffer* next; - AudioBuffer* prev; + AudioBuffer *next; + AudioBuffer *prev; unsigned char buffer[1]; -} AudioBuffer; +}; void StopAudioBuffer(AudioBuffer *audioBuffer); @@ -250,48 +251,46 @@ 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 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 { + if (firstAudioBuffer == NULL) firstAudioBuffer = audioBuffer; + else + { lastAudioBuffer->next = audioBuffer; audioBuffer->prev = lastAudioBuffer; } 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; - } + 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; - } + if (audioBuffer->next == NULL) lastAudioBuffer = audioBuffer->prev; + else audioBuffer->next->prev = audioBuffer->prev; audioBuffer->prev = NULL; audioBuffer->next = NULL; } + mal_mutex_unlock(&audioLock); } -static void OnLog_MAL(mal_context* pContext, mal_device* pDevice, const char* message) +static void OnLog_MAL(mal_context *pContext, mal_device *pDevice, const char *message) { (void)pContext; (void)pDevice; @@ -303,17 +302,19 @@ static void OnLog_MAL(mal_context* pContext, mal_device* pDevice, const char* me // 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); + 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; + frameOut[iChannel] += frameIn[iChannel]*masterVolume*localVolume; } } } -static mal_uint32 OnSendAudioDataToDevice(mal_device* pDevice, mal_uint32 frameCount, void* pFramesOut) +static mal_uint32 OnSendAudioDataToDevice(mal_device *pDevice, mal_uint32 frameCount, void *pFramesOut) { // This is where all of the mixing takes place. (void)pDevice; @@ -328,27 +329,28 @@ static mal_uint32 OnSendAudioDataToDevice(mal_device* pDevice, mal_uint32 frameC for (AudioBuffer* audioBuffer = firstAudioBuffer; audioBuffer != NULL; audioBuffer = audioBuffer->next) { // Ignore stopped or paused sounds. - if (!audioBuffer->playing || audioBuffer->paused) { - continue; - } + if (!audioBuffer->playing || audioBuffer->paused) continue; mal_uint32 framesRead = 0; - for (;;) { - if (framesRead > frameCount) { + for (;;) + { + if (framesRead > frameCount) + { TraceLog(LOG_DEBUG, "Mixed too many frames from audio buffer"); break; } - if (framesRead == frameCount) { - break; - } + + if (framesRead == frameCount) break; // Just read as much data as we can from the stream. mal_uint32 framesToRead = (frameCount - framesRead); - while (framesToRead > 0) { + while (framesToRead > 0) + { float tempBuffer[1024]; // 512 frames for stereo. mal_uint32 framesToReadRightNow = framesToRead; - if (framesToReadRightNow > sizeof(tempBuffer)/sizeof(tempBuffer[0])/DEVICE_CHANNELS) { + if (framesToReadRightNow > sizeof(tempBuffer)/sizeof(tempBuffer[0])/DEVICE_CHANNELS) + { framesToReadRightNow = sizeof(tempBuffer)/sizeof(tempBuffer[0])/DEVICE_CHANNELS; } @@ -357,9 +359,10 @@ static mal_uint32 OnSendAudioDataToDevice(mal_device* pDevice, mal_uint32 frameC mal_bool32 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; + if (framesJustRead > 0) + { + float *framesOut = (float *)pFramesOut + (framesRead*device.channels); + float *framesIn = tempBuffer; MixFrames(framesOut, framesIn, framesJustRead, audioBuffer->volume); framesToRead -= framesJustRead; @@ -367,11 +370,15 @@ static mal_uint32 OnSendAudioDataToDevice(mal_device* pDevice, mal_uint32 frameC } // If we weren't able to read all the frames we requested, break. - if (framesJustRead < framesToReadRightNow) { - if (!audioBuffer->looping) { + if (framesJustRead < framesToReadRightNow) + { + if (!audioBuffer->looping) + { StopAudioBuffer(audioBuffer); break; - } else { + } + else + { // Should never get here, but just for safety, move the cursor position back to the start and continue the loop. audioBuffer->frameCursorPos = 0; continue; @@ -381,12 +388,11 @@ static mal_uint32 OnSendAudioDataToDevice(mal_device* pDevice, mal_uint32 frameC // 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; - } + if (framesToRead > 0) break; } } } + mal_mutex_unlock(&audioLock); return frameCount; // We always output the same number of frames that were originally requested. @@ -488,7 +494,8 @@ void InitAudioDevice(void) void CloseAudioDevice(void) { #if USE_MINI_AL - if (!isAudioInitialized) { + if (!isAudioInitialized) + { TraceLog(LOG_WARNING, "Could not close audio device because it is not currently initialized"); return; } @@ -551,11 +558,13 @@ void SetMasterVolume(float volume) #if USE_MINI_AL static mal_uint32 AudioBuffer_OnDSPRead(mal_dsp* pDSP, mal_uint32 frameCount, void* pFramesOut, void* pUserData) { - AudioBuffer* audioBuffer = (AudioBuffer*)pUserData; + AudioBuffer *audioBuffer = (AudioBuffer *)pUserData; - mal_uint32 subBufferSizeInFrames = audioBuffer->bufferSizeInFrames / 2; - mal_uint32 currentSubBufferIndex = audioBuffer->frameCursorPos / subBufferSizeInFrames; - if (currentSubBufferIndex > 1) { + 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; } @@ -565,7 +574,7 @@ static mal_uint32 AudioBuffer_OnDSPRead(mal_dsp* pDSP, mal_uint32 frameCount, vo 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; + 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; @@ -573,49 +582,47 @@ static mal_uint32 AudioBuffer_OnDSPRead(mal_dsp* pDSP, mal_uint32 frameCount, vo { // 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; - } + 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; - } + if (totalFramesRemaining == 0) break; mal_uint32 framesRemainingInOutputBuffer; - if (audioBuffer->usage == AUDIO_BUFFER_USAGE_STATIC) { + if (audioBuffer->usage == AUDIO_BUFFER_USAGE_STATIC) + { framesRemainingInOutputBuffer = audioBuffer->bufferSizeInFrames - audioBuffer->frameCursorPos; - } else { + } + else + { mal_uint32 firstFrameIndexOfThisSubBuffer = subBufferSizeInFrames * currentSubBufferIndex; framesRemainingInOutputBuffer = subBufferSizeInFrames - (audioBuffer->frameCursorPos - firstFrameIndexOfThisSubBuffer); } - - mal_uint32 framesToRead = totalFramesRemaining; - if (framesToRead > framesRemainingInOutputBuffer) { - framesToRead = framesRemainingInOutputBuffer; - } + if (framesToRead > framesRemainingInOutputBuffer) framesToRead = framesRemainingInOutputBuffer; - memcpy((unsigned char*)pFramesOut + (framesRead*frameSizeInBytes), audioBuffer->buffer + (audioBuffer->frameCursorPos*frameSizeInBytes), framesToRead*frameSizeInBytes); + 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) { + 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) { + if (!audioBuffer->looping) + { StopAudioBuffer(audioBuffer); break; } @@ -624,24 +631,23 @@ static mal_uint32 AudioBuffer_OnDSPRead(mal_dsp* pDSP, mal_uint32 frameCount, vo // Zero-fill excess. mal_uint32 totalFramesRemaining = (frameCount - framesRead); - if (totalFramesRemaining > 0) { + 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; - } + if (audioBuffer->usage != AUDIO_BUFFER_USAGE_STATIC) framesRead += totalFramesRemaining; } return framesRead; } // 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 *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); + AudioBuffer *audioBuffer = (AudioBuffer *)calloc(sizeof(*audioBuffer) + (bufferSizeInFrames*channels*mal_get_sample_size_in_bytes(format)), 1); if (audioBuffer == NULL) { TraceLog(LOG_ERROR, "CreateAudioBuffer() : Failed to allocate memory for audio buffer"); @@ -658,7 +664,8 @@ AudioBuffer* CreateAudioBuffer(mal_format format, mal_uint32 channels, mal_uint3 dspConfig.sampleRateIn = sampleRate; dspConfig.sampleRateOut = DEVICE_SAMPLE_RATE; mal_result resultMAL = mal_dsp_init(&dspConfig, AudioBuffer_OnDSPRead, audioBuffer, &audioBuffer->dsp); - if (resultMAL != MAL_SUCCESS) { + if (resultMAL != MAL_SUCCESS) + { TraceLog(LOG_ERROR, "LoadSoundFromWave() : Failed to create data conversion pipeline"); free(audioBuffer); return NULL; @@ -683,7 +690,7 @@ AudioBuffer* CreateAudioBuffer(mal_format format, mal_uint32 channels, mal_uint3 } // Delete an audio buffer. -void DeleteAudioBuffer(AudioBuffer* audioBuffer) +void DeleteAudioBuffer(AudioBuffer *audioBuffer) { if (audioBuffer == NULL) { @@ -696,7 +703,7 @@ void DeleteAudioBuffer(AudioBuffer* audioBuffer) } // Check if an audio buffer is playing. -bool IsAudioBufferPlaying(AudioBuffer* audioBuffer) +bool IsAudioBufferPlaying(AudioBuffer *audioBuffer) { if (audioBuffer == NULL) { @@ -711,7 +718,7 @@ bool IsAudioBufferPlaying(AudioBuffer* audioBuffer) // // This will restart the buffer from the start. Use PauseAudioBuffer() and ResumeAudioBuffer() if the playback position // should be maintained. -void PlayAudioBuffer(AudioBuffer* audioBuffer) +void PlayAudioBuffer(AudioBuffer *audioBuffer) { if (audioBuffer == NULL) { @@ -725,7 +732,7 @@ void PlayAudioBuffer(AudioBuffer* audioBuffer) } // Stop an audio buffer. -void StopAudioBuffer(AudioBuffer* audioBuffer) +void StopAudioBuffer(AudioBuffer *audioBuffer) { if (audioBuffer == NULL) { @@ -734,10 +741,7 @@ void StopAudioBuffer(AudioBuffer* audioBuffer) } // Don't do anything if the audio buffer is already stopped. - if (!IsAudioBufferPlaying(audioBuffer)) - { - return; - } + if (!IsAudioBufferPlaying(audioBuffer)) return; audioBuffer->playing = false; audioBuffer->paused = false; @@ -747,7 +751,7 @@ void StopAudioBuffer(AudioBuffer* audioBuffer) } // Pause an audio buffer. -void PauseAudioBuffer(AudioBuffer* audioBuffer) +void PauseAudioBuffer(AudioBuffer *audioBuffer) { if (audioBuffer == NULL) { @@ -759,7 +763,7 @@ void PauseAudioBuffer(AudioBuffer* audioBuffer) } // Resume an audio buffer. -void ResumeAudioBuffer(AudioBuffer* audioBuffer) +void ResumeAudioBuffer(AudioBuffer *audioBuffer) { if (audioBuffer == NULL) { @@ -771,7 +775,7 @@ void ResumeAudioBuffer(AudioBuffer* audioBuffer) } // Set volume for an audio buffer. -void SetAudioBufferVolume(AudioBuffer* audioBuffer, float volume) +void SetAudioBufferVolume(AudioBuffer *audioBuffer, float volume) { if (audioBuffer == NULL) { @@ -783,7 +787,7 @@ void SetAudioBufferVolume(AudioBuffer* audioBuffer, float volume) } // Set pitch for an audio buffer. -void SetAudioBufferPitch(AudioBuffer* audioBuffer, float pitch) +void SetAudioBufferPitch(AudioBuffer *audioBuffer, float pitch) { if (audioBuffer == NULL) { @@ -874,23 +878,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_ERROR, "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_ERROR, "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_ERROR, "LoadSoundFromWave() : Format conversion failed"); sound.audioBuffer = audioBuffer; #else @@ -965,7 +959,7 @@ void UnloadWave(Wave wave) void UnloadSound(Sound sound) { #if USE_MINI_AL - DeleteAudioBuffer((AudioBuffer*)sound.audioBuffer); + DeleteAudioBuffer((AudioBuffer *)sound.audioBuffer); #else alSourceStop(sound.source); @@ -981,7 +975,7 @@ void UnloadSound(Sound sound) void UpdateSound(Sound sound, const void *data, int samplesCount) { #if USE_MINI_AL - AudioBuffer* audioBuffer = (AudioBuffer*)sound.audioBuffer; + AudioBuffer *audioBuffer = (AudioBuffer *)sound.audioBuffer; if (audioBuffer == NULL) { TraceLog(LOG_ERROR, "UpdateSound() : Invalid sound - no audio buffer"); @@ -1021,7 +1015,7 @@ void UpdateSound(Sound sound, const void *data, int samplesCount) void PlaySound(Sound sound) { #if USE_MINI_AL - PlayAudioBuffer((AudioBuffer*)sound.audioBuffer); + PlayAudioBuffer((AudioBuffer *)sound.audioBuffer); #else alSourcePlay(sound.source); // Play the sound #endif @@ -1046,7 +1040,7 @@ void PlaySound(Sound sound) void PauseSound(Sound sound) { #if USE_MINI_AL - PauseAudioBuffer((AudioBuffer*)sound.audioBuffer); + PauseAudioBuffer((AudioBuffer *)sound.audioBuffer); #else alSourcePause(sound.source); #endif @@ -1056,7 +1050,7 @@ void PauseSound(Sound sound) void ResumeSound(Sound sound) { #if USE_MINI_AL - ResumeAudioBuffer((AudioBuffer*)sound.audioBuffer); + ResumeAudioBuffer((AudioBuffer *)sound.audioBuffer); #else ALenum state; @@ -1070,7 +1064,7 @@ void ResumeSound(Sound sound) void StopSound(Sound sound) { #if USE_MINI_AL - StopAudioBuffer((AudioBuffer*)sound.audioBuffer); + StopAudioBuffer((AudioBuffer *)sound.audioBuffer); #else alSourceStop(sound.source); #endif @@ -1080,7 +1074,7 @@ void StopSound(Sound sound) bool IsSoundPlaying(Sound sound) { #if USE_MINI_AL - return IsAudioBufferPlaying((AudioBuffer*)sound.audioBuffer); + return IsAudioBufferPlaying((AudioBuffer *)sound.audioBuffer); #else bool playing = false; ALint state; @@ -1096,7 +1090,7 @@ bool IsSoundPlaying(Sound sound) void SetSoundVolume(Sound sound, float volume) { #if USE_MINI_AL - SetAudioBufferVolume((AudioBuffer*)sound.audioBuffer, volume); + SetAudioBufferVolume((AudioBuffer *)sound.audioBuffer, volume); #else alSourcef(sound.source, AL_GAIN, volume); #endif @@ -1106,7 +1100,7 @@ void SetSoundVolume(Sound sound, float volume) void SetSoundPitch(Sound sound, float pitch) { #if USE_MINI_AL - SetAudioBufferPitch((AudioBuffer*)sound.audioBuffer, pitch); + SetAudioBufferPitch((AudioBuffer *)sound.audioBuffer, pitch); #else alSourcef(sound.source, AL_PITCH, pitch); #endif @@ -1121,15 +1115,17 @@ void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels) 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, formatOut, channels, sampleRate, NULL, formatIn, wave->channels, wave->sampleRate, frameCountIn); - if (frameCount == 0) { + if (frameCount == 0) + { TraceLog(LOG_ERROR, "WaveFormat() : Failed to get frame count for format conversion."); return; } - void* data = malloc(frameCount * channels * (sampleSize/8)); + void *data = malloc(frameCount*channels*(sampleSize/8)); frameCount = mal_convert_frames(data, formatOut, channels, sampleRate, wave->data, formatIn, wave->channels, wave->sampleRate, frameCountIn); - if (frameCount == 0) { + if (frameCount == 0) + { TraceLog(LOG_ERROR, "WaveFormat() : Format conversion failed."); return; } @@ -1404,7 +1400,7 @@ void UnloadMusicStream(Music music) void PlayMusicStream(Music music) { #if USE_MINI_AL - AudioBuffer* audioBuffer = (AudioBuffer*)music->stream.audioBuffer; + AudioBuffer *audioBuffer = (AudioBuffer *)music->stream.audioBuffer; if (audioBuffer == NULL) { TraceLog(LOG_ERROR, "PlayMusicStream() : No audio buffer"); @@ -1416,9 +1412,9 @@ void PlayMusicStream(Music music) // // just make sure to play again on window restore // if (IsMusicPlaying(music)) PlayMusicStream(music); mal_uint32 frameCursorPos = audioBuffer->frameCursorPos; - { - PlayAudioStream(music->stream); // <-- This resets the cursor position. - } + + PlayAudioStream(music->stream); // <-- This resets the cursor position. + audioBuffer->frameCursorPos = frameCursorPos; #else alSourcePlay(music->stream.source); @@ -1502,7 +1498,7 @@ void UpdateMusicStream(Music music) #if USE_MINI_AL bool streamEnding = false; - unsigned int subBufferSizeInFrames = ((AudioBuffer*)music->stream.audioBuffer)->bufferSizeInFrames / 2; + unsigned int subBufferSizeInFrames = ((AudioBuffer *)music->stream.audioBuffer)->bufferSizeInFrames/2; // NOTE: Using dynamic allocation because it could require more than 16KB void *pcm = calloc(subBufferSizeInFrames*music->stream.sampleSize/8*music->stream.channels, 1); @@ -1566,10 +1562,7 @@ void UpdateMusicStream(Music music) } else { - if (music->loopCount == -1) - { - PlayMusicStream(music); - } + if (music->loopCount == -1) PlayMusicStream(music); } } else @@ -1756,11 +1749,9 @@ 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 = device.bufferSizeInFrames / device.periods; unsigned int subBufferSize = AUDIO_BUFFER_SIZE; - if (subBufferSize < periodSize) { - subBufferSize = periodSize; - } + if (subBufferSize < periodSize) subBufferSize = periodSize; - AudioBuffer* audioBuffer = CreateAudioBuffer(formatIn, stream.channels, stream.sampleRate, subBufferSize*2, AUDIO_BUFFER_USAGE_STREAM); + AudioBuffer *audioBuffer = CreateAudioBuffer(formatIn, stream.channels, stream.sampleRate, subBufferSize*2, AUDIO_BUFFER_USAGE_STREAM); if (audioBuffer == NULL) { TraceLog(LOG_ERROR, "InitAudioStream() : Failed to create audio buffer"); @@ -1825,7 +1816,7 @@ AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, un void CloseAudioStream(AudioStream stream) { #if USE_MINI_AL - DeleteAudioBuffer((AudioBuffer*)stream.audioBuffer); + DeleteAudioBuffer((AudioBuffer *)stream.audioBuffer); #else // Stop playing channel alSourceStop(stream.source); @@ -1879,23 +1870,22 @@ void UpdateAudioStream(AudioStream stream, const void *data, int samplesCount) } mal_uint32 subBufferSizeInFrames = audioBuffer->bufferSizeInFrames/2; - unsigned char *subBuffer = audioBuffer->buffer + ((subBufferSizeInFrames * stream.channels * (stream.sampleSize/8)) * subBufferToUpdate); + unsigned char *subBuffer = audioBuffer->buffer + ((subBufferSizeInFrames*stream.channels*(stream.sampleSize/8))*subBufferToUpdate); // 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 >= (mal_uint32)samplesCount) { mal_uint32 framesToWrite = subBufferSizeInFrames; - if (framesToWrite > (mal_uint32)samplesCount) { - framesToWrite = (mal_uint32)samplesCount; - } + if (framesToWrite > (mal_uint32)samplesCount) framesToWrite = (mal_uint32)samplesCount; - mal_uint32 bytesToWrite = framesToWrite * stream.channels * (stream.sampleSize/8); + mal_uint32 bytesToWrite = framesToWrite*stream.channels*(stream.sampleSize/8); memcpy(subBuffer, data, bytesToWrite); // Any leftover frames should be filled with zeros. mal_uint32 leftoverFrameCount = subBufferSizeInFrames - framesToWrite; - if (leftoverFrameCount > 0) { - memset(subBuffer + bytesToWrite, 0, leftoverFrameCount * stream.channels * (stream.sampleSize/8)); + if (leftoverFrameCount > 0) + { + memset(subBuffer + bytesToWrite, 0, leftoverFrameCount*stream.channels*(stream.sampleSize/8)); } audioBuffer->isSubBufferProcessed[subBufferToUpdate] = false; @@ -1929,7 +1919,7 @@ void UpdateAudioStream(AudioStream stream, const void *data, int samplesCount) bool IsAudioBufferProcessed(AudioStream stream) { #if USE_MINI_AL - AudioBuffer* audioBuffer = (AudioBuffer*)stream.audioBuffer; + AudioBuffer *audioBuffer = (AudioBuffer *)stream.audioBuffer; if (audioBuffer == NULL) { TraceLog(LOG_ERROR, "IsAudioBufferProcessed() : No audio buffer"); @@ -1951,7 +1941,7 @@ bool IsAudioBufferProcessed(AudioStream stream) void PlayAudioStream(AudioStream stream) { #if USE_MINI_AL - PlayAudioBuffer((AudioBuffer*)stream.audioBuffer); + PlayAudioBuffer((AudioBuffer *)stream.audioBuffer); #else alSourcePlay(stream.source); #endif @@ -1961,7 +1951,7 @@ void PlayAudioStream(AudioStream stream) void PauseAudioStream(AudioStream stream) { #if USE_MINI_AL - PauseAudioBuffer((AudioBuffer*)stream.audioBuffer); + PauseAudioBuffer((AudioBuffer *)stream.audioBuffer); #else alSourcePause(stream.source); #endif @@ -1971,7 +1961,7 @@ void PauseAudioStream(AudioStream stream) void ResumeAudioStream(AudioStream stream) { #if USE_MINI_AL - ResumeAudioBuffer((AudioBuffer*)stream.audioBuffer); + ResumeAudioBuffer((AudioBuffer *)stream.audioBuffer); #else ALenum state; alGetSourcei(stream.source, AL_SOURCE_STATE, &state); @@ -1984,7 +1974,7 @@ void ResumeAudioStream(AudioStream stream) bool IsAudioStreamPlaying(AudioStream stream) { #if USE_MINI_AL - return IsAudioBufferPlaying((AudioBuffer*)stream.audioBuffer); + return IsAudioBufferPlaying((AudioBuffer *)stream.audioBuffer); #else bool playing = false; ALint state; @@ -2001,7 +1991,7 @@ bool IsAudioStreamPlaying(AudioStream stream) void StopAudioStream(AudioStream stream) { #if USE_MINI_AL - StopAudioBuffer((AudioBuffer*)stream.audioBuffer); + StopAudioBuffer((AudioBuffer *)stream.audioBuffer); #else alSourceStop(stream.source); #endif @@ -2010,7 +2000,7 @@ void StopAudioStream(AudioStream stream) void SetAudioStreamVolume(AudioStream stream, float volume) { #if USE_MINI_AL - SetAudioBufferVolume((AudioBuffer*)stream.audioBuffer, volume); + SetAudioBufferVolume((AudioBuffer *)stream.audioBuffer, volume); #else alSourcef(stream.source, AL_GAIN, volume); #endif @@ -2019,7 +2009,7 @@ void SetAudioStreamVolume(AudioStream stream, float volume) void SetAudioStreamPitch(AudioStream stream, float pitch) { #if USE_MINI_AL - SetAudioBufferPitch((AudioBuffer*)stream.audioBuffer, pitch); + SetAudioBufferPitch((AudioBuffer *)stream.audioBuffer, pitch); #else alSourcef(stream.source, AL_PITCH, pitch); #endif -- cgit v1.2.3 From 61afd07bd7b3a96c6f0f460b668f52cf1a8bd90f Mon Sep 17 00:00:00 2001 From: Ray San Date: Wed, 20 Dec 2017 12:34:18 +0100 Subject: Force OpenAL backend on some platforms OpenAL audio backend is being forced on HTML5 and OSX --- src/Makefile | 27 ++++++++++++++++++++++++--- src/audio.c | 29 +++++++++++++++++------------ src/audio.h | 19 ++++++++++++------- 3 files changed, 53 insertions(+), 22 deletions(-) (limited to 'src/audio.c') diff --git a/src/Makefile b/src/Makefile index 00f5fa2f..1d1aa75c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -47,12 +47,20 @@ API_VERSION = 1 PLATFORM ?= PLATFORM_DESKTOP RAYLIB_PATH = .. +# Library type used for raylib: STATIC (.a) or SHARED (.so/.dll) +RAYLIB_LIBTYPE ?= STATIC + # Included raylib audio module on compilation # NOTE: Some programs like tools could not require audio support INCLUDE_AUDIO_MODULE ?= YES -# Library type used for raylib: STATIC (.a) or SHARED (.so/.dll) -RAYLIB_LIBTYPE ?= STATIC +# Force OpenAL Soft backend for audio +FORCE_OPENAL_BACKEND ?= FALSE + +# OpenAL Soft audio backend forced on HTML5 and OSX (see below) +ifeq ($(PLATFORM),PLATFORM_WEB) + FORCE_OPENAL_BACKEND = TRUE +endif # Use cross-compiler for PLATFORM_RPI ifeq ($(PLATFORM),PLATFORM_RPI) @@ -95,6 +103,13 @@ ifeq ($(PLATFORM),PLATFORM_RPI) endif endif +# Force OpenAL Soft audio backend for OSX platform +# NOTE 1: mini_al library does not support CoreAudio yet +# NOTE 2: Required OpenAL libraries should be available on OSX +ifeq ($(PLATFORM_OS),OSX) + FORCE_OPENAL_BACKEND = TRUE +endif + ifeq ($(PLATFORM),PLATFORM_WEB) # Emscripten required variables EMSDK_PATH = C:/emsdk @@ -269,6 +284,10 @@ ifeq ($(RAYLIB_LIBTYPE),SHARED) CFLAGS += -fPIC -DBUILD_LIBTYPE_SHARED endif +ifeq ($(FORCE_OPENAL_BACKEND),TRUE) + CFLAGS += -DFORCE_OPENAL_BACKEND +endif + # Define include paths for required headers # NOTE: Several external required libraries (stb and others) INCLUDE_PATHS = -I. -Iexternal -Iexternal/glfw/include @@ -329,8 +348,10 @@ endif ifeq ($(INCLUDE_AUDIO_MODULE),YES) OBJS += audio.o - OBJS += mini_al.o OBJS += stb_vorbis.o +ifeq ($(FORCE_OPENAL_BACKEND),FALSE) + OBJS += mini_al.o +endif endif # Default target entry diff --git a/src/audio.c b/src/audio.c index 4855333f..b8ca60fd 100644 --- a/src/audio.c +++ b/src/audio.c @@ -16,6 +16,9 @@ * Define to use the module as standalone library (independently of raylib). * Required types and functions are defined in the same module. * +* #define FORCE_OPENAL_BACKEND +* Force OpenAL Soft audio backend usage +* * #define SUPPORT_FILEFORMAT_WAV * #define SUPPORT_FILEFORMAT_OGG * #define SUPPORT_FILEFORMAT_XM @@ -24,19 +27,24 @@ * Selected desired fileformats to be supported for loading. Some of those formats are * supported by default, to remove support, just comment unrequired #define in this module * -* LIMITATIONS: +* LIMITATIONS (only OpenAL Soft): * Only up to two channels supported: MONO and STEREO (for additional channels, use AL_EXT_MCFORMATS) * Only the following sample sizes supported: 8bit PCM, 16bit PCM, 32-bit float PCM (using AL_EXT_FLOAT32) * * DEPENDENCIES: -* OpenAL Soft - Audio device management (http://kcat.strangesoft.net/openal.html) +* mini_al - Audio device/context management (https://github.com/dr-soft/mini_al) * stb_vorbis - OGG audio files loading (http://www.nothings.org/stb_vorbis/) * jar_xm - XM module file loading * jar_mod - MOD audio file loading * dr_flac - FLAC audio file loading * +* *OpenAL Soft - Audio device management, still used on HTML5 and OSX platforms +* * CONTRIBUTORS: -* Joshua Reisenauer (github: @kd7tck): +* David Reid (github: @mackron) (Nov. 2017): +* - Complete port to mini_al library +* +* Joshua Reisenauer (github: @kd7tck) (2015) * - XM audio module support (jar_xm) * - MOD audio module support (jar_mod) * - Mixing channels support @@ -45,7 +53,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2014-2017 Ramon Santamaria (@raysan5) +* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. @@ -72,8 +80,8 @@ #define SUPPORT_FILEFORMAT_MOD //------------------------------------------------- -#ifndef USE_MINI_AL -#define USE_MINI_AL 1 // Set to 1 to use mini_al; 0 to use OpenAL. +#if !defined(FORCE_OPENAL_BACKEND) + #define USE_MINI_AL 1 // Set to 1 to use mini_al; 0 to use OpenAL. #endif #if defined(AUDIO_STANDALONE) @@ -86,7 +94,7 @@ #include "external/mini_al.h" // Implemented in mini_al.c. Cannot implement this here because it conflicts with Win32 APIs such as CloseWindow(), etc. -#if !defined(USE_MINI_AL) || USE_MINI_AL == 0 +#if !defined(USE_MINI_AL) || (USE_MINI_AL == 0) #if defined(__APPLE__) #include "OpenAL/al.h" // OpenAL basic header #include "OpenAL/alc.h" // OpenAL context header (like OpenGL, OpenAL requires a context to work) @@ -480,11 +488,8 @@ void InitAudioDevice(void) alListenerf(AL_GAIN, 1.0f); - if (alIsExtensionPresent("AL_EXT_float32")) { - TraceLog(LOG_INFO, "AL_EXT_float32 supported"); - } else { - TraceLog(LOG_INFO, "AL_EXT_float32 not supported"); - } + if (alIsExtensionPresent("AL_EXT_float32")) TraceLog(LOG_INFO, "[EXTENSION] AL_EXT_float32 supported"); + else TraceLog(LOG_INFO, "[EXTENSION] AL_EXT_float32 not supported"); } } #endif diff --git a/src/audio.h b/src/audio.h index 4c9faf25..01c93741 100644 --- a/src/audio.h +++ b/src/audio.h @@ -10,19 +10,24 @@ * - Manage mixing channels * - Manage raw audio context * -* LIMITATIONS: +* LIMITATIONS (only OpenAL Soft): * Only up to two channels supported: MONO and STEREO (for additional channels, use AL_EXT_MCFORMATS) * Only the following sample sizes supported: 8bit PCM, 16bit PCM, 32-bit float PCM (using AL_EXT_FLOAT32) * * DEPENDENCIES: -* OpenAL Soft - Audio device management (http://kcat.strangesoft.net/openal.html) +* mini_al - Audio device/context management (https://github.com/dr-soft/mini_al) * stb_vorbis - OGG audio files loading (http://www.nothings.org/stb_vorbis/) -* jar_xm - XM module file loading (#define SUPPORT_FILEFORMAT_XM) -* jar_mod - MOD audio file loading (#define SUPPORT_FILEFORMAT_MOD) -* dr_flac - FLAC audio file loading (#define SUPPORT_FILEFORMAT_FLAC) +* jar_xm - XM module file loading +* jar_mod - MOD audio file loading +* dr_flac - FLAC audio file loading +* +* *OpenAL Soft - Audio device management, still used on HTML5 and OSX platforms * * CONTRIBUTORS: -* Joshua Reisenauer (github: @kd7tck): +* David Reid (github: @mackron) (Nov. 2017): +* - Complete port to mini_al library +* +* Joshua Reisenauer (github: @kd7tck) (2015) * - XM audio module support (jar_xm) * - MOD audio module support (jar_mod) * - Mixing channels support @@ -31,7 +36,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2014-2017 Ramon Santamaria (@raysan5) +* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. -- cgit v1.2.3 From c93bca8c272af83ae752afb46db2b54d85dca454 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Thu, 28 Dec 2017 17:58:09 +0100 Subject: Review Makefile config flags Support external GLFW usage Renamed some flags for consistency --- examples/Makefile | 6 ++++++ src/Makefile | 38 +++++++++++++++++++++++--------------- src/audio.c | 6 +++--- 3 files changed, 32 insertions(+), 18 deletions(-) (limited to 'src/audio.c') diff --git a/examples/Makefile b/examples/Makefile index fe3ff205..c9081b2e 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -33,6 +33,9 @@ ifeq ($(PLATFORM),PLATFORM_RPI) RAYLIB_PATH ?= /home/pi/raylib endif +# Use external GLFW library instead of rglfw module +USE_EXTERNAL_GLFW ?= FALSE + # Library type used for raylib: STATIC (.a) or SHARED (.so/.dll) RAYLIB_LIBTYPE ?= STATIC @@ -235,6 +238,9 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP) # On XWindow requires also below libraries LDLIBS += -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor endif + ifeq ($(USE_EXTERNAL_GLFW),TRUE) + LDLIBS += -lglfw + endif endif ifeq ($(PLATFORM),PLATFORM_RPI) # Libraries for Raspberry Pi compiling diff --git a/src/Makefile b/src/Makefile index 1d1aa75c..de9a639e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -52,21 +52,24 @@ RAYLIB_LIBTYPE ?= STATIC # Included raylib audio module on compilation # NOTE: Some programs like tools could not require audio support -INCLUDE_AUDIO_MODULE ?= YES +INCLUDE_AUDIO_MODULE ?= TRUE # Force OpenAL Soft backend for audio -FORCE_OPENAL_BACKEND ?= FALSE +USE_OPENAL_BACKEND ?= FALSE + +# Use external GLFW library instead of rglfw module +USE_EXTERNAL_GLFW ?= FALSE # OpenAL Soft audio backend forced on HTML5 and OSX (see below) ifeq ($(PLATFORM),PLATFORM_WEB) - FORCE_OPENAL_BACKEND = TRUE + USE_OPENAL_BACKEND = TRUE endif # Use cross-compiler for PLATFORM_RPI ifeq ($(PLATFORM),PLATFORM_RPI) - RPI_CROSS_COMPILE ?= NO + USE_RPI_CROSS_COMPILER ?= FALSE - ifeq ($(RPI_CROSS_COMPILE),YES) + ifeq ($(USE_RPI_CROSS_COMPILER),TRUE) RPI_TOOLCHAIN ?= C:/SysGCC/Raspberry RPI_TOOLCHAIN_SYSROOT ?= $(RPI_TOOLCHAIN)/arm-linux-gnueabihf/sysroot endif @@ -107,7 +110,7 @@ endif # NOTE 1: mini_al library does not support CoreAudio yet # NOTE 2: Required OpenAL libraries should be available on OSX ifeq ($(PLATFORM_OS),OSX) - FORCE_OPENAL_BACKEND = TRUE + USE_OPENAL_BACKEND = TRUE endif ifeq ($(PLATFORM),PLATFORM_WEB) @@ -201,7 +204,7 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP) endif endif ifeq ($(PLATFORM),PLATFORM_RPI) - ifeq ($(RPI_CROSS_COMPILE),YES) + ifeq ($(USE_RPI_CROSS_COMPILER),TRUE) # Define RPI cross-compiler #CC = armv6j-hardfloat-linux-gnueabi-gcc CC = $(RPI_TOOLCHAIN)/bin/arm-linux-gnueabihf-gcc @@ -226,7 +229,7 @@ endif AR = ar ifeq ($(PLATFORM),PLATFORM_RPI) - ifeq ($(RPI_CROSS_COMPILE),YES) + ifeq ($(USE_RPI_CROSS_COMPILER),TRUE) # Define RPI cross-archiver #CC = armv6j-hardfloat-linux-gnueabi-gcc AR = $(RPI_TOOLCHAIN)/bin/arm-linux-gnueabihf-ar @@ -284,8 +287,8 @@ ifeq ($(RAYLIB_LIBTYPE),SHARED) CFLAGS += -fPIC -DBUILD_LIBTYPE_SHARED endif -ifeq ($(FORCE_OPENAL_BACKEND),TRUE) - CFLAGS += -DFORCE_OPENAL_BACKEND +ifeq ($(USE_OPENAL_BACKEND),TRUE) + CFLAGS += -DUSE_OPENAL_BACKEND endif # Define include paths for required headers @@ -297,6 +300,9 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP) INCLUDE_PATHS += -I/usr/local/include LDFLAGS += -L. -Lsrc -L/usr/local/lib -L$(RAYLIB_RELEASE_PATH) endif + ifeq ($(USE_EXTERNAL_GLFW),TRUE) + LDFLAGS += -lglfw + endif endif # Define additional directories containing required header files @@ -343,15 +349,17 @@ OBJS = core.o \ utils.o ifeq ($(PLATFORM),PLATFORM_DESKTOP) - OBJS += rglfw.o + ifeq ($(USE_EXTERNAL_GLFW),FALSE) + OBJS += rglfw.o + endif endif -ifeq ($(INCLUDE_AUDIO_MODULE),YES) +ifeq ($(INCLUDE_AUDIO_MODULE),TRUE) OBJS += audio.o OBJS += stb_vorbis.o -ifeq ($(FORCE_OPENAL_BACKEND),FALSE) - OBJS += mini_al.o -endif + ifeq ($(USE_OPENAL_BACKEND),FALSE) + OBJS += mini_al.o + endif endif # Default target entry diff --git a/src/audio.c b/src/audio.c index b8ca60fd..17b8ea22 100644 --- a/src/audio.c +++ b/src/audio.c @@ -16,8 +16,8 @@ * Define to use the module as standalone library (independently of raylib). * Required types and functions are defined in the same module. * -* #define FORCE_OPENAL_BACKEND -* Force OpenAL Soft audio backend usage +* #define USE_OPENAL_BACKEND +* Use OpenAL Soft audio backend usage * * #define SUPPORT_FILEFORMAT_WAV * #define SUPPORT_FILEFORMAT_OGG @@ -80,7 +80,7 @@ #define SUPPORT_FILEFORMAT_MOD //------------------------------------------------- -#if !defined(FORCE_OPENAL_BACKEND) +#if !defined(USE_OPENAL_BACKEND) #define USE_MINI_AL 1 // Set to 1 to use mini_al; 0 to use OpenAL. #endif -- cgit v1.2.3 From 230e78a23e3482aaa3e16f56ade3c940712d1272 Mon Sep 17 00:00:00 2001 From: - <-> Date: Mon, 15 Jan 2018 13:54:25 +0100 Subject: Code tweak while using OpenAL backend --- src/audio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/audio.c') diff --git a/src/audio.c b/src/audio.c index 17b8ea22..052d4d3c 100644 --- a/src/audio.c +++ b/src/audio.c @@ -1114,6 +1114,7 @@ void SetSoundPitch(Sound sound, float pitch) // Convert wave data to desired format void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels) { +#if USE_MINI_AL mal_format formatIn = ((wave->sampleSize == 8) ? mal_format_u8 : ((wave->sampleSize == 16) ? mal_format_s16 : mal_format_f32)); mal_format formatOut = (( sampleSize == 8) ? mal_format_u8 : (( sampleSize == 16) ? mal_format_s16 : mal_format_f32)); @@ -1142,7 +1143,7 @@ void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels) free(wave->data); wave->data = data; -#if 0 +#else // Format sample rate // NOTE: Only supported 22050 <--> 44100 if (wave->sampleRate != sampleRate) -- cgit v1.2.3 From 7bf6becc94ee18f782e6ef176745bc8d50b19944 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 11 Feb 2018 01:12:16 +0100 Subject: Reviewed mini_al implementation - Some functions renamed - Comments reviewed - Functions reorganized --- src/audio.c | 383 ++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 207 insertions(+), 176 deletions(-) (limited to 'src/audio.c') 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"); -- cgit v1.2.3 From 231a69417ab5a9627fc9972392e7146ddea07106 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 11 Feb 2018 01:28:30 +0100 Subject: Corrected masteVolume setting --- src/audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/audio.c') diff --git a/src/audio.c b/src/audio.c index 55b43bea..baa5256f 100644 --- a/src/audio.c +++ b/src/audio.c @@ -633,7 +633,7 @@ void SetMasterVolume(float volume) else if (volume > 1.0f) volume = 1.0f; #if USE_MINI_AL - masterVolume = 1; + masterVolume = volume; #else alListenerf(AL_GAIN, volume); #endif -- cgit v1.2.3 From 03ca9508bfdf594e7f8cbbdb9312d533549b6bde Mon Sep 17 00:00:00 2001 From: "maficccc@gmail.com" Date: Fri, 16 Mar 2018 18:17:58 +0100 Subject: Fix Dead initialization --- src/audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/audio.c') diff --git a/src/audio.c b/src/audio.c index baa5256f..1fcf6f91 100644 --- a/src/audio.c +++ b/src/audio.c @@ -1553,7 +1553,7 @@ void UpdateMusicStream(Music music) case MUSIC_AUDIO_OGG: { // NOTE: Returns the number of samples to process (be careful! we ask for number of shorts!) - int numSamplesOgg = stb_vorbis_get_samples_short_interleaved(music->ctxOgg, music->stream.channels, (short *)pcm, samplesCount*music->stream.channels); + stb_vorbis_get_samples_short_interleaved(music->ctxOgg, music->stream.channels, (short *)pcm, samplesCount*music->stream.channels); } break; #if defined(SUPPORT_FILEFORMAT_FLAC) -- cgit v1.2.3 From 1841afad11892bab16976b976d69b7757b617c8b Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Sat, 7 Apr 2018 22:29:53 +0200 Subject: Refactor all #define SUPPORT_* into a config.h That way, a user needs only to touch a single file to configure what features raylib is built with. Include guards are left out intentionally, because config.h should only be included in source files, not headers. Later on, config.h can also define the raylib version (#461). --- src/audio.c | 12 +++------- src/config.h | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/core.c | 12 ++-------- src/models.c | 7 +----- src/rlgl.c | 6 +---- src/rlgl.h | 4 ++-- src/shapes.c | 8 +------ src/text.c | 9 ++----- src/textures.c | 12 +--------- src/utils.c | 2 +- src/utils.h | 6 +++-- 11 files changed, 92 insertions(+), 60 deletions(-) create mode 100644 src/config.h (limited to 'src/audio.c') diff --git a/src/audio.c b/src/audio.c index 1fcf6f91..3ee1fe81 100644 --- a/src/audio.c +++ b/src/audio.c @@ -11,7 +11,7 @@ * - Manage raw audio context * * CONFIGURATION: -* +* * #define AUDIO_STANDALONE * Define to use the module as standalone library (independently of raylib). * Required types and functions are defined in the same module. @@ -24,7 +24,7 @@ * #define SUPPORT_FILEFORMAT_XM * #define SUPPORT_FILEFORMAT_MOD * #define SUPPORT_FILEFORMAT_FLAC -* Selected desired fileformats to be supported for loading. Some of those formats are +* Selected desired fileformats to be supported for loading. Some of those formats are * supported by default, to remove support, just comment unrequired #define in this module * * LIMITATIONS (only OpenAL Soft): @@ -72,13 +72,7 @@ * **********************************************************************************************/ -// Default configuration flags (supported features) -//------------------------------------------------- -#define SUPPORT_FILEFORMAT_WAV -#define SUPPORT_FILEFORMAT_OGG -#define SUPPORT_FILEFORMAT_XM -#define SUPPORT_FILEFORMAT_MOD -//------------------------------------------------- +#include "config.h" #if !defined(USE_OPENAL_BACKEND) #define USE_MINI_AL 1 // Set to 1 to use mini_al; 0 to use OpenAL. diff --git a/src/config.h b/src/config.h new file mode 100644 index 00000000..40b9d7c4 --- /dev/null +++ b/src/config.h @@ -0,0 +1,74 @@ +/* Edit to control what features raylib is compiled with. */ + +// text.c +/* Default font is loaded on window initialization to be available for the user to render simple text. NOTE: If enabled, uses external module functions to load default raylib font (module: text) */ +#define SUPPORT_DEFAULT_FONT 1 +/* Selected desired fileformats to be supported for loading. */ +#define SUPPORT_FILEFORMAT_FNT 1 +#define SUPPORT_FILEFORMAT_TTF 1 + +// textures.c +/* Selecte desired fileformats to be supported for image data loading. */ +#define SUPPORT_FILEFORMAT_PNG 1 +#define SUPPORT_FILEFORMAT_DDS 1 +#define SUPPORT_FILEFORMAT_HDR 1 +#define SUPPORT_FILEFORMAT_KTX 1 +#define SUPPORT_FILEFORMAT_ASTC 1 +/* #undef SUPPORT_FILEFORMAT_BMP */ +/* #undef SUPPORT_FILEFORMAT_TGA */ +/* #undef SUPPORT_FILEFORMAT_JPG */ +/* #undef SUPPORT_FILEFORMAT_GIF */ +/* #undef SUPPORT_FILEFORMAT_PSD */ +/* #undef SUPPORT_FILEFORMAT_PKM */ +/* #undef SUPPORT_FILEFORMAT_PVR */ + +/* Support multiple image editing functions to scale, adjust colors, flip, draw on images, crop... If not defined only three image editing functions supported: ImageFormat(), ImageAlphaMask(), ImageToPOT() */ +#define SUPPORT_IMAGE_MANIPULATION 1 + +/* Support proedural image generation functionality (gradient, spot, perlin-noise, cellular) */ +#define SUPPORT_IMAGE_GENERATION 1 + +// rlgl.c +/* Support VR simulation functionality (stereo rendering) */ +#define SUPPORT_VR_SIMULATOR 1 +/* Include stereo rendering distortion shader (shader_distortion.h) */ +#define SUPPORT_DISTORTION_SHADER 1 + +// core.c +/* Camera module is included (camera.h) and multiple predefined cameras are available: free, 1st/3rd person, orbital */ +#define SUPPORT_CAMERA_SYSTEM 1 +/* Gestures module is included (gestures.h) to support gestures detection: tap, hold, swipe, drag */ +#define SUPPORT_GESTURES_SYSTEM 1 +/* Mouse gestures are directly mapped like touches and processed by gestures system. */ +#define SUPPORT_MOUSE_GESTURES 1 +/* Use busy wait loop for timing sync, if not defined, a high-resolution timer is setup and used */ +#define SUPPORT_BUSY_WAIT_LOOP 1 +/* Allow automatic gif recording of current screen pressing CTRL+F12, defined in KeyCallback() */ +#define SUPPORT_GIF_RECORDING 1 + +// audio.c +/* Desired fileformats to be supported for loading. */ +#define SUPPORT_FILEFORMAT_WAV 1 +#define SUPPORT_FILEFORMAT_OGG 1 +#define SUPPORT_FILEFORMAT_XM 1 +#define SUPPORT_FILEFORMAT_MOD 1 +/* #undef SUPPORT_FILEFORMAT_FLAC */ + +// models.c +/* Selected desired fileformats to be supported for loading. */ +#define SUPPORT_FILEFORMAT_OBJ 1 +#define SUPPORT_FILEFORMAT_MTL 1 + +/* Support procedural mesh generation functions, uses external par_shapes.h library + * NOTE: Some generated meshes DO NOT include generated texture coordinates + */ +#define SUPPORT_MESH_GENERATION 1 + +// utils.c +/* Show TraceLog() output messages. NOTE: By default LOG_DEBUG traces not shown */ +#define SUPPORT_TRACELOG 1 + +/* Support saving image data as PNG fileformat. NOTE: Requires stb_image_write library */ +#define SUPPORT_SAVE_PNG 1 +/* Support saving image data as PMP fileformat. NOTE: Requires stb_image_write library */ +/* #undef SUPPORT_SAVE_BMP */ diff --git a/src/core.c b/src/core.c index e10494c1..0265afd0 100644 --- a/src/core.c +++ b/src/core.c @@ -48,7 +48,7 @@ * Mouse gestures are directly mapped like touches and processed by gestures system. * * #define SUPPORT_BUSY_WAIT_LOOP -* Use busy wait loop for timming sync, if not defined, a high-resolution timer is setup and used +* Use busy wait loop for timing sync, if not defined, a high-resolution timer is setup and used * * #define SUPPORT_GIF_RECORDING * Allow automatic gif recording of current screen pressing CTRL+F12, defined in KeyCallback() @@ -81,15 +81,7 @@ * **********************************************************************************************/ -// Default configuration flags (supported features) -//------------------------------------------------- -#define SUPPORT_DEFAULT_FONT -#define SUPPORT_MOUSE_GESTURES -#define SUPPORT_CAMERA_SYSTEM -#define SUPPORT_GESTURES_SYSTEM -#define SUPPORT_BUSY_WAIT_LOOP -#define SUPPORT_GIF_RECORDING -//------------------------------------------------- +#include "config.h" #include "raylib.h" diff --git a/src/models.c b/src/models.c index ae1fc968..0486d17c 100644 --- a/src/models.c +++ b/src/models.c @@ -36,12 +36,7 @@ * **********************************************************************************************/ -// Default configuration flags (supported features) -//------------------------------------------------- -#define SUPPORT_FILEFORMAT_OBJ -#define SUPPORT_FILEFORMAT_MTL -#define SUPPORT_MESH_GENERATION -//------------------------------------------------- +#include "config.h" #include "raylib.h" diff --git a/src/rlgl.c b/src/rlgl.c index 118823db..68bd3670 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -54,11 +54,7 @@ * **********************************************************************************************/ -// Default configuration flags (supported features) -//------------------------------------------------- -#define SUPPORT_VR_SIMULATOR -#define SUPPORT_DISTORTION_SHADER -//------------------------------------------------- +#include "config.h" #include "rlgl.h" diff --git a/src/rlgl.h b/src/rlgl.h index 01278699..c071acac 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -24,7 +24,7 @@ * #define RLGL_STANDALONE * Use rlgl as standalone library (no raylib dependency) * -* #define SUPPORT_VR_SIMULATION / SUPPORT_STEREO_RENDERING +* #define SUPPORT_VR_SIMULATOR * Support VR simulation functionality (stereo rendering) * * #define SUPPORT_DISTORTION_SHADER @@ -496,4 +496,4 @@ void TraceLog(int msgType, const char *text, ...); // Show trace log messag } #endif -#endif // RLGL_H \ No newline at end of file +#endif // RLGL_H diff --git a/src/shapes.c b/src/shapes.c index 693463ff..a1bc7098 100644 --- a/src/shapes.c +++ b/src/shapes.c @@ -4,12 +4,6 @@ * * CONFIGURATION: * -* #define SUPPORT_QUADS_ONLY -* Draw shapes using only QUADS, vertex are accumulated in QUADS arrays (like textures) -* -* #define SUPPORT_TRIANGLES_ONLY -* Draw shapes using only TRIANGLES, vertex are accumulated in TRIANGLES arrays -* * #define USE_DEFAULT_FONT_TEXTURE * Draw rectangle shapes using font texture white character instead of default white texture * Allows drawing rectangles and text with a single draw call, very useful for GUI systems! @@ -36,7 +30,7 @@ * **********************************************************************************************/ -#define USE_DEFAULT_FONT_TEXTURE +#include "config.h" #include "raylib.h" diff --git a/src/text.c b/src/text.c index d053be30..1a9d386a 100644 --- a/src/text.c +++ b/src/text.c @@ -6,7 +6,7 @@ * * #define SUPPORT_FILEFORMAT_FNT * #define SUPPORT_FILEFORMAT_TTF -* Selected desired fileformats to be supported for loading. Some of those formats are +* Selected desired fileformats to be supported for loading. Some of those formats are * supported by default, to remove support, just comment unrequired #define in this module * * #define SUPPORT_DEFAULT_FONT @@ -36,12 +36,7 @@ * **********************************************************************************************/ -// Default supported features -//------------------------------------- -#define SUPPORT_DEFAULT_FONT -#define SUPPORT_FILEFORMAT_FNT -#define SUPPORT_FILEFORMAT_TTF -//------------------------------------- +#include "config.h" #include "raylib.h" diff --git a/src/textures.c b/src/textures.c index 8a562887..43453f73 100644 --- a/src/textures.c +++ b/src/textures.c @@ -52,17 +52,7 @@ * 3. This notice may not be removed or altered from any source distribution. * **********************************************************************************************/ - -// Default configuration flags (supported features) -//------------------------------------------------- -#define SUPPORT_FILEFORMAT_PNG -#define SUPPORT_FILEFORMAT_DDS -#define SUPPORT_FILEFORMAT_HDR -#define SUPPORT_FILEFORMAT_KTX -#define SUPPORT_FILEFORMAT_ASTC -#define SUPPORT_IMAGE_MANIPULATION -#define SUPPORT_IMAGE_GENERATION -//------------------------------------------------- +#include "config.h" #include "raylib.h" diff --git a/src/utils.c b/src/utils.c index e37b4ff7..9d9d8b55 100644 --- a/src/utils.c +++ b/src/utils.c @@ -41,7 +41,7 @@ * **********************************************************************************************/ -#define SUPPORT_TRACELOG // Output tracelog messages +#include "config.h" #include "raylib.h" // WARNING: Required for: LogType enum #include "utils.h" diff --git a/src/utils.h b/src/utils.h index f4a1a01a..ed75eb68 100644 --- a/src/utils.h +++ b/src/utils.h @@ -32,7 +32,9 @@ #include // Required for: AAssetManager #endif -#define SUPPORT_SAVE_PNG +#ifndef SUPPORT_SAVE_PNG +#define SUPPORT_SAVE_PNG 1 +#endif //---------------------------------------------------------------------------------- // Some basic Defines @@ -74,4 +76,4 @@ FILE *android_fopen(const char *fileName, const char *mode); // Replacement f } #endif -#endif // UTILS_H \ No newline at end of file +#endif // UTILS_H -- cgit v1.2.3