diff --git a/src/frontend/qt_sdl/AudioInOut.cpp b/src/frontend/qt_sdl/AudioInOut.cpp new file mode 100644 index 00000000..b7461e51 --- /dev/null +++ b/src/frontend/qt_sdl/AudioInOut.cpp @@ -0,0 +1,354 @@ +#include "AudioInOut.h" + +#include + +#include "FrontendUtil.h" +#include "Config.h" +#include "SPU.h" +#include "Platform.h" +#include "Input.h" +#include "main.h" + +namespace AudioInOut +{ + +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; + +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 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 AudioMute(QMainWindow* mainWindow) +{ + 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 != micInputType_External) + { + 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) + { + Platform::Log(Platform::LogLevel::Error, "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 MicProcess() +{ + int type = Config::MicInputType; + bool cmd = Input::HotkeyDown(HK_Mic); + + if (type != micInputType_External && !cmd) + { + type = micInputType_Silence; + } + + switch (type) + { + case micInputType_Silence: // no mic + Frontend::Mic_FeedSilence(); + break; + + case micInputType_External: // host mic + case micInputType_Wav: // WAV + Frontend::Mic_FeedExternalBuffer(); + break; + + case micInputType_Noise: // blowing noise + Frontend::Mic_FeedNoise(); + break; + } +} + +void SetupMicInputData() +{ + if (micWavBuffer != nullptr) + { + delete[] micWavBuffer; + micWavBuffer = nullptr; + micWavLength = 0; + } + + switch (Config::MicInputType) + { + case micInputType_Silence: + case micInputType_Noise: + Frontend::Mic_SetExternalBuffer(NULL, 0); + break; + case micInputType_External: + Frontend::Mic_SetExternalBuffer(micExtBuffer, sizeof(micExtBuffer)/sizeof(s16)); + break; + case micInputType_Wav: + MicLoadWav(Config::MicWavPath); + Frontend::Mic_SetExternalBuffer(micWavBuffer, micWavLength); + break; + } +} + +void Init() +{ + 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) + { + Platform::Log(Platform::LogLevel::Error, "Audio init failed: %s\n", SDL_GetError()); + } + else + { + audioFreq = whatIget.freq; + Platform::Log(Platform::LogLevel::Info, "Audio output frequency: %d Hz\n", audioFreq); + SDL_PauseAudioDevice(audioDevice, 1); + } + + micDevice = 0; + + memset(micExtBuffer, 0, sizeof(micExtBuffer)); + micExtBufferWritePos = 0; + micWavBuffer = nullptr; + + Frontend::Init_Audio(audioFreq); + + SetupMicInputData(); +} + +void DeInit() +{ + if (audioDevice) SDL_CloseAudioDevice(audioDevice); + MicClose(); + + SDL_DestroyCond(audioSync); + SDL_DestroyMutex(audioSyncLock); + + if (micWavBuffer) delete[] micWavBuffer; +} + +void AudioSync() +{ + if (audioDevice) + { + SDL_LockMutex(audioSyncLock); + while (SPU::GetOutputSize() > 1024) + { + int ret = SDL_CondWaitTimeout(audioSync, audioSyncLock, 500); + if (ret == SDL_MUTEX_TIMEDOUT) break; + } + SDL_UnlockMutex(audioSyncLock); + } +} + +void UpdateSettings() +{ + MicClose(); + + SPU::SetInterpolation(Config::AudioInterp); + SetupMicInputData(); + + MicOpen(); +} + +void Enable() +{ + if (audioDevice) SDL_PauseAudioDevice(audioDevice, 0); + MicOpen(); +} + +void Disable() +{ + if (audioDevice) SDL_PauseAudioDevice(audioDevice, 1); + MicClose(); +} + +} \ No newline at end of file diff --git a/src/frontend/qt_sdl/AudioInOut.h b/src/frontend/qt_sdl/AudioInOut.h new file mode 100644 index 00000000..76e0cb8b --- /dev/null +++ b/src/frontend/qt_sdl/AudioInOut.h @@ -0,0 +1,44 @@ +/* + Copyright 2016-2022 melonDS team + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#ifndef AUDIO_INOUT_H +#define AUDIO_INOUT_H + +#include "types.h" + +#include + +namespace AudioInOut +{ + +void Init(); +void DeInit(); + +void MicProcess(); +void AudioMute(QMainWindow* mainWindow); + +void AudioSync(); + +void UpdateSettings(); + +void Enable(); +void Disable(); + +} + +#endif \ No newline at end of file diff --git a/src/frontend/qt_sdl/AudioSettingsDialog.cpp b/src/frontend/qt_sdl/AudioSettingsDialog.cpp index 198c06b3..5d8f2fbd 100644 --- a/src/frontend/qt_sdl/AudioSettingsDialog.cpp +++ b/src/frontend/qt_sdl/AudioSettingsDialog.cpp @@ -72,16 +72,16 @@ AudioSettingsDialog::AudioSettingsDialog(QWidget* parent, bool emuActive) : QDia } grpMicMode = new QButtonGroup(this); - grpMicMode->addButton(ui->rbMicNone, 0); - grpMicMode->addButton(ui->rbMicExternal, 1); - grpMicMode->addButton(ui->rbMicNoise, 2); - grpMicMode->addButton(ui->rbMicWav, 3); + grpMicMode->addButton(ui->rbMicNone, micInputType_Silence); + grpMicMode->addButton(ui->rbMicExternal, micInputType_External); + grpMicMode->addButton(ui->rbMicNoise, micInputType_Noise); + grpMicMode->addButton(ui->rbMicWav, micInputType_Wav); connect(grpMicMode, SIGNAL(buttonClicked(int)), this, SLOT(onChangeMicMode(int))); grpMicMode->button(Config::MicInputType)->setChecked(true); ui->txtMicWavPath->setText(QString::fromStdString(Config::MicWavPath)); - bool iswav = (Config::MicInputType == 3); + bool iswav = (Config::MicInputType == micInputType_Wav); ui->txtMicWavPath->setEnabled(iswav); ui->btnMicWavBrowse->setEnabled(iswav); diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt index 00e4c036..0ae6ecea 100644 --- a/src/frontend/qt_sdl/CMakeLists.txt +++ b/src/frontend/qt_sdl/CMakeLists.txt @@ -36,6 +36,7 @@ set(SOURCES_QT_SDL ROMManager.cpp SaveManager.cpp CameraManager.cpp + AudioInOut.cpp ArchiveUtil.h ArchiveUtil.cpp diff --git a/src/frontend/qt_sdl/Config.h b/src/frontend/qt_sdl/Config.h index 2d4022e4..2028879a 100644 --- a/src/frontend/qt_sdl/Config.h +++ b/src/frontend/qt_sdl/Config.h @@ -53,6 +53,15 @@ enum screenSizing_MAX, }; +enum +{ + micInputType_Silence, + micInputType_External, + micInputType_Noise, + micInputType_Wav, + micInputType_MAX, +}; + namespace Config { diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 9200538c..b0f1538d 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];