Merge pull request #1926 from skidau/emu-wiimote-speaker-adpcm-sample-rate

Fixed the emulated wiimote speaker's ADPCM sample rate.  Patch by hk.konpie
This commit is contained in:
skidau 2015-01-23 12:31:20 +11:00
commit 0b1d8fae1b
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; //wm_speaker_data *spkz = (wm_speaker_data*)sr->data;
//ERROR_LOG(WIIMOTE, "WM_WRITE_SPEAKER_DATA len:%x %s", spkz->length, //ERROR_LOG(WIIMOTE, "WM_WRITE_SPEAKER_DATA len:%x %s", spkz->length,
// ArrayToString(spkz->data, spkz->length, 100, false).c_str()); // 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); Wiimote::SpeakerData((wm_speaker_data*) sr->data);
return; // no ack return; // no ack
break; break;

View File

@ -28,7 +28,7 @@ static const s32 yamaha_indexscale[] = {
230, 230, 230, 230, 307, 409, 512, 614 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; if ((a+32768) & ~65535) return (a>>31) ^ 32767;
else return a; 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) 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 += (s.step * yamaha_difflookup[nibble]) / 8;
s.predictor = av_clip16(s.predictor); s.predictor = av_clip16(s.predictor);
s.step = (s.step * yamaha_indexscale[nibble]) >> 8; s.step = (s.step * yamaha_indexscale[nibble]) >> 8;
@ -67,11 +61,13 @@ void Wiimote::SpeakerData(wm_speaker_data* sd)
{ {
if (!SConfig::GetInstance().m_WiimoteEnableSpeaker) if (!SConfig::GetInstance().m_WiimoteEnableSpeaker)
return; 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 // TODO consider using static max size instead of new
std::unique_ptr<s16[]> samples(new s16[sd->length * 2]); 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; u8 volume_divisor;
if (m_reg_speaker.format == 0x40) if (m_reg_speaker.format == 0x40)
@ -79,12 +75,13 @@ void Wiimote::SpeakerData(wm_speaker_data* sd)
// 8 bit PCM // 8 bit PCM
for (int i = 0; i < sd->length; ++i) 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 // Following details from http://wiibrew.org/wiki/Wiimote#Speaker
sample_rate_dividend = 12000000; sample_rate_dividend = 12000000;
volume_divisor = 0xff; volume_divisor = 0xff;
sample_length = (unsigned int)sd->length;
} }
else if (m_reg_speaker.format == 0x00) else if (m_reg_speaker.format == 0x00)
{ {
@ -101,6 +98,7 @@ void Wiimote::SpeakerData(wm_speaker_data* sd)
// 0 - 127 // 0 - 127
// TODO: does it go beyond 127 for format == 0x40? // TODO: does it go beyond 127 for format == 0x40?
volume_divisor = 0x7F; volume_divisor = 0x7F;
sample_length = (unsigned int)sd->length * 2;
} }
else else
{ {
@ -111,21 +109,20 @@ void Wiimote::SpeakerData(wm_speaker_data* sd)
// Speaker Pan // Speaker Pan
unsigned int vol = (unsigned int)(m_options->settings[4]->GetValue() * 100); 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 sample_rate = sample_rate_dividend / m_reg_speaker.sample_rate; unsigned int left_volume = (unsigned int)((128 + vol) * speaker_volume_ratio);
float speaker_volume_ratio = (float)m_reg_speaker.volume / volume_divisor; unsigned int right_volume = (unsigned int)((128 - vol) * speaker_volume_ratio);
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) if (left_volume > 255)
left_volume = 255; left_volume = 255;
if (right_volume > 255) if (right_volume > 255)
right_volume = 255; right_volume = 255;
g_sound_stream->GetMixer()->SetWiimoteSpeakerVolume(left_volume, right_volume); g_sound_stream->GetMixer()->SetWiimoteSpeakerVolume(left_volume, right_volume);
g_sound_stream->GetMixer()->PushWiimoteSpeakerSamples(samples.get(), sd->length, sample_rate);
} // 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 #ifdef WIIMOTE_SPEAKER_DUMP
static int num = 0; static int num = 0;

View File

@ -240,6 +240,10 @@ void Wiimote::Reset()
delete[] m_read_requests.front().data; delete[] m_read_requests.front().data;
m_read_requests.pop(); m_read_requests.pop();
} }
// Yamaha ADPCM state initialize
m_adpcm_state.predictor = 0;
m_adpcm_state.step = 127;
} }
Wiimote::Wiimote( const unsigned int index ) Wiimote::Wiimote( const unsigned int index )