rlm@0
|
1 // snes_spc 0.9.0. http://www.slack.net/~ant/
|
rlm@0
|
2
|
rlm@0
|
3 #include "SPC_Filter.h"
|
rlm@0
|
4
|
rlm@0
|
5 #include <string.h>
|
rlm@0
|
6
|
rlm@0
|
7 /* Copyright (C) 2007 Shay Green. This module is free software; you
|
rlm@0
|
8 can redistribute it and/or modify it under the terms of the GNU Lesser
|
rlm@0
|
9 General Public License as published by the Free Software Foundation; either
|
rlm@0
|
10 version 2.1 of the License, or (at your option) any later version. This
|
rlm@0
|
11 module is distributed in the hope that it will be useful, but WITHOUT ANY
|
rlm@0
|
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
rlm@0
|
13 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
rlm@0
|
14 details. You should have received a copy of the GNU Lesser General Public
|
rlm@0
|
15 License along with this module; if not, write to the Free Software Foundation,
|
rlm@0
|
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
rlm@0
|
17
|
rlm@0
|
18 #include "blargg_source.h"
|
rlm@0
|
19
|
rlm@0
|
20 void SPC_Filter::clear() { memset( ch, 0, sizeof ch ); }
|
rlm@0
|
21
|
rlm@0
|
22 SPC_Filter::SPC_Filter()
|
rlm@0
|
23 {
|
rlm@0
|
24 gain = gain_unit;
|
rlm@0
|
25 bass = bass_norm;
|
rlm@0
|
26 clear();
|
rlm@0
|
27 }
|
rlm@0
|
28
|
rlm@0
|
29 void SPC_Filter::run( short* io, int count )
|
rlm@0
|
30 {
|
rlm@0
|
31 require( (count & 1) == 0 ); // must be even
|
rlm@0
|
32
|
rlm@0
|
33 int const gain = this->gain;
|
rlm@0
|
34 int const bass = this->bass;
|
rlm@0
|
35 chan_t* c = &ch [2];
|
rlm@0
|
36 do
|
rlm@0
|
37 {
|
rlm@0
|
38 // cache in registers
|
rlm@0
|
39 int sum = (--c)->sum;
|
rlm@0
|
40 int pp1 = c->pp1;
|
rlm@0
|
41 int p1 = c->p1;
|
rlm@0
|
42
|
rlm@0
|
43 for ( int i = 0; i < count; i += 2 )
|
rlm@0
|
44 {
|
rlm@0
|
45 // Low-pass filter (two point FIR with coeffs 0.25, 0.75)
|
rlm@0
|
46 int f = io [i] + p1;
|
rlm@0
|
47 p1 = io [i] * 3;
|
rlm@0
|
48
|
rlm@0
|
49 // High-pass filter ("leaky integrator")
|
rlm@0
|
50 int delta = f - pp1;
|
rlm@0
|
51 pp1 = f;
|
rlm@0
|
52 int s = sum >> (gain_bits + 2);
|
rlm@0
|
53 sum += (delta * gain) - (sum >> bass);
|
rlm@0
|
54
|
rlm@0
|
55 // Clamp to 16 bits
|
rlm@0
|
56 if ( (short) s != s )
|
rlm@0
|
57 s = (s >> 31) ^ 0x7FFF;
|
rlm@0
|
58
|
rlm@0
|
59 io [i] = (short) s;
|
rlm@0
|
60 }
|
rlm@0
|
61
|
rlm@0
|
62 c->p1 = p1;
|
rlm@0
|
63 c->pp1 = pp1;
|
rlm@0
|
64 c->sum = sum;
|
rlm@0
|
65 ++io;
|
rlm@0
|
66 }
|
rlm@0
|
67 while ( c != ch );
|
rlm@0
|
68 }
|