#include "audio.h" #include #ifndef _WIN32 #define AUDIO_FREQUENCY 96000 #include #else #include /* Windows (well, at least my VM) can't handle 96KHz sound well :( */ /* felsqualle says: For SDL 2.0.6+ using the WASAPI driver, the highest freq. we can get is 48000. 96000 also works, but always has some faint crackling in the audio, no matter how high or low I set the buffer length... Not quite satisfied with that solution, because acc. to SDL2 docs, 96k + WASAPI *should* work. */ #define AUDIO_FREQUENCY 48000 #endif /* Compatibility with older SDL versions */ #ifndef SDL_AUDIO_ALLOW_SAMPLES_CHANGE #define SDL_AUDIO_ALLOW_SAMPLES_CHANGE 0 #endif static SDL_AudioDeviceID device_id; static SDL_AudioSpec want_aspec, have_aspec; #define AUDIO_BUFFER_SIZE 512 static unsigned buffer_pos = 0; static GB_sample_t audio_buffer[AUDIO_BUFFER_SIZE]; static bool _audio_is_playing(void) { return SDL_GetAudioDeviceStatus(device_id) == SDL_AUDIO_PLAYING; } static void _audio_clear_queue(void) { SDL_ClearQueuedAudio(device_id); } static void _audio_set_paused(bool paused) { _audio_clear_queue(); SDL_PauseAudioDevice(device_id, paused); } static unsigned _audio_get_frequency(void) { return have_aspec.freq; } static size_t _audio_get_queue_length(void) { return SDL_GetQueuedAudioSize(device_id); } static void _audio_queue_sample(GB_sample_t *sample) { audio_buffer[buffer_pos++] = *sample; if (buffer_pos == AUDIO_BUFFER_SIZE) { buffer_pos = 0; SDL_QueueAudio(device_id, (const void *)audio_buffer, sizeof(audio_buffer)); } } static bool _audio_init(void) { /* Configure Audio */ memset(&want_aspec, 0, sizeof(want_aspec)); want_aspec.freq = AUDIO_FREQUENCY; want_aspec.format = AUDIO_S16SYS; want_aspec.channels = 2; want_aspec.samples = 512; SDL_version _sdl_version; SDL_GetVersion(&_sdl_version); unsigned sdl_version = _sdl_version.major * 1000 + _sdl_version.minor * 100 + _sdl_version.patch; #ifndef _WIN32 /* SDL 2.0.5 on macOS and Linux introduced a bug where certain combinations of buffer lengths and frequencies fail to produce audio correctly. */ if (sdl_version >= 2005) { want_aspec.samples = 2048; } #else if (sdl_version < 2006) { /* Since WASAPI audio was introduced in SDL 2.0.6, we have to lower the audio frequency to 44100 because otherwise we would get garbled audio output.*/ want_aspec.freq = 44100; } #endif device_id = SDL_OpenAudioDevice(0, 0, &want_aspec, &have_aspec, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE | SDL_AUDIO_ALLOW_SAMPLES_CHANGE); return true; } GB_AUDIO_DRIVER(SDL);