Skip to content

Commit

Permalink
Merge pull request #1926 from skidau/emu-wiimote-speaker-adpcm-sample…
Browse files Browse the repository at this point in the history
…-rate

Fixed the emulated wiimote speaker's ADPCM sample rate.  Patch by hk.konpie
  • Loading branch information
skidau committed Jan 23, 2015
2 parents 6e99acc + 84848b5 commit 0b1d8fa
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 25 deletions.
2 changes: 1 addition & 1 deletion Source/Core/Core/HW/WiimoteEmu/EmuSubroutines.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
45 changes: 21 additions & 24 deletions Source/Core/Core/HW/WiimoteEmu/Speaker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -67,24 +61,27 @@ 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<s16[]> 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)
{
// 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)
{
Expand All @@ -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
{
Expand All @@ -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);

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);
}
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;

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;
Expand Down
4 changes: 4 additions & 0 deletions Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 )
Expand Down

0 comments on commit 0b1d8fa

Please sign in to comment.