Fixed the emulated wiimote speaker's ADPCM sample rate. Patch by hk.konpie.

This commit is contained in:
skidau 2015-01-21 00:11:54 +11:00
parent 8ff1dc9c87
commit 84848b52e0
3 changed files with 24 additions and 23 deletions

View File

@ -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;

View File

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

View File

@ -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 )