#include "sdl_audio_stream.h" #include "common/assert.h" #include "common/log.h" #include "sdl_initializer.h" #include Log_SetChannel(SDLAudioStream); SDLAudioStream::SDLAudioStream() = default; SDLAudioStream::~SDLAudioStream() { if (IsOpen()) SDLAudioStream::CloseDevice(); } std::unique_ptr SDLAudioStream::Create() { return std::make_unique(); } bool SDLAudioStream::OpenDevice() { DebugAssert(!IsOpen()); FrontendCommon::EnsureSDLInitialized(); if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { Log_ErrorPrintf("SDL_InitSubSystem(SDL_INIT_AUDIO) failed"); return false; } SDL_AudioSpec spec = {}; spec.freq = m_output_sample_rate; spec.channels = static_cast(m_channels); spec.format = AUDIO_S16; spec.samples = static_cast(m_buffer_size); spec.callback = AudioCallback; spec.userdata = static_cast(this); SDL_AudioSpec obtained_spec = {}; #ifdef SDL_AUDIO_ALLOW_SAMPLES_CHANGE const u32 allowed_change_flags = SDL_AUDIO_ALLOW_SAMPLES_CHANGE; #else const u32 allowed_change_flags = 0; #endif m_device_id = SDL_OpenAudioDevice(nullptr, 0, &spec, &obtained_spec, allowed_change_flags); if (m_device_id == 0) { Log_ErrorPrintf("SDL_OpenAudioDevice() failed: %s", SDL_GetError()); SDL_QuitSubSystem(SDL_INIT_AUDIO); return false; } if (obtained_spec.samples > spec.samples) { Log_WarningPrintf("Requested buffer size %u, got buffer size %u. Adjusting to compensate.", spec.samples, obtained_spec.samples); if (!SetBufferSize(obtained_spec.samples)) { Log_ErrorPrintf("Failed to set new buffer size of %u", obtained_spec.samples); CloseDevice(); return false; } } return true; } void SDLAudioStream::PauseDevice(bool paused) { SDL_PauseAudioDevice(m_device_id, paused ? 1 : 0); } void SDLAudioStream::CloseDevice() { SDL_CloseAudioDevice(m_device_id); SDL_QuitSubSystem(SDL_INIT_AUDIO); m_device_id = 0; } void SDLAudioStream::AudioCallback(void* userdata, uint8_t* stream, int len) { SDLAudioStream* const this_ptr = static_cast(userdata); const u32 num_frames = len / sizeof(SampleType) / this_ptr->m_channels; this_ptr->ReadFrames(reinterpret_cast(stream), num_frames, false); } void SDLAudioStream::FramesAvailable() {}