From 7da04d7d01b305c6c03bdfb27b93f5f7545a6bba Mon Sep 17 00:00:00 2001 From: Daryl Borth Date: Tue, 14 Aug 2018 11:00:45 -0600 Subject: [PATCH] fix sound crackling --- source/preferences.cpp | 5 +-- source/s9xsupport.cpp | 6 +--- source/snes9x/apu/SNES_SPC.cpp | 7 ++-- source/snes9x/apu/apu.cpp | 60 +++++++++++++++++++++++++++++----- source/snes9x/snes9x.h | 1 + source/video.cpp | 2 +- 6 files changed, 60 insertions(+), 21 deletions(-) diff --git a/source/preferences.cpp b/source/preferences.cpp index 201bfb4..12132ff 100644 --- a/source/preferences.cpp +++ b/source/preferences.cpp @@ -478,12 +478,13 @@ DefaultSettings () Settings.HDMATimingHack = 100; // Sound defaults. On Wii this is 32Khz/16bit/Stereo - //Settings.SoundSync = true; + Settings.SoundSync = true; Settings.SixteenBitSound = true; Settings.Stereo = true; Settings.ReverseStereo = true; Settings.SoundPlaybackRate = 32040; - Settings.SoundInputRate = 32040; + Settings.SoundInputRate = 32000; + Settings.DynamicRateControl = true; // Graphics Settings.Transparency = true; diff --git a/source/s9xsupport.cpp b/source/s9xsupport.cpp index c6d1548..f9bfc3d 100644 --- a/source/s9xsupport.cpp +++ b/source/s9xsupport.cpp @@ -85,11 +85,7 @@ void S9xInitSync() /*** Synchronisation ***/ -void S9xSyncSpeed () -{ - while (!S9xSyncSound()) - usleep(10); - +void S9xSyncSpeed () { uint32 skipFrms = Settings.SkipFrames; if (Settings.TurboMode) diff --git a/source/snes9x/apu/SNES_SPC.cpp b/source/snes9x/apu/SNES_SPC.cpp index 567b7dd..9e82b83 100644 --- a/source/snes9x/apu/SNES_SPC.cpp +++ b/source/snes9x/apu/SNES_SPC.cpp @@ -131,7 +131,6 @@ void SNES_SPC::enable_rom( int enable ) int count = (time) - m.dsp_time;\ if ( !SPC_MORE_ACCURACY || count )\ {\ - assert( count > 0 );\ m.dsp_time = (time);\ dsp.run( count );\ }\ @@ -402,7 +401,7 @@ void SNES_SPC::cpu_write_high( int data, int i, rel_time_t time ) } 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 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% { - assert( reg + (r_t0out + 0xF0 - 0x10000) < 0x100 ); + //assert( reg + (r_t0out + 0xF0 - 0x10000) < 0x100 ); 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 // not being able to execute current instruction without going over // 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 for ( int i = 0; i < timer_count; i++ ) diff --git a/source/snes9x/apu/apu.cpp b/source/snes9x/apu/apu.cpp index 25b8814..fb5258a 100644 --- a/source/snes9x/apu/apu.cpp +++ b/source/snes9x/apu/apu.cpp @@ -237,8 +237,10 @@ namespace spc if necessary on game load. */ static uint32 ratio_numerator = APU_NUMERATOR_NTSC; static uint32 ratio_denominator = APU_DENOMINATOR_NTSC; + + static double dynamic_rate_multiplier = 1.0; } - + namespace msu { static int buffer_size; @@ -273,7 +275,7 @@ static void DeStereo (uint8 *buffer, int sample_count) int16 *buf = (int16 *) buffer; 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]; s2 = (int32) buf[2 * i + 1]; @@ -328,7 +330,9 @@ bool8 S9xMixSamples (uint8 *buffer, int sample_count) { memset(dest, 0, sample_count << 1); spc::resampler->clear(); - msu::resampler->clear(); + + if(Settings.MSU1) + msu::resampler->clear(); return (FALSE); } @@ -387,6 +391,24 @@ int S9xGetSampleCount (void) 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) { bool drop_current_msu1_samples = TRUE; @@ -399,7 +421,8 @@ void S9xFinalizeSamples (void) { /* We weren't able to process the entire buffer. Potential overrun. */ spc::sound_in_sync = FALSE; - + S9xIncreaseDynamicRateMultiplier(); + if (Settings.SoundSync && !Settings.TurboMode) return; @@ -428,8 +451,14 @@ void S9xFinalizeSamples (void) else if (spc::resampler->space_empty() >= spc::resampler->space_filled()) spc::sound_in_sync = TRUE; - else + else { + S9xIncreaseDynamicRateMultiplier (); 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); } @@ -472,10 +501,19 @@ void UpdatePlaybackRate (void) Settings.SoundInputRate = APU_DEFAULT_INPUT_RATE; 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); - time_ratio = (44100.0 / Settings.SoundPlaybackRate) * (Settings.SoundInputRate / 32040.0); - msu::resampler->time_ratio(time_ratio); + if (Settings.MSU1) + { + time_ratio = (44100.0 / Settings.SoundPlaybackRate) * (Settings.SoundInputRate / 32040.0); + msu::resampler->time_ratio(time_ratio); + } } 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::resampler->clear(); - msu::resampler->clear(); + + if (Settings.MSU1) + msu::resampler->clear(); } 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::resampler->clear(); - msu::resampler->clear(); + + if (Settings.MSU1) + msu::resampler->clear(); } static void from_apu_to_state (uint8 **buf, void *var, size_t size) diff --git a/source/snes9x/snes9x.h b/source/snes9x/snes9x.h index d9118ad..6a2dfbf 100644 --- a/source/snes9x/snes9x.h +++ b/source/snes9x/snes9x.h @@ -423,6 +423,7 @@ struct SSettings bool8 Stereo; bool8 ReverseStereo; bool8 Mute; + bool8 DynamicRateControl; bool8 SupportHiRes; bool8 Transparency; diff --git a/source/video.cpp b/source/video.cpp index 70b86b8..c9a8665 100644 --- a/source/video.cpp +++ b/source/video.cpp @@ -638,7 +638,7 @@ ResetVideo_Emu () else ResetFbWidth(512, rmode); - Settings.SoundInputRate = 31953; + Settings.SoundInputRate = 32000; UpdatePlaybackRate(); }