Merge pull request #7782 from jordan-woyak/wiimote-emu-speaker-pan

WiimoteEmu: Change speaker pan to use "constant power pan law".
This commit is contained in:
Tilka 2019-02-11 00:20:07 +00:00 committed by GitHub
commit 4d85bb2d18
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 14 additions and 13 deletions

View File

@ -391,8 +391,7 @@ void Wiimote::HandleSpeakerData(const WiimoteCommon::OutputReportSpeakerData& rp
else else
{ {
// Speaker Pan // Speaker Pan
// GUI clamps pan setting from -127 to 127. Why? const auto pan = m_options->numeric_settings[0]->GetValue();
const auto pan = int(m_options->numeric_settings[0]->GetValue() * 100);
m_speaker_logic.SpeakerData(rpt.data, rpt.length, pan); m_speaker_logic.SpeakerData(rpt.data, rpt.length, pan);
} }

View File

@ -71,7 +71,7 @@ void stopdamnwav()
} }
#endif #endif
void SpeakerLogic::SpeakerData(const u8* data, int length, int speaker_pan) void SpeakerLogic::SpeakerData(const u8* data, int length, float speaker_pan)
{ {
// TODO: should we still process samples for the decoder state? // TODO: should we still process samples for the decoder state?
if (!SConfig::GetInstance().m_WiimoteEnableSpeaker) if (!SConfig::GetInstance().m_WiimoteEnableSpeaker)
@ -127,19 +127,20 @@ void SpeakerLogic::SpeakerData(const u8* data, int length, int speaker_pan)
volume_divisor = reg_data.volume; volume_divisor = reg_data.volume;
} }
// TODO: use speaker pan law // SetWiimoteSpeakerVolume expects values from 0 to 255.
// Multiply by 256, cast to int, and clamp to 255 for a uniform conversion.
const double volume = float(reg_data.volume) / volume_divisor * 256;
const unsigned int sample_rate = sample_rate_dividend / reg_data.sample_rate; // Speaker pan using "Constant Power Pan Law"
float speaker_volume_ratio = (float)reg_data.volume / volume_divisor; const double pan_prime = MathUtil::PI * (speaker_pan + 1) / 4;
// Sloppy math:
unsigned int left_volume = const auto left_volume = std::min(int(std::cos(pan_prime) * volume), 255);
MathUtil::Clamp<unsigned int>((0xff + (2 * speaker_pan)) * speaker_volume_ratio, 0, 0xff); const auto right_volume = std::min(int(std::sin(pan_prime) * volume), 255);
unsigned int right_volume =
MathUtil::Clamp<unsigned int>((0xff - (2 * speaker_pan)) * speaker_volume_ratio, 0, 0xff);
g_sound_stream->GetMixer()->SetWiimoteSpeakerVolume(left_volume, right_volume); g_sound_stream->GetMixer()->SetWiimoteSpeakerVolume(left_volume, right_volume);
// ADPCM sample rate is thought to be x2.(3000 x2 = 6000). // ADPCM sample rate is thought to be x2.(3000 x2 = 6000).
const unsigned int sample_rate = sample_rate_dividend / reg_data.sample_rate;
g_sound_stream->GetMixer()->PushWiimoteSpeakerSamples(samples.get(), sample_length, g_sound_stream->GetMixer()->PushWiimoteSpeakerSamples(samples.get(), sample_length,
sample_rate * 2); sample_rate * 2);

View File

@ -23,7 +23,8 @@ public:
void Reset(); void Reset();
void DoState(PointerWrap& p); void DoState(PointerWrap& p);
void SpeakerData(const u8* data, int length, int speaker_pan); // Pan is -1.0 to +1.0
void SpeakerData(const u8* data, int length, float speaker_pan);
private: private:
// TODO: enum class // TODO: enum class

View File

@ -233,7 +233,7 @@ Wiimote::Wiimote(const unsigned int index) : m_index(index)
false, ControllerEmu::SettingType::NORMAL, true)); false, ControllerEmu::SettingType::NORMAL, true));
m_options->numeric_settings.emplace_back( m_options->numeric_settings.emplace_back(
std::make_unique<ControllerEmu::NumericSetting>(_trans("Speaker Pan"), 0, -127, 127)); std::make_unique<ControllerEmu::NumericSetting>(_trans("Speaker Pan"), 0, -100, 100));
m_options->numeric_settings.emplace_back( m_options->numeric_settings.emplace_back(
m_battery_setting = new ControllerEmu::NumericSetting(_trans("Battery"), 95.0 / 100, 0, 100)); m_battery_setting = new ControllerEmu::NumericSetting(_trans("Battery"), 95.0 / 100, 0, 100));