diff --git a/Frameworks/GME/gme/Spc_Emu.cpp b/Frameworks/GME/gme/Spc_Emu.cpp index 662c17e18..dd193b9c6 100644 --- a/Frameworks/GME/gme/Spc_Emu.cpp +++ b/Frameworks/GME/gme/Spc_Emu.cpp @@ -22,7 +22,7 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ Spc_Emu::Spc_Emu() { set_type( gme_spc_type ); - set_gain( 1.0 ); + set_gain( 1.4 ); } Spc_Emu::~Spc_Emu() { } diff --git a/Frameworks/GME/gme/Spc_Filter.cpp b/Frameworks/GME/gme/Spc_Filter.cpp index 746af8ccd..c4e56a19b 100644 --- a/Frameworks/GME/gme/Spc_Filter.cpp +++ b/Frameworks/GME/gme/Spc_Filter.cpp @@ -15,6 +15,21 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "blargg_source.h" +static const float limiter_max = (float)0.9999; +static const float limiter_max_05 = (float)(limiter_max - 0.5); + +#include + +static short hard_limit_sample( int sample ) +{ + double val = (double)sample * (1.0 / 32768.0); + if (val < -0.5) + val = (tanh((val + 0.5) / limiter_max_05) * limiter_max_05 - 0.5); + else if (val > 0.5) + val = (tanh((val - 0.5) / limiter_max_05) * limiter_max_05 + 0.5); + return val * 32768.0; +} + void Spc_Filter::clear() { memset( ch, 0, sizeof ch ); } Spc_Filter::Spc_Filter() @@ -52,12 +67,8 @@ void Spc_Filter::run( short io [], int count ) pp1 = f; int s = sum >> (gain_bits + 2); sum += (delta * gain) - (sum >> bass); - - // Clamp to 16 bits - if ( (short) s != s ) - s = (s >> 31) ^ 0x7FFF; - - io [i] = (short) s; + + io [i] = hard_limit_sample( s ); } c->p1 = p1; @@ -73,9 +84,7 @@ void Spc_Filter::run( short io [], int count ) while ( io < end ) { int s = (*io * gain) >> gain_bits; - if ( (short) s != s ) - s = (s >> 31) ^ 0x7FFF; - *io++ = (short) s; + *io++ = hard_limit_sample( s ); } } } diff --git a/Frameworks/GME/gme/Spc_Sfm.cpp b/Frameworks/GME/gme/Spc_Sfm.cpp index 4e0016666..8912782f6 100644 --- a/Frameworks/GME/gme/Spc_Sfm.cpp +++ b/Frameworks/GME/gme/Spc_Sfm.cpp @@ -24,7 +24,7 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ Sfm_Emu::Sfm_Emu() { set_type( gme_sfm_type ); - set_gain( 1.0 ); + set_gain( 1.4 ); set_max_initial_silence( 30 ); set_silence_lookahead( 30 ); // Some SFMs may have a lot of initialization code }