diff snes_spc/SPC_Filter.cpp @ 0:e38dacceb958

initial import
author Robert McIntyre <rlm@mit.edu>
date Fri, 21 Oct 2011 05:53:11 -0700
parents
children
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/snes_spc/SPC_Filter.cpp	Fri Oct 21 05:53:11 2011 -0700
     1.3 @@ -0,0 +1,68 @@
     1.4 +// snes_spc 0.9.0. http://www.slack.net/~ant/
     1.5 +
     1.6 +#include "SPC_Filter.h"
     1.7 +
     1.8 +#include <string.h>
     1.9 +
    1.10 +/* Copyright (C) 2007 Shay Green. This module is free software; you
    1.11 +can redistribute it and/or modify it under the terms of the GNU Lesser
    1.12 +General Public License as published by the Free Software Foundation; either
    1.13 +version 2.1 of the License, or (at your option) any later version. This
    1.14 +module is distributed in the hope that it will be useful, but WITHOUT ANY
    1.15 +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    1.16 +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
    1.17 +details. You should have received a copy of the GNU Lesser General Public
    1.18 +License along with this module; if not, write to the Free Software Foundation,
    1.19 +Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
    1.20 +
    1.21 +#include "blargg_source.h"
    1.22 +
    1.23 +void SPC_Filter::clear() { memset( ch, 0, sizeof ch ); }
    1.24 +
    1.25 +SPC_Filter::SPC_Filter()
    1.26 +{
    1.27 +	gain = gain_unit;
    1.28 +	bass = bass_norm;
    1.29 +	clear();
    1.30 +}
    1.31 +
    1.32 +void SPC_Filter::run( short* io, int count )
    1.33 +{
    1.34 +	require( (count & 1) == 0 ); // must be even
    1.35 +	
    1.36 +	int const gain = this->gain;
    1.37 +	int const bass = this->bass;
    1.38 +	chan_t* c = &ch [2];
    1.39 +	do
    1.40 +	{
    1.41 +		// cache in registers
    1.42 +		int sum = (--c)->sum;
    1.43 +		int pp1 = c->pp1;
    1.44 +		int p1  = c->p1;
    1.45 +		
    1.46 +		for ( int i = 0; i < count; i += 2 )
    1.47 +		{
    1.48 +			// Low-pass filter (two point FIR with coeffs 0.25, 0.75)
    1.49 +			int f = io [i] + p1;
    1.50 +			p1 = io [i] * 3;
    1.51 +			
    1.52 +			// High-pass filter ("leaky integrator")
    1.53 +			int delta = f - pp1;
    1.54 +			pp1 = f;
    1.55 +			int s = sum >> (gain_bits + 2);
    1.56 +			sum += (delta * gain) - (sum >> bass);
    1.57 +			
    1.58 +			// Clamp to 16 bits
    1.59 +			if ( (short) s != s )
    1.60 +				s = (s >> 31) ^ 0x7FFF;
    1.61 +			
    1.62 +			io [i] = (short) s;
    1.63 +		}
    1.64 +		
    1.65 +		c->p1  = p1;
    1.66 +		c->pp1 = pp1;
    1.67 +		c->sum = sum;
    1.68 +		++io;
    1.69 +	}
    1.70 +	while ( c != ch );
    1.71 +}