From 3caab10df8eaaa79ced782befb0b84a98721136d Mon Sep 17 00:00:00 2001 From: skidau Date: Fri, 5 Sep 2014 22:32:48 +1000 Subject: [PATCH 1/3] Hooked up the emulated Wiimote speaker. The Wiimotes are positioned as follows: Wiimote 0 = Center Wiimote 1 = Left Wiimote 2 = Right Wiimote 3 = Center The Wiimote speaker output can be disabled via the "Enable Speaker Data" checkbox in the Wiimote settings. --- Source/Core/AudioCommon/Mixer.cpp | 31 +++++++++++++++++++++ Source/Core/AudioCommon/Mixer.h | 4 +++ Source/Core/Core/HW/WiimoteEmu/Speaker.cpp | 8 ++++++ Source/Core/DolphinWX/WiimoteConfigDiag.cpp | 10 +++---- 4 files changed, 48 insertions(+), 5 deletions(-) diff --git a/Source/Core/AudioCommon/Mixer.cpp b/Source/Core/AudioCommon/Mixer.cpp index 70accf240f..0a71fbd98b 100644 --- a/Source/Core/AudioCommon/Mixer.cpp +++ b/Source/Core/AudioCommon/Mixer.cpp @@ -121,6 +121,7 @@ unsigned int CMixer::Mix(short* samples, unsigned int num_samples, bool consider m_dma_mixer.Mix(samples, num_samples, consider_framelimit); m_streaming_mixer.Mix(samples, num_samples, consider_framelimit); + m_wiimote_speaker_mixer.Mix(samples, num_samples, consider_framelimit); if (m_logAudio) g_wave_writer.AddStereoSamples(samples, num_samples); return num_samples; @@ -167,6 +168,31 @@ void CMixer::PushStreamingSamples(const short *samples, unsigned int num_samples m_streaming_mixer.PushSamples(samples, num_samples); } +void CMixer::PushWiimoteSpeakerSamples(const short *samples, unsigned int num_samples, unsigned int sample_rate, const u8 wiimote_index) +{ + short samples_stereo[MAX_SAMPLES * 2]; + + if (num_samples < MAX_SAMPLES) + { + m_wiimote_speaker_mixer.SetInputSampleRate(sample_rate); + + for (unsigned int i = 0; i < num_samples; ++i) + { + // Position the Wiimotes as follow + // Wiimote 0 = Center + // Wiimote 1 = Left + // Wiimote 2 = Right + // Wiimote 3 = Center + if (wiimote_index != 2) + samples_stereo[i * 2] = Common::swap16(samples[i]); + if (wiimote_index != 1) + samples_stereo[i * 2 + 1] = Common::swap16(samples[i]); + } + + m_wiimote_speaker_mixer.PushSamples(samples_stereo, num_samples); + } +} + void CMixer::SetDMAInputSampleRate(unsigned int rate) { m_dma_mixer.SetInputSampleRate(rate); @@ -182,6 +208,11 @@ void CMixer::SetStreamingVolume(unsigned int lvolume, unsigned int rvolume) m_streaming_mixer.SetVolume(lvolume, rvolume); } +void CMixer::SetWiimoteSpeakerVolume(unsigned int lvolume, unsigned int rvolume) +{ + m_wiimote_speaker_mixer.SetVolume(lvolume, rvolume); +} + void CMixer::MixerFifo::SetInputSampleRate(unsigned int rate) { m_input_sample_rate = rate; diff --git a/Source/Core/AudioCommon/Mixer.h b/Source/Core/AudioCommon/Mixer.h index 806e6aa83a..f12066d22f 100644 --- a/Source/Core/AudioCommon/Mixer.h +++ b/Source/Core/AudioCommon/Mixer.h @@ -24,6 +24,7 @@ public: CMixer(unsigned int BackendSampleRate) : m_dma_mixer(this, 32000) , m_streaming_mixer(this, 48000) + , m_wiimote_speaker_mixer(this, 3000) , m_sampleRate(BackendSampleRate) , m_logAudio(0) , m_speed(0) @@ -39,11 +40,13 @@ public: // Called from main thread virtual void PushSamples(const short* samples, unsigned int num_samples); virtual void PushStreamingSamples(const short* samples, unsigned int num_samples); + virtual void PushWiimoteSpeakerSamples(const short* samples, unsigned int num_samples, unsigned int sample_rate, const u8 wiimote_index); unsigned int GetSampleRate() const { return m_sampleRate; } void SetDMAInputSampleRate(unsigned int rate); void SetStreamInputSampleRate(unsigned int rate); void SetStreamingVolume(unsigned int lvolume, unsigned int rvolume); + void SetWiimoteSpeakerVolume(unsigned int lvolume, unsigned int rvolume); virtual void StartLogAudio(const std::string& filename) { @@ -112,6 +115,7 @@ protected: }; MixerFifo m_dma_mixer; MixerFifo m_streaming_mixer; + MixerFifo m_wiimote_speaker_mixer; unsigned int m_sampleRate; WaveFileWriter g_wave_writer; diff --git a/Source/Core/Core/HW/WiimoteEmu/Speaker.cpp b/Source/Core/Core/HW/WiimoteEmu/Speaker.cpp index 97e6df5b15..a0e374cf23 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Speaker.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/Speaker.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 // Refer to the license.txt file included. +#include "AudioCommon/AudioCommon.h" #include "Core/HW/WiimoteEmu/WiimoteEmu.h" //#define WIIMOTE_SPEAKER_DUMP @@ -64,6 +65,9 @@ void stopdamnwav(){wav.Stop();ofile.close();} void Wiimote::SpeakerData(wm_speaker_data* sd) { + if (!SConfig::GetInstance().m_WiimoteEnableSpeaker) + return; + // TODO consider using static max size instead of new s16 *samples = new s16[sd->length * 2]; @@ -74,6 +78,8 @@ void Wiimote::SpeakerData(wm_speaker_data* sd) { samples[i] = (s16)(s8)sd->data[i]; } + soundStream->GetMixer()->SetWiimoteSpeakerVolume(256, 256); + soundStream->GetMixer()->PushWiimoteSpeakerSamples(samples, sd->length, 1500, m_index); } else if (m_reg_speaker.format == 0x00) { @@ -83,6 +89,8 @@ void Wiimote::SpeakerData(wm_speaker_data* sd) samples[i * 2] = adpcm_yamaha_expand_nibble(m_adpcm_state, (sd->data[i] >> 4) & 0xf); samples[i * 2 + 1] = adpcm_yamaha_expand_nibble(m_adpcm_state, sd->data[i] & 0xf); } + soundStream->GetMixer()->SetWiimoteSpeakerVolume(256, 256); + soundStream->GetMixer()->PushWiimoteSpeakerSamples(samples, sd->length, 3000, m_index); } #ifdef WIIMOTE_SPEAKER_DUMP diff --git a/Source/Core/DolphinWX/WiimoteConfigDiag.cpp b/Source/Core/DolphinWX/WiimoteConfigDiag.cpp index 54b9beb6dd..984f8cf0f2 100644 --- a/Source/Core/DolphinWX/WiimoteConfigDiag.cpp +++ b/Source/Core/DolphinWX/WiimoteConfigDiag.cpp @@ -113,15 +113,10 @@ WiimoteConfigDiag::WiimoteConfigDiag(wxWindow* const parent, InputConfig& config continuous_scanning->Bind(wxEVT_CHECKBOX, &WiimoteConfigDiag::OnContinuousScanning, this); continuous_scanning->SetValue(SConfig::GetInstance().m_WiimoteContinuousScanning); - auto wiimote_speaker = new wxCheckBox(this, wxID_ANY, _("Enable Speaker Data")); - wiimote_speaker->Bind(wxEVT_CHECKBOX, &WiimoteConfigDiag::OnEnableSpeaker, this); - wiimote_speaker->SetValue(SConfig::GetInstance().m_WiimoteEnableSpeaker); - real_wiimotes_sizer->Add(continuous_scanning, 0, wxALIGN_CENTER_VERTICAL); real_wiimotes_sizer->AddStretchSpacer(1); real_wiimotes_sizer->Add(refresh_btn, 0, wxALL | wxALIGN_CENTER, 5); - real_wiimotes_group->Add(wiimote_speaker, 0); real_wiimotes_group->Add(real_wiimotes_sizer, 0, wxEXPAND); // "General Settings" controls @@ -131,6 +126,10 @@ WiimoteConfigDiag::WiimoteConfigDiag(wxWindow* const parent, InputConfig& config wxSlider* const WiimoteSpkVolume = new wxSlider(this, wxID_ANY, 0, 0, 127); wxCheckBox* const WiimoteMotor = new wxCheckBox(this, wxID_ANY, _("Wiimote Motor")); + auto wiimote_speaker = new wxCheckBox(this, wxID_ANY, _("Enable Speaker Data")); + wiimote_speaker->Bind(wxEVT_CHECKBOX, &WiimoteConfigDiag::OnEnableSpeaker, this); + wiimote_speaker->SetValue(SConfig::GetInstance().m_WiimoteEnableSpeaker); + wxStaticText* const WiiSensBarPosText = new wxStaticText(this, wxID_ANY, _("Sensor Bar Position:")); wxStaticText* const WiiSensBarSensText = new wxStaticText(this, wxID_ANY, _("IR Sensitivity:")); wxStaticText* const WiiSensBarSensMinText = new wxStaticText(this, wxID_ANY, _("Min")); @@ -204,6 +203,7 @@ WiimoteConfigDiag::WiimoteConfigDiag(wxWindow* const parent, InputConfig& config wxGridSizer* const general_wiimote_sizer = new wxGridSizer(1, 5, 5); general_wiimote_sizer->Add(WiimoteMotor); + general_wiimote_sizer->Add(wiimote_speaker, 0); general_sizer->Add(choice_sizer); general_sizer->Add(general_wiimote_sizer); From 8abe9622fd125f86e95d1ba62f6f2b16ff93791f Mon Sep 17 00:00:00 2001 From: skidau Date: Sat, 6 Sep 2014 01:23:54 +1000 Subject: [PATCH 2/3] Route the wiimote speaker to the sound mixer (the host system's speakers). Emulated Wiimote speaker sounds will go to the host system's speakers. Real Wiimotes will continue to use their own speaker for Wiimote speaker sounds. All Wiimote speaker sound can be disabled by unchecking the "Enable Speaker Data" option. Each emulated Wiimote can have its speaker routed from left to right via the "Speaker Pan" setting in the emulated wiimote settings dialog. Use any value from -127 for leftmost to 127 for rightmost with 0 being the centre. Added code in the InputConfig to use a spin control for non-boolean values. Defaulted the setting of "Enable Speaker Data" to disabled. --- Source/Core/AudioCommon/Mixer.cpp | 13 ++------- Source/Core/AudioCommon/Mixer.h | 2 +- Source/Core/Core/ConfigManager.cpp | 2 +- Source/Core/Core/HW/WiimoteEmu/Speaker.cpp | 16 ++++++++--- Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp | 1 + Source/Core/DolphinWX/InputConfigDiag.cpp | 28 +++++++++++++------ 6 files changed, 38 insertions(+), 24 deletions(-) diff --git a/Source/Core/AudioCommon/Mixer.cpp b/Source/Core/AudioCommon/Mixer.cpp index 0a71fbd98b..a7984579ca 100644 --- a/Source/Core/AudioCommon/Mixer.cpp +++ b/Source/Core/AudioCommon/Mixer.cpp @@ -168,7 +168,7 @@ void CMixer::PushStreamingSamples(const short *samples, unsigned int num_samples m_streaming_mixer.PushSamples(samples, num_samples); } -void CMixer::PushWiimoteSpeakerSamples(const short *samples, unsigned int num_samples, unsigned int sample_rate, const u8 wiimote_index) +void CMixer::PushWiimoteSpeakerSamples(const short *samples, unsigned int num_samples, unsigned int sample_rate) { short samples_stereo[MAX_SAMPLES * 2]; @@ -178,15 +178,8 @@ void CMixer::PushWiimoteSpeakerSamples(const short *samples, unsigned int num_sa for (unsigned int i = 0; i < num_samples; ++i) { - // Position the Wiimotes as follow - // Wiimote 0 = Center - // Wiimote 1 = Left - // Wiimote 2 = Right - // Wiimote 3 = Center - if (wiimote_index != 2) - samples_stereo[i * 2] = Common::swap16(samples[i]); - if (wiimote_index != 1) - samples_stereo[i * 2 + 1] = Common::swap16(samples[i]); + samples_stereo[i * 2] = Common::swap16(samples[i]); + samples_stereo[i * 2 + 1] = Common::swap16(samples[i]); } m_wiimote_speaker_mixer.PushSamples(samples_stereo, num_samples); diff --git a/Source/Core/AudioCommon/Mixer.h b/Source/Core/AudioCommon/Mixer.h index f12066d22f..e3272af070 100644 --- a/Source/Core/AudioCommon/Mixer.h +++ b/Source/Core/AudioCommon/Mixer.h @@ -40,7 +40,7 @@ public: // Called from main thread virtual void PushSamples(const short* samples, unsigned int num_samples); virtual void PushStreamingSamples(const short* samples, unsigned int num_samples); - virtual void PushWiimoteSpeakerSamples(const short* samples, unsigned int num_samples, unsigned int sample_rate, const u8 wiimote_index); + virtual void PushWiimoteSpeakerSamples(const short* samples, unsigned int num_samples, unsigned int sample_rate); unsigned int GetSampleRate() const { return m_sampleRate; } void SetDMAInputSampleRate(unsigned int rate); diff --git a/Source/Core/Core/ConfigManager.cpp b/Source/Core/Core/ConfigManager.cpp index 45770e961c..1b2975bd42 100644 --- a/Source/Core/Core/ConfigManager.cpp +++ b/Source/Core/Core/ConfigManager.cpp @@ -521,7 +521,7 @@ void SConfig::LoadCoreSettings(IniFile& ini) core->Get("WiiSDCard", &m_WiiSDCard, false); core->Get("WiiKeyboard", &m_WiiKeyboard, false); core->Get("WiimoteContinuousScanning", &m_WiimoteContinuousScanning, false); - core->Get("WiimoteEnableSpeaker", &m_WiimoteEnableSpeaker, true); + core->Get("WiimoteEnableSpeaker", &m_WiimoteEnableSpeaker, false); core->Get("RunCompareServer", &m_LocalCoreStartupParameter.bRunCompareServer, false); core->Get("RunCompareClient", &m_LocalCoreStartupParameter.bRunCompareClient, false); core->Get("MMU", &m_LocalCoreStartupParameter.bMMU, false); diff --git a/Source/Core/Core/HW/WiimoteEmu/Speaker.cpp b/Source/Core/Core/HW/WiimoteEmu/Speaker.cpp index a0e374cf23..2dd6b2d0e1 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Speaker.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/Speaker.cpp @@ -78,8 +78,12 @@ void Wiimote::SpeakerData(wm_speaker_data* sd) { samples[i] = (s16)(s8)sd->data[i]; } - soundStream->GetMixer()->SetWiimoteSpeakerVolume(256, 256); - soundStream->GetMixer()->PushWiimoteSpeakerSamples(samples, sd->length, 1500, m_index); + + // Speaker Pan + unsigned int vol = (unsigned int)(m_options->settings[4]->GetValue() * 100); + soundStream->GetMixer()->SetWiimoteSpeakerVolume(128 + vol, 128 - vol); + + soundStream->GetMixer()->PushWiimoteSpeakerSamples(samples, sd->length, 1500); } else if (m_reg_speaker.format == 0x00) { @@ -89,8 +93,12 @@ void Wiimote::SpeakerData(wm_speaker_data* sd) samples[i * 2] = adpcm_yamaha_expand_nibble(m_adpcm_state, (sd->data[i] >> 4) & 0xf); samples[i * 2 + 1] = adpcm_yamaha_expand_nibble(m_adpcm_state, sd->data[i] & 0xf); } - soundStream->GetMixer()->SetWiimoteSpeakerVolume(256, 256); - soundStream->GetMixer()->PushWiimoteSpeakerSamples(samples, sd->length, 3000, m_index); + + // Speaker Pan + unsigned int vol = (unsigned int)(m_options->settings[4]->GetValue() * 100); + soundStream->GetMixer()->SetWiimoteSpeakerVolume(128 + vol, 128 - vol); + + soundStream->GetMixer()->PushWiimoteSpeakerSamples(samples, sd->length, 3000); } #ifdef WIIMOTE_SPEAKER_DUMP diff --git a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp index 9dca20802a..c0bd342e8e 100644 --- a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp @@ -309,6 +309,7 @@ Wiimote::Wiimote( const unsigned int index ) m_options->settings.emplace_back(new ControlGroup::Setting(_trans("Sideways Wiimote"), false)); m_options->settings.emplace_back(new ControlGroup::Setting(_trans("Upright Wiimote"), false)); m_options->settings.emplace_back(new ControlGroup::IterateUI(_trans("Iterative Input"))); + m_options->settings.emplace_back(new ControlGroup::Setting(_trans("Speaker Pan"), 0, -127, 127)); // TODO: This value should probably be re-read if SYSCONF gets changed m_sensor_bar_on_top = SConfig::GetInstance().m_SYSCONF->GetData("BT.BAR") != 0; diff --git a/Source/Core/DolphinWX/InputConfigDiag.cpp b/Source/Core/DolphinWX/InputConfigDiag.cpp index 378b8729a0..010732eb79 100644 --- a/Source/Core/DolphinWX/InputConfigDiag.cpp +++ b/Source/Core/DolphinWX/InputConfigDiag.cpp @@ -911,19 +911,31 @@ ControlGroupBox::ControlGroupBox(ControllerEmu::ControlGroup* const group, wxWin //options for (auto& groupSetting : group->settings) { - PadSettingCheckBox* setting_cbox = new PadSettingCheckBox(parent, groupSetting.get()); - if (groupSetting.get()->is_iterate == true) + if (groupSetting.get()->high == 100) { - setting_cbox->wxcontrol->Bind(wxEVT_CHECKBOX, &GamepadPage::AdjustSettingUI, eventsink); - groupSetting.get()->value = 0; + PadSettingCheckBox* setting_cbox = new PadSettingCheckBox(parent, groupSetting.get()); + if (groupSetting.get()->is_iterate == true) + { + setting_cbox->wxcontrol->Bind(wxEVT_CHECKBOX, &GamepadPage::AdjustSettingUI, eventsink); + groupSetting.get()->value = 0; + } + else + { + setting_cbox->wxcontrol->Bind(wxEVT_CHECKBOX, &GamepadPage::AdjustSetting, eventsink); + } + options.push_back(setting_cbox); + Add(setting_cbox->wxcontrol, 0, wxALL | wxLEFT, 5); } else { - setting_cbox->wxcontrol->Bind(wxEVT_CHECKBOX, &GamepadPage::AdjustSetting, eventsink); + PadSettingSpin* setting = new PadSettingSpin(parent, groupSetting.get()); + setting->wxcontrol->Bind(wxEVT_SPINCTRL, &GamepadPage::AdjustSetting, eventsink); + options.push_back(setting); + wxBoxSizer* const szr = new wxBoxSizer(wxHORIZONTAL); + szr->Add(new wxStaticText(parent, -1, wxGetTranslation(StrToWxStr(groupSetting->name))), 0, wxCENTER | wxRIGHT, 3); + szr->Add(setting->wxcontrol, 0, wxRIGHT, 3); + Add(szr, 0, wxALL | wxCENTER, 3); } - options.push_back(setting_cbox); - - Add(setting_cbox->wxcontrol, 0, wxALL|wxLEFT, 5); } } break; From 786329555517c832f7883ed67583b95b1474fdc3 Mon Sep 17 00:00:00 2001 From: skidau Date: Sun, 7 Sep 2014 14:25:06 +1000 Subject: [PATCH 3/3] Used a constant for the default high value. --- Source/Core/DolphinWX/InputConfigDiag.cpp | 2 +- Source/Core/DolphinWX/InputConfigDiag.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/Core/DolphinWX/InputConfigDiag.cpp b/Source/Core/DolphinWX/InputConfigDiag.cpp index 010732eb79..388801a226 100644 --- a/Source/Core/DolphinWX/InputConfigDiag.cpp +++ b/Source/Core/DolphinWX/InputConfigDiag.cpp @@ -911,7 +911,7 @@ ControlGroupBox::ControlGroupBox(ControllerEmu::ControlGroup* const group, wxWin //options for (auto& groupSetting : group->settings) { - if (groupSetting.get()->high == 100) + if (groupSetting.get()->high == DEFAULT_HIGH_VALUE) { PadSettingCheckBox* setting_cbox = new PadSettingCheckBox(parent, groupSetting.get()); if (groupSetting.get()->is_iterate == true) diff --git a/Source/Core/DolphinWX/InputConfigDiag.h b/Source/Core/DolphinWX/InputConfigDiag.h index 5d1f94ba03..68694dc1e1 100644 --- a/Source/Core/DolphinWX/InputConfigDiag.h +++ b/Source/Core/DolphinWX/InputConfigDiag.h @@ -7,6 +7,7 @@ #define SLIDER_TICK_COUNT 100 #define DETECT_WAIT_TIME 2500 #define PREVIEW_UPDATE_TIME 25 +#define DEFAULT_HIGH_VALUE 100 // might have to change this setup for wiimote #define PROFILES_PATH "Profiles/"