diff --git a/CMakeLists.txt b/CMakeLists.txt index 678d8e372..d61daca41 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,8 @@ cmake_minimum_required(VERSION 3.5) project(raylib) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + # Avoid excessive expansion of variables in conditionals. In particular, if # "PLATFORM" is "DRM" then: # diff --git a/currentBuffer b/currentBuffer deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/audio/audio_mixed_processor.c b/examples/audio/audio_mixed_processor.c index df46edc4e..eb440af5b 100644 --- a/examples/audio/audio_mixed_processor.c +++ b/examples/audio/audio_mixed_processor.c @@ -55,7 +55,8 @@ int main(void) InitWindow(screenWidth, screenHeight, "raylib [audio] example - processing mixed output"); - InitAudioDevice(); // Initialize audio device + InitAudioContext(); + InitAudioDevice(0); // Initialize audio device AttachAudioMixedProcessor(ProcessAudio); diff --git a/examples/audio/audio_module_playing.c b/examples/audio/audio_module_playing.c index 6234f0e55..22cf44d36 100644 --- a/examples/audio/audio_module_playing.c +++ b/examples/audio/audio_module_playing.c @@ -37,7 +37,8 @@ int main(void) InitWindow(screenWidth, screenHeight, "raylib [audio] example - module playing (streaming)"); - InitAudioDevice(); // Initialize audio device + InitAudioContext(); + InitAudioDevice(0); // Initialize audio device Color colors[14] = { ORANGE, RED, GOLD, LIME, BLUE, VIOLET, BROWN, LIGHTGRAY, PINK, YELLOW, GREEN, SKYBLUE, PURPLE, BEIGE }; diff --git a/examples/audio/audio_music_stream.c b/examples/audio/audio_music_stream.c index bdf141edf..014be995c 100644 --- a/examples/audio/audio_music_stream.c +++ b/examples/audio/audio_music_stream.c @@ -12,6 +12,11 @@ ********************************************************************************************/ #include "raylib.h" +#include + +void AudioDevicesQuery(int index, char* deviceName, bool isDefault) { + printf("index: %d / deviceName: %s / isDefault: %d\n", index, deviceName, isDefault); +} //------------------------------------------------------------------------------------ // Program main entry point @@ -25,7 +30,11 @@ int main(void) InitWindow(screenWidth, screenHeight, "raylib [audio] example - music playing (streaming)"); - InitAudioDevice(); // Initialize audio device + InitAudioContext(); + + QueryAudioDevices(AudioDevicesQuery); + + InitAudioDevice(0); // Initialize audio device Music music = LoadMusicStream("resources/country.mp3"); @@ -90,6 +99,7 @@ int main(void) UnloadMusicStream(music); // Unload music stream buffers from RAM CloseAudioDevice(); // Close audio device (music streaming is automatically stopped) + CloseAudioDevice(); CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- diff --git a/examples/audio/audio_raw_stream.c b/examples/audio/audio_raw_stream.c index 0b7954293..6bcf4af88 100644 --- a/examples/audio/audio_raw_stream.c +++ b/examples/audio/audio_raw_stream.c @@ -62,7 +62,8 @@ int main(void) InitWindow(screenWidth, screenHeight, "raylib [audio] example - raw audio streaming"); - InitAudioDevice(); // Initialize audio device + InitAudioContext(); + InitAudioDevice(0); // Initialize audio device SetAudioStreamBufferSizeDefault(MAX_SAMPLES_PER_UPDATE); diff --git a/examples/audio/audio_sound_loading.c b/examples/audio/audio_sound_loading.c index 41aa2160e..7b621c1b9 100644 --- a/examples/audio/audio_sound_loading.c +++ b/examples/audio/audio_sound_loading.c @@ -25,7 +25,8 @@ int main(void) InitWindow(screenWidth, screenHeight, "raylib [audio] example - sound loading and playing"); - InitAudioDevice(); // Initialize audio device + InitAudioContext(); + InitAudioDevice(0); // Initialize audio device Sound fxWav = LoadSound("resources/sound.wav"); // Load WAV audio file Sound fxOgg = LoadSound("resources/target.ogg"); // Load OGG audio file diff --git a/examples/audio/audio_sound_multi.c b/examples/audio/audio_sound_multi.c index d5472efab..54c9574d5 100644 --- a/examples/audio/audio_sound_multi.c +++ b/examples/audio/audio_sound_multi.c @@ -29,7 +29,8 @@ int main(void) InitWindow(screenWidth, screenHeight, "raylib [audio] example - playing sound multiple times"); - InitAudioDevice(); // Initialize audio device + InitAudioContext(); + InitAudioDevice(0); // Initialize audio device // load the sound list soundArray[0] = LoadSound("resources/sound.wav"); // Load WAV audio file into the first slot as the 'source' sound diff --git a/examples/audio/audio_stream_effects.c b/examples/audio/audio_stream_effects.c index cc8273abc..64ecc2072 100644 --- a/examples/audio/audio_stream_effects.c +++ b/examples/audio/audio_stream_effects.c @@ -39,7 +39,8 @@ int main(void) InitWindow(screenWidth, screenHeight, "raylib [audio] example - stream effects"); - InitAudioDevice(); // Initialize audio device + InitAudioContext(); + InitAudioDevice(0); // Initialize audio device Music music = LoadMusicStream("resources/country.mp3"); diff --git a/examples/others/embedded_files_loading.c b/examples/others/embedded_files_loading.c index e46fe102f..ffb106099 100644 --- a/examples/others/embedded_files_loading.c +++ b/examples/others/embedded_files_loading.c @@ -30,7 +30,8 @@ int main(void) InitWindow(screenWidth, screenHeight, "raylib [others] example - embedded files loading"); - InitAudioDevice(); // Initialize audio device + InitAudioContext(); + InitAudioDevice(0); // Initialize audio device // Loaded in CPU memory (RAM) from header file (audio_data.h) // Same as: Wave wave = LoadWave("sound.wav"); diff --git a/examples/textures/textures_sprite_button.c b/examples/textures/textures_sprite_button.c index 5d0153b57..3bdbde817 100644 --- a/examples/textures/textures_sprite_button.c +++ b/examples/textures/textures_sprite_button.c @@ -27,7 +27,8 @@ int main(void) InitWindow(screenWidth, screenHeight, "raylib [textures] example - sprite button"); - InitAudioDevice(); // Initialize audio device + InitAudioContext(); + InitAudioDevice(0); // Initialize audio device Sound fxButton = LoadSound("resources/buttonfx.wav"); // Load button sound Texture2D button = LoadTexture("resources/button.png"); // Load button texture diff --git a/examples/textures/textures_sprite_explosion.c b/examples/textures/textures_sprite_explosion.c index a65426cb6..69ad381cc 100644 --- a/examples/textures/textures_sprite_explosion.c +++ b/examples/textures/textures_sprite_explosion.c @@ -28,7 +28,8 @@ int main(void) InitWindow(screenWidth, screenHeight, "raylib [textures] example - sprite explosion"); - InitAudioDevice(); + InitAudioContext(); + InitAudioDevice(0); // Load explosion sound Sound fxBoom = LoadSound("resources/boom.wav"); diff --git a/src/raudio.c b/src/raudio.c index 15859a661..d326cef4f 100644 --- a/src/raudio.c +++ b/src/raudio.c @@ -381,6 +381,7 @@ typedef struct AudioData { ma_context context; // miniaudio context data ma_device device; // miniaudio device ma_mutex lock; // miniaudio mutex lock + bool isCtxReady; bool isReady; // Check if audio device is ready size_t pcmBufferSize; // Pre-allocated buffer size void *pcmBuffer; // Pre-allocated buffer to read audio data from file/memory @@ -455,8 +456,9 @@ void UntrackAudioBuffer(AudioBuffer *buffer); //---------------------------------------------------------------------------------- // Module Functions Definition - Audio Device initialization and Closing //---------------------------------------------------------------------------------- + // Initialize audio device -void InitAudioDevice(void) +void InitAudioContext(void) { // Init audio context ma_context_config ctxConfig = ma_context_config_init(); @@ -469,10 +471,67 @@ void InitAudioDevice(void) return; } + AUDIO.System.isCtxReady = true; +} + +void QueryAudioDevices(void(*callback)(int, char*, bool)) { + ma_device_info* pPlaybackInfos; + ma_uint32 playbackCount; + ma_device_info* pCaptureInfos; + ma_uint32 captureCount; + + if (ma_context_get_devices(&AUDIO.System.context, &pPlaybackInfos, &playbackCount, &pCaptureInfos, &captureCount) != MA_SUCCESS) + { + TRACELOG(LOG_WARNING, "AUDIO: Failed to query playback devices"); + return; + } + + for (ma_uint32 i = 0; i < playbackCount; i += 1) { + callback(i, pPlaybackInfos[i].name, pPlaybackInfos[i].isDefault); + } +} + +// Initialize audio device +void InitAudioDevice(char* deviceName) +{ + if (!AUDIO.System.isCtxReady) { + TRACELOG(LOG_WARNING, "AUDIO: Failed to initialize playback device because context is not ready yet"); + return; + } + + ma_device_info* pPlaybackInfos; + ma_uint32 playbackCount; + ma_device_info* pCaptureInfos; + ma_uint32 captureCount; + ma_device_id* pDeviceId = NULL; + + if (deviceName == NULL) + { + TRACELOG(LOG_WARNING, "AUDIO: No playback device provided, falling back to default"); + } + else + { + if (ma_context_get_devices(&AUDIO.System.context, &pPlaybackInfos, &playbackCount, &pCaptureInfos, &captureCount) != MA_SUCCESS) + { + TRACELOG(LOG_WARNING, "AUDIO: Failed to query playback devices, falling back to default"); + } + else + { + for (ma_uint32 i = 0; i < playbackCount; i += 1) + { + if (strcmp(deviceName, pPlaybackInfos[i].name) == 0) + { + pDeviceId = &pPlaybackInfos[i].id; + break; + } + } + } + } + // Init audio device // 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 = pDeviceId; // 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 @@ -482,7 +541,7 @@ void InitAudioDevice(void) config.dataCallback = OnSendAudioDataToDevice; config.pUserData = NULL; - result = ma_device_init(&AUDIO.System.context, &config, &AUDIO.System.device); + ma_result result = ma_device_init(&AUDIO.System.context, &config, &AUDIO.System.device); if (result != MA_SUCCESS) { TRACELOG(LOG_WARNING, "AUDIO: Failed to initialize playback device"); @@ -528,7 +587,6 @@ void CloseAudioDevice(void) { ma_mutex_uninit(&AUDIO.System.lock); ma_device_uninit(&AUDIO.System.device); - ma_context_uninit(&AUDIO.System.context); AUDIO.System.isReady = false; RL_FREE(AUDIO.System.pcmBuffer); @@ -540,6 +598,17 @@ void CloseAudioDevice(void) else TRACELOG(LOG_WARNING, "AUDIO: Device could not be closed, not currently initialized"); } +void CloseAudioContext(void) { + if (AUDIO.System.isCtxReady) + { + ma_context_uninit(&AUDIO.System.context); + AUDIO.System.isCtxReady = false; + + TRACELOG(LOG_INFO, "AUDIO: Context closed successfully"); + } + else TRACELOG(LOG_WARNING, "AUDIO: Context could not be closed, not currently initialized"); +} + // Check if device has been initialized successfully bool IsAudioDeviceReady(void) { diff --git a/src/raylib.h b/src/raylib.h index a26b8ce6b..68e7edd59 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1624,7 +1624,9 @@ RLAPI RayCollision GetRayCollisionQuad(Ray ray, Vector3 p1, Vector3 p2, Vector3 typedef void (*AudioCallback)(void *bufferData, unsigned int frames); // Audio device management functions -RLAPI void InitAudioDevice(void); // Initialize audio device and context +RLAPI void InitAudioContext(void); +RLAPI void QueryAudioDevices(void(*callback)(int, char*, bool)); +RLAPI void InitAudioDevice(char* deviceName); // Initialize audio device RLAPI void CloseAudioDevice(void); // Close the audio device and context RLAPI bool IsAudioDeviceReady(void); // Check if audio device has been initialized successfully RLAPI void SetMasterVolume(float volume); // Set master volume (listener)