Skip to content

Commit

Permalink
Merge pull request #7782 from jordan-woyak/wiimote-emu-speaker-pan
Browse files Browse the repository at this point in the history
WiimoteEmu: Change speaker pan to use "constant power pan law".
  • Loading branch information
Tilka committed Feb 11, 2019
2 parents 226affe + 3c77b4a commit 4d85bb2
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 13 deletions.
3 changes: 1 addition & 2 deletions Source/Core/Core/HW/WiimoteEmu/EmuSubroutines.cpp
Expand Up @@ -391,8 +391,7 @@ void Wiimote::HandleSpeakerData(const WiimoteCommon::OutputReportSpeakerData& rp
else
{
// Speaker Pan
// GUI clamps pan setting from -127 to 127. Why?
const auto pan = int(m_options->numeric_settings[0]->GetValue() * 100);
const auto pan = m_options->numeric_settings[0]->GetValue();

m_speaker_logic.SpeakerData(rpt.data, rpt.length, pan);
}
Expand Down
19 changes: 10 additions & 9 deletions Source/Core/Core/HW/WiimoteEmu/Speaker.cpp
Expand Up @@ -71,7 +71,7 @@ void stopdamnwav()
}
#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?
if (!SConfig::GetInstance().m_WiimoteEnableSpeaker)
Expand Down Expand Up @@ -127,19 +127,20 @@ void SpeakerLogic::SpeakerData(const u8* data, int length, int speaker_pan)
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;
float speaker_volume_ratio = (float)reg_data.volume / volume_divisor;
// Sloppy math:
unsigned int left_volume =
MathUtil::Clamp<unsigned int>((0xff + (2 * speaker_pan)) * speaker_volume_ratio, 0, 0xff);
unsigned int right_volume =
MathUtil::Clamp<unsigned int>((0xff - (2 * speaker_pan)) * speaker_volume_ratio, 0, 0xff);
// Speaker pan using "Constant Power Pan Law"
const double pan_prime = MathUtil::PI * (speaker_pan + 1) / 4;

const auto left_volume = std::min(int(std::cos(pan_prime) * volume), 255);
const auto right_volume = std::min(int(std::sin(pan_prime) * volume), 255);

g_sound_stream->GetMixer()->SetWiimoteSpeakerVolume(left_volume, right_volume);

// 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,
sample_rate * 2);

Expand Down
3 changes: 2 additions & 1 deletion Source/Core/Core/HW/WiimoteEmu/Speaker.h
Expand Up @@ -23,7 +23,8 @@ class SpeakerLogic : public I2CSlave
void Reset();
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:
// TODO: enum class
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp
Expand Up @@ -233,7 +233,7 @@ Wiimote::Wiimote(const unsigned int index) : m_index(index)
false, ControllerEmu::SettingType::NORMAL, true));

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_battery_setting = new ControllerEmu::NumericSetting(_trans("Battery"), 95.0 / 100, 0, 100));

Expand Down

0 comments on commit 4d85bb2

Please sign in to comment.