Skip to content

Commit

Permalink
WiimoteEmu: Fix wiimote pan setting from keeping center at half volume.
Browse files Browse the repository at this point in the history
  • Loading branch information
jordan-woyak committed Feb 3, 2019
1 parent d3906e5 commit 6e5847a
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 23 deletions.
2 changes: 2 additions & 0 deletions Source/Core/Core/HW/WiimoteCommon/WiimoteConstants.h
Expand Up @@ -4,6 +4,8 @@


#pragma once #pragma once


#include "Common/CommonTypes.h"

// Wiimote internal codes // Wiimote internal codes


// Communication channels // Communication channels
Expand Down
14 changes: 10 additions & 4 deletions Source/Core/Core/HW/WiimoteEmu/EmuSubroutines.cpp
Expand Up @@ -128,13 +128,19 @@ void Wiimote::HidOutputReport(const wm_report* const sr, const bool send_ack)
break; break;


case RT_WRITE_SPEAKER_DATA: case RT_WRITE_SPEAKER_DATA:
// Not sure if speaker mute stops the bus write on real hardware, but it's not that important // TODO: Does speaker mute stop speaker data processing?
// (important to keep decoder in proper state)
if (!m_speaker_mute) if (!m_speaker_mute)
{ {
auto sd = reinterpret_cast<const wm_speaker_data*>(sr->data); auto sd = reinterpret_cast<const wm_speaker_data*>(sr->data);
if (sd->length > 20) if (sd->length > ArraySize(sd->data))
PanicAlert("EmuWiimote: bad speaker data length!"); {
SpeakerData(sd->data, sd->length); ERROR_LOG(WIIMOTE, "Bad speaker data length: %d", sd->length);
}
else
{
SpeakerData(sd->data, sd->length);
}
} }
// No ACK: // No ACK:
return; return;
Expand Down
39 changes: 22 additions & 17 deletions Source/Core/Core/HW/WiimoteEmu/Speaker.cpp
Expand Up @@ -7,6 +7,7 @@
#include "AudioCommon/AudioCommon.h" #include "AudioCommon/AudioCommon.h"
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Common/Logging/Log.h" #include "Common/Logging/Log.h"
#include "Common/MathUtil.h"
#include "Core/ConfigManager.h" #include "Core/ConfigManager.h"
#include "Core/HW/WiimoteEmu/WiimoteEmu.h" #include "Core/HW/WiimoteEmu/WiimoteEmu.h"
#include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h" #include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h"
Expand Down Expand Up @@ -70,12 +71,15 @@ void stopdamnwav()


void Wiimote::SpeakerData(const u8* data, int length) void Wiimote::SpeakerData(const u8* data, int length)
{ {
// TODO: should we still process samples for the decoder state?
if (!SConfig::GetInstance().m_WiimoteEnableSpeaker) if (!SConfig::GetInstance().m_WiimoteEnableSpeaker)
return; return;
if (m_speaker_logic.reg_data.volume == 0 || m_speaker_logic.reg_data.sample_rate == 0 ||
length == 0) if (m_speaker_logic.reg_data.sample_rate == 0 || length == 0)
return; return;


// Even if volume is zero we process samples to maintain proper decoder state.

// TODO consider using static max size instead of new // TODO consider using static max size instead of new
std::unique_ptr<s16[]> samples(new s16[length * 2]); std::unique_ptr<s16[]> samples(new s16[length * 2]);


Expand All @@ -87,7 +91,7 @@ void Wiimote::SpeakerData(const u8* data, int length)
// 8 bit PCM // 8 bit PCM
for (int i = 0; i < length; ++i) for (int i = 0; i < length; ++i)
{ {
samples[i] = ((s16)(s8)data[i]) << 8; samples[i] = ((s16)(s8)data[i]) * 0x100;
} }


// Following details from http://wiibrew.org/wiki/Wiimote#Speaker // Following details from http://wiibrew.org/wiki/Wiimote#Speaker
Expand All @@ -107,9 +111,6 @@ void Wiimote::SpeakerData(const u8* data, int length)


// Following details from http://wiibrew.org/wiki/Wiimote#Speaker // Following details from http://wiibrew.org/wiki/Wiimote#Speaker
sample_rate_dividend = 6000000; sample_rate_dividend = 6000000;

// 0 - 127
// TODO: does it go beyond 127 for format == 0x40?
volume_divisor = 0x7F; volume_divisor = 0x7F;
sample_length = (unsigned int)length * 2; sample_length = (unsigned int)length * 2;
} }
Expand All @@ -119,19 +120,23 @@ void Wiimote::SpeakerData(const u8* data, int length)
return; return;
} }


if (m_speaker_logic.reg_data.volume > volume_divisor)
{
DEBUG_LOG(IOS_WIIMOTE, "Wiimote volume is higher than suspected maximum!");
volume_divisor = m_speaker_logic.reg_data.volume;
}

// Speaker Pan // Speaker Pan
// TODO: fix // GUI clamps pan setting from -127 to 127. Why?
unsigned int vol = (unsigned int)(m_options->numeric_settings[0]->GetValue() * 100); const auto pan = (unsigned int)(m_options->numeric_settings[0]->GetValue() * 100);


unsigned int sample_rate = sample_rate_dividend / m_speaker_logic.reg_data.sample_rate; const unsigned int sample_rate = sample_rate_dividend / m_speaker_logic.reg_data.sample_rate;
float speaker_volume_ratio = (float)m_speaker_logic.reg_data.volume / volume_divisor; float speaker_volume_ratio = (float)m_speaker_logic.reg_data.volume / volume_divisor;
unsigned int left_volume = (unsigned int)((128 + vol) * speaker_volume_ratio); // Sloppy math:
unsigned int right_volume = (unsigned int)((128 - vol) * speaker_volume_ratio); unsigned int left_volume =

MathUtil::Clamp<unsigned int>((0xff + (2 * pan)) * speaker_volume_ratio, 0, 0xff);
if (left_volume > 255) unsigned int right_volume =
left_volume = 255; MathUtil::Clamp<unsigned int>((0xff - (2 * pan)) * speaker_volume_ratio, 0, 0xff);
if (right_volume > 255)
right_volume = 255;


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


Expand Down Expand Up @@ -161,4 +166,4 @@ void Wiimote::SpeakerData(const u8* data, int length)
num++; num++;
#endif #endif
} }
} } // namespace WiimoteEmu
4 changes: 2 additions & 2 deletions Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp
Expand Up @@ -1276,7 +1276,7 @@ void Wiimote::MotionPlusLogic::Update()


// A real wiimote takes about 2 seconds to reach this state: // A real wiimote takes about 2 seconds to reach this state:
reg_data.cert_ready = 0x1a; reg_data.cert_ready = 0x1a;
INFO_LOG(WIIMOTE, "M+ cert 2 ready!", reg_data.cert_ready); INFO_LOG(WIIMOTE, "M+ cert 2 ready!");
} }


// TODO: make sure a motion plus report is sent first after init // TODO: make sure a motion plus report is sent first after init
Expand Down Expand Up @@ -1364,7 +1364,7 @@ void Wiimote::MotionPlusLogic::Update()
break; break;
} }
default: default:
PanicAlert("MotionPlus unknown passthrough-mode %d", GetPassthroughMode()); PanicAlert("MotionPlus unknown passthrough-mode %d", (int)GetPassthroughMode());
break; break;
} }
} }
Expand Down
3 changes: 3 additions & 0 deletions Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h
Expand Up @@ -540,6 +540,7 @@ class Wiimote : public ControllerEmu::EmulatedController


static_assert(0x100 == sizeof(reg_data)); static_assert(0x100 == sizeof(reg_data));


// TODO: What actions should reset this state?
ADPCMState adpcm_state; ADPCMState adpcm_state;


static const u8 DEVICE_ADDR = 0x51; static const u8 DEVICE_ADDR = 0x51;
Expand All @@ -564,6 +565,8 @@ class Wiimote : public ControllerEmu::EmulatedController
} }
else else
{ {
// TODO: Does writing immediately change the decoder config even when active
// or does a write to 0x08 activate the new configuration or something?
return RawWrite(&reg_data, addr, count, data_in); return RawWrite(&reg_data, addr, count, data_in);
} }
} }
Expand Down

0 comments on commit 6e5847a

Please sign in to comment.