libsidplayfp  1.0.1
Filter8580.h
1 /*
2  * This file is part of libsidplayfp, a SID player engine.
3  *
4  * Copyright 2011-2013 Leandro Nini <drfiemost@users.sourceforge.net>
5  * Copyright 2007-2010 Antti Lankila
6  * Copyright 2004 Dag Lem <resid@nimrod.no>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21  */
22 
23 #ifndef FILTER8580_H
24 #define FILTER8580_H
25 
26 #include "siddefs-fp.h"
27 
28 #include "Filter.h"
29 
30 namespace reSIDfp
31 {
32 
46 class Filter8580 : public Filter
47 {
48 private:
49  double highFreq;
50  float Vlp, Vbp, Vhp;
51  float ve, w0, _1_div_Q;
52 
53 public:
54  Filter8580() :
55  highFreq(12500.),
56  Vlp(0.f),
57  Vbp(0.f),
58  Vhp(0.f),
59  ve(0.f),
60  w0(0.f),
61  _1_div_Q(0.f) {}
62 
63  int clock(int voice1, int voice2, int voice3);
64 
65  void updatedCenterFrequency() { w0 = (float)(2.*M_PI * highFreq * fc / 2047 / 1e6); }
66 
67  void updatedResonance() { _1_div_Q = 1.f / (0.707f + res / 15.f); }
68 
69  void input(int input) { ve = input << 4; }
70 
71  void updatedMixing() {}
72 
73  void setFilterCurve(double curvePosition) { highFreq = curvePosition; }
74 };
75 
76 } // namespace reSIDfp
77 
78 #if RESID_INLINING || defined(FILTER8580_CPP)
79 
80 #include <stdlib.h>
81 #include <math.h>
82 
83 namespace reSIDfp
84 {
85 
86 RESID_INLINE
87 int Filter8580::clock(int voice1, int voice2, int voice3)
88 {
89  voice1 >>= 7;
90  voice2 >>= 7;
91  voice3 >>= 7;
92 
93  int Vi = 0;
94  float Vo = 0.f;
95 
96  if (filt1)
97  {
98  Vi += voice1;
99  }
100  else
101  {
102  Vo += voice1;
103  }
104 
105  if (filt2)
106  {
107  Vi += voice2;
108  }
109  else
110  {
111  Vo += voice2;
112  }
113 
114  // NB! Voice 3 is not silenced by voice3off if it is routed
115  // through the filter.
116  if (filt3)
117  {
118  Vi += voice3;
119  }
120  else if (!voice3off)
121  {
122  Vo += voice3;
123  }
124 
125  if (filtE)
126  {
127  Vi += (int)ve;
128  }
129  else
130  {
131  Vo += ve;
132  }
133 
134  const float dVbp = w0 * Vhp;
135  const float dVlp = w0 * Vbp;
136  Vbp -= dVbp;
137  Vlp -= dVlp;
138  Vhp = (Vbp * _1_div_Q) - Vlp - Vi + float(rand()) / float(RAND_MAX);
139 
140  if (lp)
141  {
142  Vo += Vlp;
143  }
144 
145  if (bp)
146  {
147  Vo += Vbp;
148  }
149 
150  if (hp)
151  {
152  Vo += Vhp;
153  }
154 
155  return (int) Vo * vol >> 4;
156 }
157 
158 } // namespace reSIDfp
159 
160 #endif
161 
162 #endif