Skip to content

Commit

Permalink
WiimoteEmu: Change speaker pan to use "constant power pan law" and ch…
Browse files Browse the repository at this point in the history
…ange UI setting max value from 127 to 100.
  • Loading branch information
jordan-woyak committed Feb 10, 2019
1 parent 4e825be commit 3c77b4a
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 3c77b4a

Please sign in to comment.