mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-08 21:53:31 +01:00
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:
commit
0b1d8fae1b
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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 )
|
||||||
|
Loading…
x
Reference in New Issue
Block a user