libsidplayfp  1.8.7
Filter8580.h
1 /*
2  * This file is part of libsidplayfp, a SID player engine.
3  *
4  * Copyright 2011-2014 Leandro Nini <drfiemost@users.sourceforge.net>
5  * Copyright 2007-2010 Antti Lankila
6  * Copyright 2004,2010 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 <cmath>
27 #include <cstring>
28 
29 #include <stdint.h>
30 
31 #include "siddefs-fp.h"
32 
33 #include "Filter.h"
34 
35 namespace reSIDfp
36 {
37 
48 {
49 private:
50  uint32_t rand_state;
51 
52 private:
56  static inline float reduce(uint32_t val)
57  {
58  // FIXME may not be fully portable
59  // This code assumes IEEE-754 floating point representation
60  // and same endianness for integers and floats
61  const uint32_t mantissa = val & 0x807F0000; // Keep only most significant bits
62  const uint32_t flt_rnd = mantissa | 0x1E000000; // Set exponent
63  float temp;
64  memcpy(&temp, &flt_rnd, sizeof(float));
65  return temp;
66  }
67 
68 public:
70  rand_state(1) {}
71 
72  inline float get()
73  {
74  // LCG from Numerical Recipes
75  rand_state = rand_state * 1664525 + 1013904223;
76 
77  return reduce(rand_state);
78  }
79 };
80 
85 class Filter8580 : public Filter
86 {
87 private:
89  double highFreq;
90 
92  float Vlp;
93 
95  float Vbp;
96 
98  float Vhp;
99 
100  float w0;
101 
103  float _1_div_Q;
104 
106  int ve;
107 
108  antiDenormalNoise noise;
109 
110 public:
111  Filter8580() :
112  highFreq(12500.),
113  Vlp(0.f),
114  Vbp(0.f),
115  Vhp(0.f),
116  w0(0.f),
117  _1_div_Q(0.f),
118  ve(0) {}
119 
120  int clock(int voice1, int voice2, int voice3);
121 
125  void updatedCenterFrequency() { w0 = static_cast<float>(2. * M_PI * highFreq * fc / 2047. / 1e6); }
126 
134  void updatedResonance() { _1_div_Q = static_cast<float>(pow(2., (4 - res) / 8.)); }
135 
136  void input(int input) { ve = input << 4; }
137 
138  void updatedMixing() {}
139 
145  void setFilterCurve(double curvePosition) { highFreq = curvePosition; }
146 };
147 
148 } // namespace reSIDfp
149 
150 #if RESID_INLINING || defined(FILTER8580_CPP)
151 
152 #include <cassert>
153 
154 namespace reSIDfp
155 {
156 
157 RESID_INLINE
158 int Filter8580::clock(int voice1, int voice2, int voice3)
159 {
160  voice1 >>= 7;
161  voice2 >>= 7;
162  voice3 >>= 7;
163 
164  int Vi = 0;
165  int Vo = 0;
166 
167  (filt1 ? Vi : Vo) += voice1;
168 
169  (filt2 ? Vi : Vo) += voice2;
170 
171  // NB! Voice 3 is not silenced by voice3off if it is routed
172  // through the filter.
173  if (filt3) Vi += voice3;
174  else if (!voice3off) Vo += voice3;
175 
176  (filtE ? Vi : Vo) += ve;
177 
178  Vlp -= w0 * Vbp;
179  Vbp -= w0 * Vhp;
180  Vhp = (Vbp * _1_div_Q) - Vlp - Vi + noise.get();
181 
182  assert(std::fpclassify(Vlp) != FP_SUBNORMAL);
183  assert(std::fpclassify(Vbp) != FP_SUBNORMAL);
184  assert(std::fpclassify(Vhp) != FP_SUBNORMAL);
185 
186  float Vof = static_cast<float>(Vo);
187 
188  if (lp)
189  {
190  Vof += Vlp;
191  }
192 
193  if (bp)
194  {
195  Vof += Vbp;
196  }
197 
198  if (hp)
199  {
200  Vof += Vhp;
201  }
202 
203  return static_cast<int>(Vof) * vol >> 4;
204 }
205 
206 } // namespace reSIDfp
207 
208 #endif
209 
210 #endif
Definition: Filter8580.h:85
Definition: Filter8580.h:47
Definition: Dac.cpp:25
void setFilterCurve(double curvePosition)
Definition: Filter8580.h:145
void updatedResonance()
Definition: Filter8580.h:134
void updatedCenterFrequency()
Definition: Filter8580.h:125
int clock(int voice1, int voice2, int voice3)
Definition: Filter8580.h:158
void updatedMixing()
Definition: Filter8580.h:138
Definition: Filter.h:32