diff options
author | RSDuck <RSDuck@users.noreply.github.com> | 2023-05-01 02:30:00 +0200 |
---|---|---|
committer | RSDuck <RSDuck@users.noreply.github.com> | 2023-05-01 02:30:26 +0200 |
commit | 81c284b7cff2dd1b110ce1954d5ec02576720160 (patch) | |
tree | ded0617209bd9d46ba30aa08ca24a95d8c02c9ff /src/frontend/qt_sdl/main.cpp | |
parent | 38b0d21c22cb246ebaa1f099fc0d3cd4261fa983 (diff) |
refactor frontend audio functionality
Diffstat (limited to 'src/frontend/qt_sdl/main.cpp')
-rw-r--r-- | src/frontend/qt_sdl/main.cpp | 345 |
1 files changed, 16 insertions, 329 deletions
diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 9200538..b0f1538 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -72,6 +72,7 @@ #include "RAMInfoDialog.h" #include "TitleManagerDialog.h" #include "PowerManagement/PowerManagementDialog.h" +#include "AudioInOut.h" #include "types.h" #include "version.h" @@ -162,19 +163,6 @@ int videoRenderer; GPU::RenderSettings videoSettings; bool videoSettingsDirty; -SDL_AudioDeviceID audioDevice; -int audioFreq; -bool audioMuted; -SDL_cond* audioSync; -SDL_mutex* audioSyncLock; - -SDL_AudioDeviceID micDevice; -s16 micExtBuffer[2048]; -u32 micExtBufferWritePos; - -u32 micWavLength; -s16* micWavBuffer; - CameraManager* camManager[2]; bool camStarted[2]; @@ -187,227 +175,6 @@ const struct { int id; float ratio; const char* label; } aspectRatios[] = { 3, 0, "window" } }; -void micCallback(void* data, Uint8* stream, int len); - - - -void audioCallback(void* data, Uint8* stream, int len) -{ - len /= (sizeof(s16) * 2); - - // resample incoming audio to match the output sample rate - - int len_in = Frontend::AudioOut_GetNumSamples(len); - s16 buf_in[1024*2]; - int num_in; - - SDL_LockMutex(audioSyncLock); - num_in = SPU::ReadOutput(buf_in, len_in); - SDL_CondSignal(audioSync); - SDL_UnlockMutex(audioSyncLock); - - if ((num_in < 1) || audioMuted) - { - memset(stream, 0, len*sizeof(s16)*2); - return; - } - - int margin = 6; - if (num_in < len_in-margin) - { - int last = num_in-1; - - for (int i = num_in; i < len_in-margin; i++) - ((u32*)buf_in)[i] = ((u32*)buf_in)[last]; - - num_in = len_in-margin; - } - - Frontend::AudioOut_Resample(buf_in, num_in, (s16*)stream, len, Config::AudioVolume); -} - -void audioMute() -{ - int inst = Platform::InstanceID(); - audioMuted = false; - - switch (Config::MPAudioMode) - { - case 1: // only instance 1 - if (inst > 0) audioMuted = true; - break; - - case 2: // only currently focused instance - if (mainWindow != nullptr) - audioMuted = !mainWindow->isActiveWindow(); - break; - } -} - - -void micOpen() -{ - if (Config::MicInputType != 1) - { - micDevice = 0; - return; - } - - SDL_AudioSpec whatIwant, whatIget; - memset(&whatIwant, 0, sizeof(SDL_AudioSpec)); - whatIwant.freq = 44100; - whatIwant.format = AUDIO_S16LSB; - whatIwant.channels = 1; - whatIwant.samples = 1024; - whatIwant.callback = micCallback; - micDevice = SDL_OpenAudioDevice(NULL, 1, &whatIwant, &whatIget, 0); - if (!micDevice) - { - printf("Mic init failed: %s\n", SDL_GetError()); - } - else - { - SDL_PauseAudioDevice(micDevice, 0); - } -} - -void micClose() -{ - if (micDevice) - SDL_CloseAudioDevice(micDevice); - - micDevice = 0; -} - -void micLoadWav(const std::string& name) -{ - SDL_AudioSpec format; - memset(&format, 0, sizeof(SDL_AudioSpec)); - - if (micWavBuffer) delete[] micWavBuffer; - micWavBuffer = nullptr; - micWavLength = 0; - - u8* buf; - u32 len; - if (!SDL_LoadWAV(name.c_str(), &format, &buf, &len)) - return; - - const u64 dstfreq = 44100; - - int srcinc = format.channels; - len /= ((SDL_AUDIO_BITSIZE(format.format) / 8) * srcinc); - - micWavLength = (len * dstfreq) / format.freq; - if (micWavLength < 735) micWavLength = 735; - micWavBuffer = new s16[micWavLength]; - - float res_incr = len / (float)micWavLength; - float res_timer = 0; - int res_pos = 0; - - for (int i = 0; i < micWavLength; i++) - { - u16 val = 0; - - switch (SDL_AUDIO_BITSIZE(format.format)) - { - case 8: - val = buf[res_pos] << 8; - break; - - case 16: - if (SDL_AUDIO_ISBIGENDIAN(format.format)) - val = (buf[res_pos*2] << 8) | buf[res_pos*2 + 1]; - else - val = (buf[res_pos*2 + 1] << 8) | buf[res_pos*2]; - break; - - case 32: - if (SDL_AUDIO_ISFLOAT(format.format)) - { - u32 rawval; - if (SDL_AUDIO_ISBIGENDIAN(format.format)) - rawval = (buf[res_pos*4] << 24) | (buf[res_pos*4 + 1] << 16) | (buf[res_pos*4 + 2] << 8) | buf[res_pos*4 + 3]; - else - rawval = (buf[res_pos*4 + 3] << 24) | (buf[res_pos*4 + 2] << 16) | (buf[res_pos*4 + 1] << 8) | buf[res_pos*4]; - - float fval = *(float*)&rawval; - s32 ival = (s32)(fval * 0x8000); - ival = std::clamp(ival, -0x8000, 0x7FFF); - val = (s16)ival; - } - else if (SDL_AUDIO_ISBIGENDIAN(format.format)) - val = (buf[res_pos*4] << 8) | buf[res_pos*4 + 1]; - else - val = (buf[res_pos*4 + 3] << 8) | buf[res_pos*4 + 2]; - break; - } - - if (SDL_AUDIO_ISUNSIGNED(format.format)) - val ^= 0x8000; - - micWavBuffer[i] = val; - - res_timer += res_incr; - while (res_timer >= 1.0) - { - res_timer -= 1.0; - res_pos += srcinc; - } - } - - SDL_FreeWAV(buf); -} - -void micCallback(void* data, Uint8* stream, int len) -{ - s16* input = (s16*)stream; - len /= sizeof(s16); - - int maxlen = sizeof(micExtBuffer) / sizeof(s16); - - if ((micExtBufferWritePos + len) > maxlen) - { - u32 len1 = maxlen - micExtBufferWritePos; - memcpy(&micExtBuffer[micExtBufferWritePos], &input[0], len1*sizeof(s16)); - memcpy(&micExtBuffer[0], &input[len1], (len - len1)*sizeof(s16)); - micExtBufferWritePos = len - len1; - } - else - { - memcpy(&micExtBuffer[micExtBufferWritePos], input, len*sizeof(s16)); - micExtBufferWritePos += len; - } -} - -void micProcess() -{ - int type = Config::MicInputType; - bool cmd = Input::HotkeyDown(HK_Mic); - - if (type != 1 && !cmd) - { - type = 0; - } - - switch (type) - { - case 0: // no mic - Frontend::Mic_FeedSilence(); - break; - - case 1: // host mic - case 3: // WAV - Frontend::Mic_FeedExternalBuffer(); - break; - - case 2: // white noise - Frontend::Mic_FeedNoise(); - break; - } -} - EmuThread::EmuThread(QObject* parent) : QThread(parent) { @@ -703,7 +470,7 @@ void EmuThread::run() } // microphone input - micProcess(); + AudioInOut::MicProcess(); // auto screen layout if (Config::ScreenSizing == screenSizing_Auto) @@ -789,16 +556,8 @@ void EmuThread::run() Config::AudioVolume = volumeLevel * (256.0 / 31.0); } - if (Config::AudioSync && !fastforward && audioDevice) - { - SDL_LockMutex(audioSyncLock); - while (SPU::GetOutputSize() > 1024) - { - int ret = SDL_CondWaitTimeout(audioSync, audioSyncLock, 500); - if (ret == SDL_MUTEX_TIMEDOUT) break; - } - SDL_UnlockMutex(audioSyncLock); - } + if (Config::AudioSync && !fastforward) + AudioInOut::AudioSync(); double frametimeStep = nlines / (60.0 * 263.0); @@ -907,8 +666,7 @@ void EmuThread::emuRun() // checkme emit windowEmuStart(); - if (audioDevice) SDL_PauseAudioDevice(audioDevice, 0); - micOpen(); + AudioInOut::Enable(); } void EmuThread::initContext() @@ -932,8 +690,7 @@ void EmuThread::emuPause() EmuRunning = 2; while (EmuStatus != 2); - if (audioDevice) SDL_PauseAudioDevice(audioDevice, 1); - micClose(); + AudioInOut::Disable(); } void EmuThread::emuUnpause() @@ -945,8 +702,7 @@ void EmuThread::emuUnpause() EmuRunning = PrevEmuStatus; - if (audioDevice) SDL_PauseAudioDevice(audioDevice, 0); - micOpen(); + AudioInOut::Enable(); } void EmuThread::emuStop() @@ -954,8 +710,7 @@ void EmuThread::emuStop() EmuRunning = 0; EmuPause = 0; - if (audioDevice) SDL_PauseAudioDevice(audioDevice, 1); - micClose(); + AudioInOut::Disable(); } void EmuThread::emuFrameStep() @@ -2270,12 +2025,12 @@ void MainWindow::dropEvent(QDropEvent* event) void MainWindow::focusInEvent(QFocusEvent* event) { - audioMute(); + AudioInOut::AudioMute(mainWindow); } void MainWindow::focusOutEvent(QFocusEvent* event) { - audioMute(); + AudioInOut::AudioMute(mainWindow); } void MainWindow::onAppStateChanged(Qt::ApplicationState state) @@ -3158,27 +2913,7 @@ void MainWindow::onUpdateAudioSettings() void MainWindow::onAudioSettingsFinished(int res) { - micClose(); - - SPU::SetInterpolation(Config::AudioInterp); - - if (Config::MicInputType == 3) - { - micLoadWav(Config::MicWavPath); - Frontend::Mic_SetExternalBuffer(micWavBuffer, micWavLength); - } - else - { - delete[] micWavBuffer; - micWavBuffer = nullptr; - - if (Config::MicInputType == 1) - Frontend::Mic_SetExternalBuffer(micExtBuffer, sizeof(micExtBuffer)/sizeof(s16)); - else - Frontend::Mic_SetExternalBuffer(NULL, 0); - } - - micOpen(); + AudioInOut::UpdateSettings(); } void MainWindow::onOpenMPSettings() @@ -3191,7 +2926,7 @@ void MainWindow::onOpenMPSettings() void MainWindow::onMPSettingsFinished(int res) { - audioMute(); + AudioInOut::AudioMute(mainWindow); LocalMP::SetRecvTimeout(Config::MPRecvTimeout); emuThread->emuUnpause(); @@ -3542,7 +3277,7 @@ int main(int argc, char** argv) SANITIZE(Config::GL_ScaleFactor, 1, 16); SANITIZE(Config::AudioInterp, 0, 3); SANITIZE(Config::AudioVolume, 0, 256); - SANITIZE(Config::MicInputType, 0, 3); + SANITIZE(Config::MicInputType, 0, (int)micInputType_MAX); SANITIZE(Config::ScreenRotation, 0, 3); SANITIZE(Config::ScreenGap, 0, 500); SANITIZE(Config::ScreenLayout, 0, 3); @@ -3551,36 +3286,7 @@ int main(int argc, char** argv) SANITIZE(Config::ScreenAspectBot, 0, 4); #undef SANITIZE - audioMuted = false; - audioSync = SDL_CreateCond(); - audioSyncLock = SDL_CreateMutex(); - - audioFreq = 48000; // TODO: make configurable? - SDL_AudioSpec whatIwant, whatIget; - memset(&whatIwant, 0, sizeof(SDL_AudioSpec)); - whatIwant.freq = audioFreq; - whatIwant.format = AUDIO_S16LSB; - whatIwant.channels = 2; - whatIwant.samples = 1024; - whatIwant.callback = audioCallback; - audioDevice = SDL_OpenAudioDevice(NULL, 0, &whatIwant, &whatIget, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE); - if (!audioDevice) - { - printf("Audio init failed: %s\n", SDL_GetError()); - } - else - { - audioFreq = whatIget.freq; - printf("Audio output frequency: %d Hz\n", audioFreq); - SDL_PauseAudioDevice(audioDevice, 1); - } - - micDevice = 0; - - memset(micExtBuffer, 0, sizeof(micExtBuffer)); - micExtBufferWritePos = 0; - micWavBuffer = nullptr; - + AudioInOut::Init(); camStarted[0] = false; camStarted[1] = false; camManager[0] = new CameraManager(0, 640, 480, true); @@ -3590,18 +3296,6 @@ int main(int argc, char** argv) ROMManager::EnableCheats(Config::EnableCheats != 0); - Frontend::Init_Audio(audioFreq); - - if (Config::MicInputType == 1) - { - Frontend::Mic_SetExternalBuffer(micExtBuffer, sizeof(micExtBuffer)/sizeof(s16)); - } - else if (Config::MicInputType == 3) - { - micLoadWav(Config::MicWavPath); - Frontend::Mic_SetExternalBuffer(micWavBuffer, micWavLength); - } - Input::JoystickID = Config::JoystickID; Input::OpenJoystick(); @@ -3613,7 +3307,7 @@ int main(int argc, char** argv) emuThread->start(); emuThread->emuPause(); - audioMute(); + AudioInOut::AudioMute(mainWindow); QObject::connect(&melon, &QApplication::applicationStateChanged, mainWindow, &MainWindow::onAppStateChanged); @@ -3646,14 +3340,7 @@ int main(int argc, char** argv) Input::CloseJoystick(); - if (audioDevice) SDL_CloseAudioDevice(audioDevice); - micClose(); - - SDL_DestroyCond(audioSync); - SDL_DestroyMutex(audioSyncLock); - - if (micWavBuffer) delete[] micWavBuffer; - + AudioInOut::DeInit(); delete camManager[0]; delete camManager[1]; |