Mercurial > spc_convert
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 +}