SPU: Emulate SOUNDBIAS and 10-bit degrade

This commit is contained in:
Nadia Holmquist Pedersen 2021-08-16 23:47:54 +02:00
parent d5a20ad3c8
commit 418b351986
9 changed files with 83 additions and 2 deletions

View File

@ -42,6 +42,7 @@ int DSiSDEnable;
char DSiSDPath[1024]; char DSiSDPath[1024];
int RandomizeMAC; int RandomizeMAC;
int AudioBitrate;
#ifdef JIT_ENABLED #ifdef JIT_ENABLED
int JIT_Enable = false; int JIT_Enable = false;
@ -67,6 +68,7 @@ ConfigEntry ConfigFile[] =
{"DSiSDPath", 1, DSiSDPath, 0, "", 1023}, {"DSiSDPath", 1, DSiSDPath, 0, "", 1023},
{"RandomizeMAC", 0, &RandomizeMAC, 0, NULL, 0}, {"RandomizeMAC", 0, &RandomizeMAC, 0, NULL, 0},
{"AudioBitrate", 0, &AudioBitrate, 0, NULL, 0},
#ifdef JIT_ENABLED #ifdef JIT_ENABLED
{"JIT_Enable", 0, &JIT_Enable, 0, NULL, 0}, {"JIT_Enable", 0, &JIT_Enable, 0, NULL, 0},

View File

@ -55,6 +55,7 @@ extern int DSiSDEnable;
extern char DSiSDPath[1024]; extern char DSiSDPath[1024];
extern int RandomizeMAC; extern int RandomizeMAC;
extern int AudioBitrate;
#ifdef JIT_ENABLED #ifdef JIT_ENABLED
extern int JIT_Enable; extern int JIT_Enable;

View File

@ -596,12 +596,25 @@ void Reset()
RTC::Reset(); RTC::Reset();
Wifi::Reset(); Wifi::Reset();
// The SOUNDBIAS register does nothing on DSi
SPU::SetApplyBias(ConsoleType == 0);
bool degradeAudio = true;
if (ConsoleType == 1) if (ConsoleType == 1)
{ {
DSi::Reset(); DSi::Reset();
KeyInput &= ~(1 << (16+6)); 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(); AREngine::Reset();
} }

View File

@ -81,6 +81,8 @@ Platform::Mutex* AudioLock;
u16 Cnt; u16 Cnt;
u8 MasterVolume; u8 MasterVolume;
u16 Bias; u16 Bias;
bool ApplyBias;
bool Degrade10Bit;
Channel* Channels[16]; Channel* Channels[16];
CaptureUnit* Capture[2]; CaptureUnit* Capture[2];
@ -190,6 +192,14 @@ void SetBias(u16 bias)
Bias = bias; Bias = bias;
} }
void SetApplyBias(bool enable) {
ApplyBias = enable;
}
void SetDegrade10Bit(bool enable) {
Degrade10Bit = enable;
}
Channel::Channel(u32 num) Channel::Channel(u32 num)
{ {
@ -795,6 +805,21 @@ void Mix(u32 dummy)
if (rightoutput < -0x8000) rightoutput = -0x8000; if (rightoutput < -0x8000) rightoutput = -0x8000;
else if (rightoutput > 0x7FFF) rightoutput = 0x7FFF; 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 // OutputBufferFrame can never get full because it's
// transfered to OutputBuffer at the end of the frame // transfered to OutputBuffer at the end of the frame
OutputBackbuffer[OutputBackbufferWritePosition ] = leftoutput >> 1; OutputBackbuffer[OutputBackbufferWritePosition ] = leftoutput >> 1;

View File

@ -35,6 +35,8 @@ void DoSavestate(Savestate* file);
void SetInterpolation(int type); void SetInterpolation(int type);
void SetBias(u16 bias); void SetBias(u16 bias);
void SetDegrade10Bit(bool enable);
void SetApplyBias(bool enable);
void Mix(u32 dummy); void Mix(u32 dummy);

View File

@ -39,6 +39,7 @@ AudioSettingsDialog::AudioSettingsDialog(QWidget* parent) : QDialog(parent), ui(
setAttribute(Qt::WA_DeleteOnClose); setAttribute(Qt::WA_DeleteOnClose);
oldInterp = Config::AudioInterp; oldInterp = Config::AudioInterp;
oldBitrate = Config::AudioBitrate;
oldVolume = Config::AudioVolume; oldVolume = Config::AudioVolume;
ui->cbInterpolation->addItem("None"); ui->cbInterpolation->addItem("None");
@ -47,6 +48,11 @@ AudioSettingsDialog::AudioSettingsDialog(QWidget* parent) : QDialog(parent), ui(
ui->cbInterpolation->addItem("Cubic"); ui->cbInterpolation->addItem("Cubic");
ui->cbInterpolation->setCurrentIndex(Config::AudioInterp); 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); ui->slVolume->setValue(Config::AudioVolume);
grpMicMode = new QButtonGroup(this); grpMicMode = new QButtonGroup(this);
@ -81,11 +87,22 @@ void AudioSettingsDialog::on_AudioSettingsDialog_accepted()
void AudioSettingsDialog::on_AudioSettingsDialog_rejected() void AudioSettingsDialog::on_AudioSettingsDialog_rejected()
{ {
Config::AudioInterp = oldInterp; Config::AudioInterp = oldInterp;
Config::AudioBitrate = oldBitrate;
Config::AudioVolume = oldVolume; Config::AudioVolume = oldVolume;
closeDlg(); 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) void AudioSettingsDialog::on_cbInterpolation_currentIndexChanged(int idx)
{ {
// prevent a spurious change // prevent a spurious change

View File

@ -59,6 +59,7 @@ private slots:
void on_AudioSettingsDialog_rejected(); void on_AudioSettingsDialog_rejected();
void on_cbInterpolation_currentIndexChanged(int idx); void on_cbInterpolation_currentIndexChanged(int idx);
void on_cbBitrate_currentIndexChanged(int idx);
void on_slVolume_valueChanged(int val); void on_slVolume_valueChanged(int val);
void onChangeMicMode(int mode); void onChangeMicMode(int mode);
void on_btnMicWavBrowse_clicked(); void on_btnMicWavBrowse_clicked();
@ -67,6 +68,7 @@ private:
Ui::AudioSettingsDialog* ui; Ui::AudioSettingsDialog* ui;
int oldInterp; int oldInterp;
int oldBitrate;
int oldVolume; int oldVolume;
QButtonGroup* grpMicMode; QButtonGroup* grpMicMode;
}; };

View File

@ -29,14 +29,14 @@
<string>Audio output</string> <string>Audio output</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout_2"> <layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="0"> <item row="2" column="0">
<widget class="QLabel" name="label"> <widget class="QLabel" name="label">
<property name="text"> <property name="text">
<string>Volume:</string> <string>Volume:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="2" column="1">
<widget class="QSlider" name="slVolume"> <widget class="QSlider" name="slVolume">
<property name="whatsThis"> <property name="whatsThis">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Controls the volume of the audio output.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Controls the volume of the audio output.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
@ -66,6 +66,20 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Bitrate:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="cbBitrate">
<property name="whatsThis">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The bitrate of audio playback. If set to &quot;Automatic&quot; this will be 10-bit for DS mode and 16-bit for DSi mode.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>

View File

@ -2436,6 +2436,11 @@ void MainWindow::onOpenAudioSettings()
void MainWindow::onUpdateAudioSettings() void MainWindow::onUpdateAudioSettings()
{ {
SPU::SetInterpolation(Config::AudioInterp); SPU::SetInterpolation(Config::AudioInterp);
if (Config::AudioBitrate == 0)
SPU::SetDegrade10Bit(NDS::ConsoleType == 0);
else
SPU::SetDegrade10Bit(Config::AudioBitrate == 1);
} }
void MainWindow::onAudioSettingsFinished(int res) void MainWindow::onAudioSettingsFinished(int res)