mirror of
https://github.com/dborth/snes9xgx.git
synced 2024-11-24 03:29:22 +01:00
fix sound crackling
This commit is contained in:
parent
395f9069ef
commit
7da04d7d01
@ -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;
|
||||||
|
@ -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)
|
||||||
|
@ -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++ )
|
||||||
|
@ -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,7 +330,9 @@ 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();
|
||||||
msu::resampler->clear();
|
|
||||||
|
if(Settings.MSU1)
|
||||||
|
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,10 +501,19 @@ 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);
|
||||||
|
|
||||||
time_ratio = (44100.0 / Settings.SoundPlaybackRate) * (Settings.SoundInputRate / 32040.0);
|
if (Settings.MSU1)
|
||||||
msu::resampler->time_ratio(time_ratio);
|
{
|
||||||
|
time_ratio = (44100.0 / Settings.SoundPlaybackRate) * (Settings.SoundInputRate / 32040.0);
|
||||||
|
msu::resampler->time_ratio(time_ratio);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool8 S9xInitSound (int buffer_ms, int lag_ms)
|
bool8 S9xInitSound (int buffer_ms, int lag_ms)
|
||||||
@ -712,7 +750,9 @@ 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();
|
||||||
msu::resampler->clear();
|
|
||||||
|
if (Settings.MSU1)
|
||||||
|
msu::resampler->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xSoftResetAPU (void)
|
void S9xSoftResetAPU (void)
|
||||||
@ -723,7 +763,9 @@ 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();
|
||||||
msu::resampler->clear();
|
|
||||||
|
if (Settings.MSU1)
|
||||||
|
msu::resampler->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void from_apu_to_state (uint8 **buf, void *var, size_t size)
|
static void from_apu_to_state (uint8 **buf, void *var, size_t size)
|
||||||
|
@ -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;
|
||||||
|
@ -638,7 +638,7 @@ ResetVideo_Emu ()
|
|||||||
else
|
else
|
||||||
ResetFbWidth(512, rmode);
|
ResetFbWidth(512, rmode);
|
||||||
|
|
||||||
Settings.SoundInputRate = 31953;
|
Settings.SoundInputRate = 32000;
|
||||||
UpdatePlaybackRate();
|
UpdatePlaybackRate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user