libsidplayfp  1.3.0
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 public:
54  rand_state(1) {}
55 
56  inline float get()
57  {
58  // FIXME
59  // This code assumes IEEE-754 floating point representation
60  // and same endianness for integers and floats
61  rand_state = rand_state * 1234567UL + 890123UL;
62  const uint32_t mantissa = rand_state & 0x807F0000; // Keep only most significant bits
63  const uint32_t flt_rnd = mantissa | 0x1E000000; // Set exponent
64  float temp;
65  memcpy(&temp, &flt_rnd, sizeof(float));
66  return temp;
67  }
68 };
69 
74 class Filter8580 : public Filter
75 {
76 private:
77  double highFreq;
78  float Vlp, Vbp, Vhp;
79  float w0, _1_div_Q;
80  int ve;
81 
82  antiDenormalNoise noise;
83 
84 public:
85  Filter8580() :
86  highFreq(12500.),
87  Vlp(0.f),
88  Vbp(0.f),
89  Vhp(0.f),
90  w0(0.f),
91  _1_div_Q(0.f),
92  ve(0) {}
93 
94  int clock(int voice1, int voice2, int voice3);
95 
99  void updatedCenterFrequency() { w0 = (float)(2. * M_PI * highFreq * fc / 2047. / 1e6); }
100 
108  void updatedResonance() { _1_div_Q = (float)pow(2., (4 - res) / 8.); }
109 
110  void input(int input) { ve = input << 4; }
111 
112  void updatedMixing() {}
113 
119  void setFilterCurve(double curvePosition) { highFreq = curvePosition; }
120 };
121 
122 } // namespace reSIDfp
123 
124 #if RESID_INLINING || defined(FILTER8580_CPP)
125 
126 #include <cassert>
127 
128 namespace reSIDfp
129 {
130 
131 RESID_INLINE
132 int Filter8580::clock(int voice1, int voice2, int voice3)
133 {
134  voice1 >>= 7;
135  voice2 >>= 7;
136  voice3 >>= 7;
137 
138  int Vi = 0;
139  int Vo = 0;
140 
141  (filt1 ? Vi : Vo) += voice1;
142 
143  (filt2 ? Vi : Vo) += voice2;
144 
145  // NB! Voice 3 is not silenced by voice3off if it is routed
146  // through the filter.
147  if (filt3)
148  {
149  Vi += voice3;
150  }
151  else if (!voice3off)
152  {
153  Vo += voice3;
154  }
155 
156  (filtE ? Vi : Vo) += ve;
157 
158  Vlp -= w0 * Vbp;
159  Vbp -= w0 * Vhp;
160  Vhp = (Vbp * _1_div_Q) - Vlp - Vi + noise.get();
161 
162  assert(std::fpclassify(Vlp) != FP_SUBNORMAL);
163  assert(std::fpclassify(Vbp) != FP_SUBNORMAL);
164  assert(std::fpclassify(Vhp) != FP_SUBNORMAL);
165 
166  float Vof = (float)Vo;
167 
168  if (lp)
169  {
170  Vof += Vlp;
171  }
172 
173  if (bp)
174  {
175  Vof += Vbp;
176  }
177 
178  if (hp)
179  {
180  Vof += Vhp;
181  }
182 
183  return (int) Vof * vol >> 4;
184 }
185 
186 } // namespace reSIDfp
187 
188 #endif
189 
190 #endif
Definition: Filter8580.h:74
bool hp
Highpass, bandpass, and lowpass filter modes.
Definition: Filter.h:61
bool filt1
Routing to filter or outside filter.
Definition: Filter.h:55
Definition: Filter8580.h:47
void setFilterCurve(double curvePosition)
Definition: Filter8580.h:119
bool voice3off
Switch voice 3 off.
Definition: Filter.h:58
int vol
Current volume.
Definition: Filter.h:52
void updatedResonance()
Definition: Filter8580.h:108
void updatedCenterFrequency()
Definition: Filter8580.h:99
int res
Filter resonance.
Definition: Filter.h:49
int clock(int voice1, int voice2, int voice3)
Definition: Filter8580.h:132
void updatedMixing()
Definition: Filter8580.h:112
Definition: Filter.h:32
int fc
Filter cutoff frequency.
Definition: Filter.h:46