SPU: Emulate SOUNDBIAS and 10-bit degrade
This commit is contained in:
parent
d5a20ad3c8
commit
418b351986
|
@ -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},
|
||||||
|
|
|
@ -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;
|
||||||
|
|
13
src/NDS.cpp
13
src/NDS.cpp
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
25
src/SPU.cpp
25
src/SPU.cpp
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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><html><head/><body><p>Controls the volume of the audio output.</p></body></html></string>
|
<string><html><head/><body><p>Controls the volume of the audio output.</p></body></html></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><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></string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue