libsidplayfp 1.8.8
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
35namespace reSIDfp
36{
37
48{
49private:
50 uint32_t rand_state;
51
52private:
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
68public:
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
85class Filter8580 : public Filter
86{
87private:
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
110public:
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
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
154namespace reSIDfp
155{
156
157RESID_INLINE
158int 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:86
int clock(int voice1, int voice2, int voice3)
Definition: Filter8580.h:158
void setFilterCurve(double curvePosition)
Definition: Filter8580.h:145
void updatedResonance()
Definition: Filter8580.h:134
void updatedMixing()
Definition: Filter8580.h:138
void updatedCenterFrequency()
Definition: Filter8580.h:125
Definition: Filter.h:33
bool hp
Highpass, bandpass, and lowpass filter modes.
Definition: Filter.h:51
bool voice3off
Switch voice 3 off.
Definition: Filter.h:48
bool filt1
Routing to filter or outside filter.
Definition: Filter.h:45
unsigned char vol
Current volume.
Definition: Filter.h:42
unsigned char res
Filter resonance.
Definition: Filter.h:39
unsigned int fc
Filter cutoff frequency.
Definition: Filter.h:36
Definition: Filter8580.h:48