fix sound crackling

This commit is contained in:
Daryl Borth 2018-08-14 11:00:45 -06:00
parent 395f9069ef
commit 7da04d7d01
6 changed files with 60 additions and 21 deletions

View File

@ -478,12 +478,13 @@ DefaultSettings ()
Settings.HDMATimingHack = 100; Settings.HDMATimingHack = 100;
// Sound defaults. On Wii this is 32Khz/16bit/Stereo // Sound defaults. On Wii this is 32Khz/16bit/Stereo
//Settings.SoundSync = true; Settings.SoundSync = true;
Settings.SixteenBitSound = true; Settings.SixteenBitSound = true;
Settings.Stereo = true; Settings.Stereo = true;
Settings.ReverseStereo = true; Settings.ReverseStereo = true;
Settings.SoundPlaybackRate = 32040; Settings.SoundPlaybackRate = 32040;
Settings.SoundInputRate = 32040; Settings.SoundInputRate = 32000;
Settings.DynamicRateControl = true;
// Graphics // Graphics
Settings.Transparency = true; Settings.Transparency = true;

View File

@ -85,11 +85,7 @@ void S9xInitSync()
/*** Synchronisation ***/ /*** Synchronisation ***/
void S9xSyncSpeed () void S9xSyncSpeed () {
{
while (!S9xSyncSound())
usleep(10);
uint32 skipFrms = Settings.SkipFrames; uint32 skipFrms = Settings.SkipFrames;
if (Settings.TurboMode) if (Settings.TurboMode)

View File

@ -131,7 +131,6 @@ void SNES_SPC::enable_rom( int enable )
int count = (time) - m.dsp_time;\ int count = (time) - m.dsp_time;\
if ( !SPC_MORE_ACCURACY || count )\ if ( !SPC_MORE_ACCURACY || count )\
{\ {\
assert( count > 0 );\
m.dsp_time = (time);\ m.dsp_time = (time);\
dsp.run( count );\ dsp.run( count );\
}\ }\
@ -402,7 +401,7 @@ void SNES_SPC::cpu_write_high( int data, int i, rel_time_t time )
} }
else else
{ {
assert( *(&(RAM [0]) + i + rom_addr) == (uint8_t) data ); //assert( *(&(RAM [0]) + i + rom_addr) == (uint8_t) data );
*(&(RAM [0]) + i + rom_addr) = cpu_pad_fill; // restore overwritten padding *(&(RAM [0]) + i + rom_addr) = cpu_pad_fill; // restore overwritten padding
cpu_write( data, i + rom_addr - 0x10000, time ); cpu_write( data, i + rom_addr - 0x10000, time );
} }
@ -494,7 +493,7 @@ int SNES_SPC::cpu_read( int addr, rel_time_t time )
} }
else // 1% else // 1%
{ {
assert( reg + (r_t0out + 0xF0 - 0x10000) < 0x100 ); //assert( reg + (r_t0out + 0xF0 - 0x10000) < 0x100 );
result = cpu_read( reg + (r_t0out + 0xF0 - 0x10000), time ); result = cpu_read( reg + (r_t0out + 0xF0 - 0x10000), time );
} }
} }
@ -543,7 +542,7 @@ void SNES_SPC::end_frame( time_t end_time )
// Greatest number of clocks early that emulation can stop early due to // Greatest number of clocks early that emulation can stop early due to
// not being able to execute current instruction without going over // not being able to execute current instruction without going over
// allowed time. // allowed time.
assert( -cpu_lag_max <= m.spc_time && m.spc_time <= cpu_lag_max ); //assert( -cpu_lag_max <= m.spc_time && m.spc_time <= cpu_lag_max );
// Catch timers up to CPU // Catch timers up to CPU
for ( int i = 0; i < timer_count; i++ ) for ( int i = 0; i < timer_count; i++ )

View File

@ -237,6 +237,8 @@ namespace spc
if necessary on game load. */ if necessary on game load. */
static uint32 ratio_numerator = APU_NUMERATOR_NTSC; static uint32 ratio_numerator = APU_NUMERATOR_NTSC;
static uint32 ratio_denominator = APU_DENOMINATOR_NTSC; static uint32 ratio_denominator = APU_DENOMINATOR_NTSC;
static double dynamic_rate_multiplier = 1.0;
} }
namespace msu namespace msu
@ -273,7 +275,7 @@ static void DeStereo (uint8 *buffer, int sample_count)
int16 *buf = (int16 *) buffer; int16 *buf = (int16 *) buffer;
int32 s1, s2; int32 s1, s2;
for (int i = 0; i < sample_count >> 1; i++) for (int i = 0; i < (sample_count >> 1); i++)
{ {
s1 = (int32) buf[2 * i]; s1 = (int32) buf[2 * i];
s2 = (int32) buf[2 * i + 1]; s2 = (int32) buf[2 * i + 1];
@ -328,6 +330,8 @@ bool8 S9xMixSamples (uint8 *buffer, int sample_count)
{ {
memset(dest, 0, sample_count << 1); memset(dest, 0, sample_count << 1);
spc::resampler->clear(); spc::resampler->clear();
if(Settings.MSU1)
msu::resampler->clear(); msu::resampler->clear();
return (FALSE); return (FALSE);
@ -387,6 +391,24 @@ int S9xGetSampleCount (void)
return (spc::resampler->avail() >> (Settings.Stereo ? 0 : 1)); return (spc::resampler->avail() >> (Settings.Stereo ? 0 : 1));
} }
#ifdef GEKKO
void S9xIncreaseDynamicRateMultiplier ()
{
if(spc::dynamic_rate_multiplier != 1.001) {
spc::dynamic_rate_multiplier = 1.001;
UpdatePlaybackRate();
}
}
void S9xResetDynamicRateMultiplier ()
{
if(spc::dynamic_rate_multiplier != 1.0) {
spc::dynamic_rate_multiplier = 1.0;
UpdatePlaybackRate();
}
}
#endif
void S9xFinalizeSamples (void) void S9xFinalizeSamples (void)
{ {
bool drop_current_msu1_samples = TRUE; bool drop_current_msu1_samples = TRUE;
@ -399,6 +421,7 @@ void S9xFinalizeSamples (void)
{ {
/* We weren't able to process the entire buffer. Potential overrun. */ /* We weren't able to process the entire buffer. Potential overrun. */
spc::sound_in_sync = FALSE; spc::sound_in_sync = FALSE;
S9xIncreaseDynamicRateMultiplier();
if (Settings.SoundSync && !Settings.TurboMode) if (Settings.SoundSync && !Settings.TurboMode)
return; return;
@ -428,8 +451,14 @@ void S9xFinalizeSamples (void)
else else
if (spc::resampler->space_empty() >= spc::resampler->space_filled()) if (spc::resampler->space_empty() >= spc::resampler->space_filled())
spc::sound_in_sync = TRUE; spc::sound_in_sync = TRUE;
else else {
S9xIncreaseDynamicRateMultiplier ();
spc::sound_in_sync = FALSE; spc::sound_in_sync = FALSE;
}
if(spc::sound_in_sync) {
S9xResetDynamicRateMultiplier ();
}
spc_core->set_output((SNES_SPC::sample_t *) spc::landing_buffer, spc::buffer_size >> 1); spc_core->set_output((SNES_SPC::sample_t *) spc::landing_buffer, spc::buffer_size >> 1);
} }
@ -472,11 +501,20 @@ void UpdatePlaybackRate (void)
Settings.SoundInputRate = APU_DEFAULT_INPUT_RATE; Settings.SoundInputRate = APU_DEFAULT_INPUT_RATE;
double time_ratio = (double) Settings.SoundInputRate * spc::timing_hack_numerator / (Settings.SoundPlaybackRate * spc::timing_hack_denominator); double time_ratio = (double) Settings.SoundInputRate * spc::timing_hack_numerator / (Settings.SoundPlaybackRate * spc::timing_hack_denominator);
if (Settings.DynamicRateControl)
{
time_ratio *= spc::dynamic_rate_multiplier;
}
spc::resampler->time_ratio(time_ratio); spc::resampler->time_ratio(time_ratio);
if (Settings.MSU1)
{
time_ratio = (44100.0 / Settings.SoundPlaybackRate) * (Settings.SoundInputRate / 32040.0); time_ratio = (44100.0 / Settings.SoundPlaybackRate) * (Settings.SoundInputRate / 32040.0);
msu::resampler->time_ratio(time_ratio); msu::resampler->time_ratio(time_ratio);
} }
}
bool8 S9xInitSound (int buffer_ms, int lag_ms) bool8 S9xInitSound (int buffer_ms, int lag_ms)
{ {
@ -712,6 +750,8 @@ void S9xResetAPU (void)
spc_core->set_output((SNES_SPC::sample_t *) spc::landing_buffer, spc::buffer_size >> 1); spc_core->set_output((SNES_SPC::sample_t *) spc::landing_buffer, spc::buffer_size >> 1);
spc::resampler->clear(); spc::resampler->clear();
if (Settings.MSU1)
msu::resampler->clear(); msu::resampler->clear();
} }
@ -723,6 +763,8 @@ void S9xSoftResetAPU (void)
spc_core->set_output((SNES_SPC::sample_t *) spc::landing_buffer, spc::buffer_size >> 1); spc_core->set_output((SNES_SPC::sample_t *) spc::landing_buffer, spc::buffer_size >> 1);
spc::resampler->clear(); spc::resampler->clear();
if (Settings.MSU1)
msu::resampler->clear(); msu::resampler->clear();
} }

View File

@ -423,6 +423,7 @@ struct SSettings
bool8 Stereo; bool8 Stereo;
bool8 ReverseStereo; bool8 ReverseStereo;
bool8 Mute; bool8 Mute;
bool8 DynamicRateControl;
bool8 SupportHiRes; bool8 SupportHiRes;
bool8 Transparency; bool8 Transparency;

View File

@ -638,7 +638,7 @@ ResetVideo_Emu ()
else else
ResetFbWidth(512, rmode); ResetFbWidth(512, rmode);
Settings.SoundInputRate = 31953; Settings.SoundInputRate = 32000;
UpdatePlaybackRate(); UpdatePlaybackRate();
} }