Added a hard limiter to SPC playback instead

CQTexperiment
Chris Moeller 2013-10-30 17:58:29 -07:00
parent a02bc5000b
commit 2cfdacf890
3 changed files with 20 additions and 11 deletions

View File

@ -22,7 +22,7 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
Spc_Emu::Spc_Emu() Spc_Emu::Spc_Emu()
{ {
set_type( gme_spc_type ); set_type( gme_spc_type );
set_gain( 1.0 ); set_gain( 1.4 );
} }
Spc_Emu::~Spc_Emu() { } Spc_Emu::~Spc_Emu() { }

View File

@ -15,6 +15,21 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
#include "blargg_source.h" #include "blargg_source.h"
static const float limiter_max = (float)0.9999;
static const float limiter_max_05 = (float)(limiter_max - 0.5);
#include <math.h>
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 ); } void Spc_Filter::clear() { memset( ch, 0, sizeof ch ); }
Spc_Filter::Spc_Filter() Spc_Filter::Spc_Filter()
@ -52,12 +67,8 @@ void Spc_Filter::run( short io [], int count )
pp1 = f; pp1 = f;
int s = sum >> (gain_bits + 2); int s = sum >> (gain_bits + 2);
sum += (delta * gain) - (sum >> bass); sum += (delta * gain) - (sum >> bass);
// Clamp to 16 bits io [i] = hard_limit_sample( s );
if ( (short) s != s )
s = (s >> 31) ^ 0x7FFF;
io [i] = (short) s;
} }
c->p1 = p1; c->p1 = p1;
@ -73,9 +84,7 @@ void Spc_Filter::run( short io [], int count )
while ( io < end ) while ( io < end )
{ {
int s = (*io * gain) >> gain_bits; int s = (*io * gain) >> gain_bits;
if ( (short) s != s ) *io++ = hard_limit_sample( s );
s = (s >> 31) ^ 0x7FFF;
*io++ = (short) s;
} }
} }
} }

View File

@ -24,7 +24,7 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
Sfm_Emu::Sfm_Emu() Sfm_Emu::Sfm_Emu()
{ {
set_type( gme_sfm_type ); set_type( gme_sfm_type );
set_gain( 1.0 ); set_gain( 1.4 );
set_max_initial_silence( 30 ); set_max_initial_silence( 30 );
set_silence_lookahead( 30 ); // Some SFMs may have a lot of initialization code set_silence_lookahead( 30 ); // Some SFMs may have a lot of initialization code
} }