From 84848b52e074b37278ebc42b3a3e6d096e0c78dd Mon Sep 17 00:00:00 2001 From: skidau Date: Wed, 21 Jan 2015 00:11:54 +1100 Subject: [PATCH] Fixed the emulated wiimote speaker's ADPCM sample rate. Patch by hk.konpie. --- .../Core/HW/WiimoteEmu/EmuSubroutines.cpp | 2 +- Source/Core/Core/HW/WiimoteEmu/Speaker.cpp | 41 +++++++++---------- Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp | 4 ++ 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/Source/Core/Core/HW/WiimoteEmu/EmuSubroutines.cpp b/Source/Core/Core/HW/WiimoteEmu/EmuSubroutines.cpp index 10277873d5..b67d6a861b 100644 --- a/Source/Core/Core/HW/WiimoteEmu/EmuSubroutines.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/EmuSubroutines.cpp @@ -125,7 +125,7 @@ void Wiimote::HidOutputReport(const wm_report* const sr, const bool send_ack) //wm_speaker_data *spkz = (wm_speaker_data*)sr->data; //ERROR_LOG(WIIMOTE, "WM_WRITE_SPEAKER_DATA len:%x %s", spkz->length, // ArrayToString(spkz->data, spkz->length, 100, false).c_str()); - if (WIIMOTE_SRC_EMU & g_wiimote_sources[m_index]) + if (WIIMOTE_SRC_EMU & g_wiimote_sources[m_index] && !m_speaker_mute) Wiimote::SpeakerData((wm_speaker_data*) sr->data); return; // no ack break; diff --git a/Source/Core/Core/HW/WiimoteEmu/Speaker.cpp b/Source/Core/Core/HW/WiimoteEmu/Speaker.cpp index 065511667f..3edea3f999 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Speaker.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/Speaker.cpp @@ -28,7 +28,7 @@ static const s32 yamaha_indexscale[] = { 230, 230, 230, 230, 307, 409, 512, 614 }; -static u16 av_clip16(s32 a) +static s16 av_clip16(s32 a) { if ((a+32768) & ~65535) return (a>>31) ^ 32767; else return a; @@ -43,12 +43,6 @@ static s32 av_clip(s32 a, s32 amin, s32 amax) static s16 adpcm_yamaha_expand_nibble(ADPCMState& s, u8 nibble) { - if (!s.step) - { - s.predictor = 0; - s.step = 0; - } - s.predictor += (s.step * yamaha_difflookup[nibble]) / 8; s.predictor = av_clip16(s.predictor); s.step = (s.step * yamaha_indexscale[nibble]) >> 8; @@ -67,11 +61,13 @@ void Wiimote::SpeakerData(wm_speaker_data* sd) { if (!SConfig::GetInstance().m_WiimoteEnableSpeaker) return; + if (m_reg_speaker.volume == 0 || m_reg_speaker.sample_rate == 0 || sd->length == 0) + return; // TODO consider using static max size instead of new std::unique_ptr samples(new s16[sd->length * 2]); - unsigned int sample_rate_dividend; + unsigned int sample_rate_dividend, sample_length; u8 volume_divisor; if (m_reg_speaker.format == 0x40) @@ -79,12 +75,13 @@ void Wiimote::SpeakerData(wm_speaker_data* sd) // 8 bit PCM for (int i = 0; i < sd->length; ++i) { - samples[i] = (s16)(s8)sd->data[i]; + samples[i] = ((s16)(s8)sd->data[i]) << 8; } // Following details from http://wiibrew.org/wiki/Wiimote#Speaker sample_rate_dividend = 12000000; volume_divisor = 0xff; + sample_length = (unsigned int)sd->length; } else if (m_reg_speaker.format == 0x00) { @@ -101,6 +98,7 @@ void Wiimote::SpeakerData(wm_speaker_data* sd) // 0 - 127 // TODO: does it go beyond 127 for format == 0x40? volume_divisor = 0x7F; + sample_length = (unsigned int)sd->length * 2; } else { @@ -111,21 +109,20 @@ void Wiimote::SpeakerData(wm_speaker_data* sd) // Speaker Pan unsigned int vol = (unsigned int)(m_options->settings[4]->GetValue() * 100); - if (m_reg_speaker.sample_rate) - { - unsigned int sample_rate = sample_rate_dividend / m_reg_speaker.sample_rate; - float speaker_volume_ratio = (float)m_reg_speaker.volume / volume_divisor; - unsigned int left_volume = (unsigned int)((128 + vol) * speaker_volume_ratio); - unsigned int right_volume = (unsigned int)((128 - vol) * speaker_volume_ratio); + unsigned int sample_rate = sample_rate_dividend / m_reg_speaker.sample_rate; + float speaker_volume_ratio = (float)m_reg_speaker.volume / volume_divisor; + unsigned int left_volume = (unsigned int)((128 + vol) * speaker_volume_ratio); + unsigned int right_volume = (unsigned int)((128 - vol) * speaker_volume_ratio); - if (left_volume > 255) - left_volume = 255; - if (right_volume > 255) - right_volume = 255; + if (left_volume > 255) + left_volume = 255; + if (right_volume > 255) + right_volume = 255; - g_sound_stream->GetMixer()->SetWiimoteSpeakerVolume(left_volume, right_volume); - g_sound_stream->GetMixer()->PushWiimoteSpeakerSamples(samples.get(), sd->length, sample_rate); - } + g_sound_stream->GetMixer()->SetWiimoteSpeakerVolume(left_volume, right_volume); + + // ADPCM sample rate is thought to be x2.(3000 x2 = 6000). + g_sound_stream->GetMixer()->PushWiimoteSpeakerSamples(samples.get(), sample_length, sample_rate * 2); #ifdef WIIMOTE_SPEAKER_DUMP static int num = 0; diff --git a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp index 14b619bef0..973840b447 100644 --- a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp @@ -240,6 +240,10 @@ void Wiimote::Reset() delete[] m_read_requests.front().data; m_read_requests.pop(); } + + // Yamaha ADPCM state initialize + m_adpcm_state.predictor = 0; + m_adpcm_state.step = 127; } Wiimote::Wiimote( const unsigned int index )