libsidplayfp 2.9.0
FilterModelConfig.h
1/*
2 * This file is part of libsidplayfp, a SID player engine.
3 *
4 * Copyright 2011-2024 Leandro Nini <drfiemost@users.sourceforge.net>
5 * Copyright 2007-2010 Antti Lankila
6 * Copyright 2004,2010 Dag Lem
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 FILTERMODELCONFIG_H
24#define FILTERMODELCONFIG_H
25
26#include <algorithm>
27#include <cassert>
28
29#include "OpAmp.h"
30#include "Spline.h"
31
32#include "sidcxx11.h"
33
34namespace reSIDfp
35{
36
37class Integrator;
38
40{
41protected:
43 const double C;
44
46
47
48 static constexpr double Ut = 26.0e-3;
49
50 const double Vdd;
51 const double Vth;
52 const double Vddt;
53 double uCox;
55
56 // Derived stuff
57 const double vmin, vmax;
58 const double denorm, norm;
59
61 const double N16;
62
63 const double voice_voltage_range;
64 const double voice_DC_voltage;
65
68
70
71 unsigned short* mixer[8]; //-V730_NOINIT this is initialized in the derived class constructor
72 unsigned short* summer[5]; //-V730_NOINIT this is initialized in the derived class constructor
73 unsigned short* volume[16]; //-V730_NOINIT this is initialized in the derived class constructor
74 unsigned short* resonance[16]; //-V730_NOINIT this is initialized in the derived class constructor
76
78 unsigned short opamp_rev[1 << 16]; //-V730_NOINIT this is initialized in the derived class constructor
79
80private:
81 FilterModelConfig(const FilterModelConfig&) = delete;
82 FilterModelConfig& operator= (const FilterModelConfig&) = delete;
83
84 inline double getVoiceVoltage(float value) const
85 {
86 return value * voice_voltage_range + voice_DC_voltage;
87 }
88
89protected:
101 double vvr,
102 double vdv,
103 double c,
104 double vdd,
105 double vth,
106 double ucox,
107 const Spline::Point *opamp_voltage,
108 int opamp_size
109 );
110
112
113 void setUCox(double new_uCox);
114
124 inline void buildSummerTable(const OpAmp& opampModel)
125 {
126 const double r_N16 = 1. / N16;
127
128 for (int i = 0; i < 5; i++)
129 {
130 const int idiv = 2 + i; // 2 - 6 input "resistors".
131 const int size = idiv << 16;
132 const double n = idiv;
133 const double r_idiv = 1. / idiv;
134 opampModel.reset();
135 summer[i] = new unsigned short[size];
136
137 for (int vi = 0; vi < size; vi++)
138 {
139 const double vin = vmin + vi * r_N16 * r_idiv; /* vmin .. vmax */
140 summer[i][vi] = getNormalizedValue(opampModel.solve(n, vin));
141 }
142 }
143 }
144
153 inline void buildMixerTable(const OpAmp& opampModel, double nRatio)
154 {
155 const double r_N16 = 1. / N16;
156
157 for (int i = 0; i < 8; i++)
158 {
159 const int idiv = (i == 0) ? 1 : i;
160 const int size = (i == 0) ? 1 : i << 16;
161 const double n = i * nRatio;
162 const double r_idiv = 1. / idiv;
163 opampModel.reset();
164 mixer[i] = new unsigned short[size];
165
166 for (int vi = 0; vi < size; vi++)
167 {
168 const double vin = vmin + vi * r_N16 * r_idiv; /* vmin .. vmax */
169 mixer[i][vi] = getNormalizedValue(opampModel.solve(n, vin));
170 }
171 }
172 }
173
181 inline void buildVolumeTable(const OpAmp& opampModel, double nDivisor)
182 {
183 const double r_N16 = 1. / N16;
184
185 for (int n8 = 0; n8 < 16; n8++)
186 {
187 const int size = 1 << 16;
188 const double n = n8 / nDivisor;
189 opampModel.reset();
190 volume[n8] = new unsigned short[size];
191
192 for (int vi = 0; vi < size; vi++)
193 {
194 const double vin = vmin + vi * r_N16; /* vmin .. vmax */
195 volume[n8][vi] = getNormalizedValue(opampModel.solve(n, vin));
196 }
197 }
198 }
199
207 inline void buildResonanceTable(const OpAmp& opampModel, const double resonance_n[16])
208 {
209 const double r_N16 = 1. / N16;
210
211 for (int n8 = 0; n8 < 16; n8++)
212 {
213 const int size = 1 << 16;
214 opampModel.reset();
215 resonance[n8] = new unsigned short[size];
216
217 for (int vi = 0; vi < size; vi++)
218 {
219 const double vin = vmin + vi * r_N16; /* vmin .. vmax */
220 resonance[n8][vi] = getNormalizedValue(opampModel.solve(resonance_n[n8], vin));
221 }
222 }
223 }
224
225public:
226 unsigned short** getVolume() { return volume; }
227 unsigned short** getResonance() { return resonance; }
228 unsigned short** getSummer() { return summer; }
229 unsigned short** getMixer() { return mixer; }
230
231 virtual Integrator* buildIntegrator() = 0;
232
233 inline unsigned short getOpampRev(int i) const { return opamp_rev[i]; }
234 inline double getVddt() const { return Vddt; }
235 inline double getVth() const { return Vth; }
236
237 // helper functions
238 inline unsigned short getNormalizedValue(double value) const
239 {
240 const double tmp = N16 * (value - vmin);
241 assert(tmp > -0.5 && tmp < 65535.5);
242 return static_cast<unsigned short>(tmp + 0.5);
243 }
244
245 inline unsigned short getNormalizedCurrentFactor(double wl) const
246 {
247 const double tmp = (1 << 13) * currFactorCoeff * wl;
248 assert(tmp > -0.5 && tmp < 65535.5);
249 return static_cast<unsigned short>(tmp + 0.5);
250 }
251
252 inline unsigned short getNVmin() const
253 {
254 const double tmp = N16 * vmin;
255 assert(tmp > -0.5 && tmp < 65535.5);
256 return static_cast<unsigned short>(tmp + 0.5);
257 }
258
259 inline int getNormalizedVoice(float value) const
260 {
261 return static_cast<int>(getNormalizedValue(getVoiceVoltage(value)));
262 }
263};
264
265} // namespace reSIDfp
266
267#endif
Definition FilterModelConfig.h:40
void buildVolumeTable(const OpAmp &opampModel, double nDivisor)
Definition FilterModelConfig.h:181
const double Vdd
Positive supply voltage.
Definition FilterModelConfig.h:50
unsigned short * mixer[8]
Lookup tables for gain and summer op-amps in output stage / filter.
Definition FilterModelConfig.h:71
void buildResonanceTable(const OpAmp &opampModel, const double resonance_n[16])
Definition FilterModelConfig.h:207
double uCox
Transconductance coefficient: u*Cox.
Definition FilterModelConfig.h:53
const double Vddt
Vdd - Vth.
Definition FilterModelConfig.h:52
double currFactorCoeff
Current factor coefficient for op-amp integrators.
Definition FilterModelConfig.h:67
const double C
Capacitor value.
Definition FilterModelConfig.h:43
unsigned short opamp_rev[1<< 16]
Reverse op-amp transfer function.
Definition FilterModelConfig.h:78
static constexpr double Ut
Transistor parameters.
Definition FilterModelConfig.h:48
const double Vth
Threshold voltage.
Definition FilterModelConfig.h:51
void buildMixerTable(const OpAmp &opampModel, double nRatio)
Definition FilterModelConfig.h:153
const double N16
Fixed point scaling for 16 bit op-amp output.
Definition FilterModelConfig.h:61
void buildSummerTable(const OpAmp &opampModel)
Definition FilterModelConfig.h:124
Definition OpAmp.h:72
double solve(double n, double vi) const
Definition OpAmp.cpp:33
void reset() const
Definition OpAmp.h:103
Definition Spline.h:42