From 418b35198680643be760dab4f4b2b8df2696041f Mon Sep 17 00:00:00 2001 From: Nadia Holmquist Pedersen Date: Mon, 16 Aug 2021 23:47:54 +0200 Subject: SPU: Emulate SOUNDBIAS and 10-bit degrade --- src/Config.cpp | 2 ++ src/Config.h | 1 + src/NDS.cpp | 13 +++++++++++++ src/SPU.cpp | 25 +++++++++++++++++++++++++ src/SPU.h | 2 ++ src/frontend/qt_sdl/AudioSettingsDialog.cpp | 17 +++++++++++++++++ src/frontend/qt_sdl/AudioSettingsDialog.h | 2 ++ src/frontend/qt_sdl/AudioSettingsDialog.ui | 18 ++++++++++++++++-- src/frontend/qt_sdl/main.cpp | 5 +++++ 9 files changed, 83 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Config.cpp b/src/Config.cpp index a84971a..23ed265 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -42,6 +42,7 @@ int DSiSDEnable; char DSiSDPath[1024]; int RandomizeMAC; +int AudioBitrate; #ifdef JIT_ENABLED int JIT_Enable = false; @@ -67,6 +68,7 @@ ConfigEntry ConfigFile[] = {"DSiSDPath", 1, DSiSDPath, 0, "", 1023}, {"RandomizeMAC", 0, &RandomizeMAC, 0, NULL, 0}, + {"AudioBitrate", 0, &AudioBitrate, 0, NULL, 0}, #ifdef JIT_ENABLED {"JIT_Enable", 0, &JIT_Enable, 0, NULL, 0}, diff --git a/src/Config.h b/src/Config.h index 54ef63b..a0c7ea8 100644 --- a/src/Config.h +++ b/src/Config.h @@ -55,6 +55,7 @@ extern int DSiSDEnable; extern char DSiSDPath[1024]; extern int RandomizeMAC; +extern int AudioBitrate; #ifdef JIT_ENABLED extern int JIT_Enable; diff --git a/src/NDS.cpp b/src/NDS.cpp index 55b4fdf..f172677 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -596,12 +596,25 @@ void Reset() RTC::Reset(); Wifi::Reset(); + // The SOUNDBIAS register does nothing on DSi + SPU::SetApplyBias(ConsoleType == 0); + + bool degradeAudio = true; + if (ConsoleType == 1) { DSi::Reset(); KeyInput &= ~(1 << (16+6)); + degradeAudio = false; } + if (Config::AudioBitrate == 1) // Always 10-bit + degradeAudio = true; + else if (Config::AudioBitrate == 2) // Always 16-bit + degradeAudio = false; + + SPU::SetDegrade10Bit(degradeAudio); + AREngine::Reset(); } diff --git a/src/SPU.cpp b/src/SPU.cpp index e42bff8..d1c2d84 100644 --- a/src/SPU.cpp +++ b/src/SPU.cpp @@ -81,6 +81,8 @@ Platform::Mutex* AudioLock; u16 Cnt; u8 MasterVolume; u16 Bias; +bool ApplyBias; +bool Degrade10Bit; Channel* Channels[16]; CaptureUnit* Capture[2]; @@ -190,6 +192,14 @@ void SetBias(u16 bias) Bias = bias; } +void SetApplyBias(bool enable) { + ApplyBias = enable; +} + +void SetDegrade10Bit(bool enable) { + Degrade10Bit = enable; +} + Channel::Channel(u32 num) { @@ -795,6 +805,21 @@ void Mix(u32 dummy) if (rightoutput < -0x8000) rightoutput = -0x8000; else if (rightoutput > 0x7FFF) rightoutput = 0x7FFF; + // The original DS and DS lite degrade the output from 16 to 10 bit before output + if (Degrade10Bit) + { + leftoutput &= 0xFFFFFFC0; + rightoutput &= 0xFFFFFFC0; + } + + // Add SOUNDBIAS value + // The value used by all commercial games is 0x200, so we subtract that so it won't offset the final sound output. + if (ApplyBias == true) + { + leftoutput += (Bias << 6) - 0x8000; + rightoutput += (Bias << 6) - 0x8000; + } + // OutputBufferFrame can never get full because it's // transfered to OutputBuffer at the end of the frame OutputBackbuffer[OutputBackbufferWritePosition ] = leftoutput >> 1; diff --git a/src/SPU.h b/src/SPU.h index 055a766..22c87a7 100644 --- a/src/SPU.h +++ b/src/SPU.h @@ -35,6 +35,8 @@ void DoSavestate(Savestate* file); void SetInterpolation(int type); void SetBias(u16 bias); +void SetDegrade10Bit(bool enable); +void SetApplyBias(bool enable); void Mix(u32 dummy); diff --git a/src/frontend/qt_sdl/AudioSettingsDialog.cpp b/src/frontend/qt_sdl/AudioSettingsDialog.cpp index 5ac178a..970b54b 100644 --- a/src/frontend/qt_sdl/AudioSettingsDialog.cpp +++ b/src/frontend/qt_sdl/AudioSettingsDialog.cpp @@ -39,6 +39,7 @@ AudioSettingsDialog::AudioSettingsDialog(QWidget* parent) : QDialog(parent), ui( setAttribute(Qt::WA_DeleteOnClose); oldInterp = Config::AudioInterp; + oldBitrate = Config::AudioBitrate; oldVolume = Config::AudioVolume; ui->cbInterpolation->addItem("None"); @@ -47,6 +48,11 @@ AudioSettingsDialog::AudioSettingsDialog(QWidget* parent) : QDialog(parent), ui( ui->cbInterpolation->addItem("Cubic"); ui->cbInterpolation->setCurrentIndex(Config::AudioInterp); + ui->cbBitrate->addItem("Automatic"); + ui->cbBitrate->addItem("10-bit"); + ui->cbBitrate->addItem("16-bit"); + ui->cbBitrate->setCurrentIndex(Config::AudioBitrate); + ui->slVolume->setValue(Config::AudioVolume); grpMicMode = new QButtonGroup(this); @@ -81,11 +87,22 @@ void AudioSettingsDialog::on_AudioSettingsDialog_accepted() void AudioSettingsDialog::on_AudioSettingsDialog_rejected() { Config::AudioInterp = oldInterp; + Config::AudioBitrate = oldBitrate; Config::AudioVolume = oldVolume; closeDlg(); } +void AudioSettingsDialog::on_cbBitrate_currentIndexChanged(int idx) +{ + // prevent a spurious change + if (ui->cbBitrate->count() < 3) return; + + Config::AudioBitrate = ui->cbBitrate->currentIndex(); + + emit updateAudioSettings(); +} + void AudioSettingsDialog::on_cbInterpolation_currentIndexChanged(int idx) { // prevent a spurious change diff --git a/src/frontend/qt_sdl/AudioSettingsDialog.h b/src/frontend/qt_sdl/AudioSettingsDialog.h index 5139975..0bb32c6 100644 --- a/src/frontend/qt_sdl/AudioSettingsDialog.h +++ b/src/frontend/qt_sdl/AudioSettingsDialog.h @@ -59,6 +59,7 @@ private slots: void on_AudioSettingsDialog_rejected(); void on_cbInterpolation_currentIndexChanged(int idx); + void on_cbBitrate_currentIndexChanged(int idx); void on_slVolume_valueChanged(int val); void onChangeMicMode(int mode); void on_btnMicWavBrowse_clicked(); @@ -67,6 +68,7 @@ private: Ui::AudioSettingsDialog* ui; int oldInterp; + int oldBitrate; int oldVolume; QButtonGroup* grpMicMode; }; diff --git a/src/frontend/qt_sdl/AudioSettingsDialog.ui b/src/frontend/qt_sdl/AudioSettingsDialog.ui index e329523..d7cfadd 100644 --- a/src/frontend/qt_sdl/AudioSettingsDialog.ui +++ b/src/frontend/qt_sdl/AudioSettingsDialog.ui @@ -29,14 +29,14 @@ Audio output - + Volume: - + <html><head/><body><p>Controls the volume of the audio output.</p></body></html> @@ -66,6 +66,20 @@ + + + + Bitrate: + + + + + + + <html><head/><body><p>The bitrate of audio playback. If set to "Automatic" this will be 10-bit for DS mode and 16-bit for DSi mode.</p></body></html> + + + diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index d8eca58..272df3c 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -2436,6 +2436,11 @@ void MainWindow::onOpenAudioSettings() void MainWindow::onUpdateAudioSettings() { SPU::SetInterpolation(Config::AudioInterp); + + if (Config::AudioBitrate == 0) + SPU::SetDegrade10Bit(NDS::ConsoleType == 0); + else + SPU::SetDegrade10Bit(Config::AudioBitrate == 1); } void MainWindow::onAudioSettingsFinished(int res) -- cgit v1.2.3