libsidplayfp 2.10.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
38{
39protected:
41 const double C;
42
44
45
46 static constexpr double Ut = 26.0e-3;
47
48 const double Vdd;
49 const double Vth;
50 const double Vddt;
51 double uCox;
53
54 // Derived stuff
55 const double vmin, vmax;
56 const double denorm, norm;
57
59 const double N16;
60
61 const double voice_voltage_range;
62 const double voice_DC_voltage;
63
66
68
69 unsigned short* mixer[8]; //-V730_NOINIT this is initialized in the derived class constructor
70 unsigned short* summer[5]; //-V730_NOINIT this is initialized in the derived class constructor
71 unsigned short* volume[16]; //-V730_NOINIT this is initialized in the derived class constructor
72 unsigned short* resonance[16]; //-V730_NOINIT this is initialized in the derived class constructor
74
76 unsigned short opamp_rev[1 << 16]; //-V730_NOINIT this is initialized in the derived class constructor
77
78private:
79 FilterModelConfig(const FilterModelConfig&) = delete;
80 FilterModelConfig& operator= (const FilterModelConfig&) = delete;
81
82 inline double getVoiceVoltage(float value) const
83 {
84 return value * voice_voltage_range + voice_DC_voltage;
85 }
86
87protected:
99 double vvr,
100 double vdv,
101 double c,
102 double vdd,
103 double vth,
104 double ucox,
105 const Spline::Point *opamp_voltage,
106 int opamp_size
107 );
108
110
111 void setUCox(double new_uCox);
112
122 inline void buildSummerTable(const OpAmp& opampModel)
123 {
124 const double r_N16 = 1. / N16;
125
126 for (int i = 0; i < 5; i++)
127 {
128 const int idiv = 2 + i; // 2 - 6 input "resistors".
129 const int size = idiv << 16;
130 const double n = idiv;
131 const double r_idiv = 1. / idiv;
132 opampModel.reset();
133 summer[i] = new unsigned short[size];
134
135 for (int vi = 0; vi < size; vi++)
136 {
137 const double vin = vmin + vi * r_N16 * r_idiv; /* vmin .. vmax */
138 summer[i][vi] = getNormalizedValue(opampModel.solve(n, vin));
139 }
140 }
141 }
142
151 inline void buildMixerTable(const OpAmp& opampModel, double nRatio)
152 {
153 const double r_N16 = 1. / N16;
154
155 for (int i = 0; i < 8; i++)
156 {
157 const int idiv = (i == 0) ? 1 : i;
158 const int size = (i == 0) ? 1 : i << 16;
159 const double n = i * nRatio;
160 const double r_idiv = 1. / idiv;
161 opampModel.reset();
162 mixer[i] = new unsigned short[size];
163
164 for (int vi = 0; vi < size; vi++)
165 {
166 const double vin = vmin + vi * r_N16 * r_idiv; /* vmin .. vmax */
167 mixer[i][vi] = getNormalizedValue(opampModel.solve(n, vin));
168 }
169 }
170 }
171
179 inline void buildVolumeTable(const OpAmp& opampModel, double nDivisor)
180 {
181 const double r_N16 = 1. / N16;
182
183 for (int n8 = 0; n8 < 16; n8++)
184 {
185 const int size = 1 << 16;
186 const double n = n8 / nDivisor;
187 opampModel.reset();
188 volume[n8] = new unsigned short[size];
189
190 for (int vi = 0; vi < size; vi++)
191 {
192 const double vin = vmin + vi * r_N16; /* vmin .. vmax */
193 volume[n8][vi] = getNormalizedValue(opampModel.solve(n, vin));
194 }
195 }
196 }
197
205 inline void buildResonanceTable(const OpAmp& opampModel, const double resonance_n[16])
206 {
207 const double r_N16 = 1. / N16;
208
209 for (int n8 = 0; n8 < 16; n8++)
210 {
211 const int size = 1 << 16;
212 opampModel.reset();
213 resonance[n8] = new unsigned short[size];
214
215 for (int vi = 0; vi < size; vi++)
216 {
217 const double vin = vmin + vi * r_N16; /* vmin .. vmax */
218 resonance[n8][vi] = getNormalizedValue(opampModel.solve(resonance_n[n8], vin));
219 }
220 }
221 }
222
223public:
224 unsigned short** getVolume() { return volume; }
225 unsigned short** getResonance() { return resonance; }
226 unsigned short** getSummer() { return summer; }
227 unsigned short** getMixer() { return mixer; }
228
229 inline unsigned short getOpampRev(int i) const { return opamp_rev[i]; }
230 inline double getVddt() const { return Vddt; }
231 inline double getVth() const { return Vth; }
232
233 // helper functions
234 inline unsigned short getNormalizedValue(double value) const
235 {
236 const double tmp = N16 * (value - vmin);
237 assert(tmp > -0.5 && tmp < 65535.5);
238 return static_cast<unsigned short>(tmp + 0.5);
239 }
240
241 inline unsigned short getNormalizedCurrentFactor(double wl) const
242 {
243 const double tmp = (1 << 13) * currFactorCoeff * wl;
244 assert(tmp > -0.5 && tmp < 65535.5);
245 return static_cast<unsigned short>(tmp + 0.5);
246 }
247
248 inline unsigned short getNVmin() const
249 {
250 const double tmp = N16 * vmin;
251 assert(tmp > -0.5 && tmp < 65535.5);
252 return static_cast<unsigned short>(tmp + 0.5);
253 }
254
255 inline int getNormalizedVoice(float value) const
256 {
257 return static_cast<int>(getNormalizedValue(getVoiceVoltage(value)));
258 }
259};
260
261} // namespace reSIDfp
262
263#endif
Definition FilterModelConfig.h:38
void buildVolumeTable(const OpAmp &opampModel, double nDivisor)
Definition FilterModelConfig.h:179
const double Vdd
Positive supply voltage.
Definition FilterModelConfig.h:48
unsigned short * mixer[8]
Lookup tables for gain and summer op-amps in output stage / filter.
Definition FilterModelConfig.h:69
void buildResonanceTable(const OpAmp &opampModel, const double resonance_n[16])
Definition FilterModelConfig.h:205
double uCox
Transconductance coefficient: u*Cox.
Definition FilterModelConfig.h:51
const double Vddt
Vdd - Vth.
Definition FilterModelConfig.h:50
double currFactorCoeff
Current factor coefficient for op-amp integrators.
Definition FilterModelConfig.h:65
const double C
Capacitor value.
Definition FilterModelConfig.h:41
unsigned short opamp_rev[1<< 16]
Reverse op-amp transfer function.
Definition FilterModelConfig.h:76
static constexpr double Ut
Transistor parameters.
Definition FilterModelConfig.h:46
const double Vth
Threshold voltage.
Definition FilterModelConfig.h:49
void buildMixerTable(const OpAmp &opampModel, double nRatio)
Definition FilterModelConfig.h:151
const double N16
Fixed point scaling for 16 bit op-amp output.
Definition FilterModelConfig.h:59
void buildSummerTable(const OpAmp &opampModel)
Definition FilterModelConfig.h:122
Definition OpAmp.h:71
double solve(double n, double vi) const
Definition OpAmp.cpp:33
void reset() const
Definition OpAmp.h:102
Definition Spline.h:42