libsidplayfp  1.5.3
Filter6581.h
1 /*
2  * This file is part of libsidplayfp, a SID player engine.
3  *
4  * Copyright 2011-2013 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 FILTER6581_H
24 #define FILTER6581_H
25 
26 #include "siddefs-fp.h"
27 
28 #include <memory>
29 
30 #include "Filter.h"
31 #include "FilterModelConfig.h"
32 
33 namespace reSIDfp
34 {
35 
36 class Integrator;
37 
42 class Filter6581 : public Filter
43 {
44 private:
46  int Vhp;
47 
49  int Vbp;
50 
52  int Vlp;
53 
55  int ve;
56 
57  const int voiceScaleS14, voiceDC;
58 
60  unsigned short* currentGain;
61 
63  unsigned short* currentMixer;
64 
66  unsigned short* currentSummer;
67 
69  unsigned short* currentResonance;
70 
72  std::auto_ptr<Integrator> hpIntegrator;
73 
75  std::auto_ptr<Integrator> bpIntegrator;
76 
77  const unsigned short* f0_dac;
78 
79  unsigned short** mixer;
80  unsigned short** summer;
81  unsigned short** gain;
82 
83 public:
84  Filter6581() :
85  Vhp(0),
86  Vbp(0),
87  Vlp(0),
88  ve(0),
89  voiceScaleS14(FilterModelConfig::getInstance()->getVoiceScaleS14()),
90  voiceDC(FilterModelConfig::getInstance()->getVoiceDC()),
91  currentGain(0),
92  currentMixer(0),
93  currentSummer(0),
94  currentResonance(0),
95  hpIntegrator(FilterModelConfig::getInstance()->buildIntegrator()),
96  bpIntegrator(FilterModelConfig::getInstance()->buildIntegrator()),
97  f0_dac(FilterModelConfig::getInstance()->getDAC(0.5)),
98  mixer(FilterModelConfig::getInstance()->getMixer()),
99  summer(FilterModelConfig::getInstance()->getSummer()),
100  gain(FilterModelConfig::getInstance()->getGain())
101  {
102  input(0);
103  }
104 
105  ~Filter6581();
106 
107  int clock(int voice1, int voice2, int voice3);
108 
109  void input(int sample) { ve = (sample * voiceScaleS14 * 3 >> 10) + mixer[0][0]; }
110 
114  void updatedCenterFrequency();
115 
121  void updatedResonance() { currentResonance = gain[~res & 0xf]; }
122 
123  void updatedMixing();
124 
125 public:
131  void setFilterCurve(double curvePosition);
132 };
133 
134 } // namespace reSIDfp
135 
136 #if RESID_INLINING || defined(FILTER6581_CPP)
137 
138 #include "Integrator.h"
139 
140 namespace reSIDfp
141 {
142 
143 RESID_INLINE
144 int Filter6581::clock(int voice1, int voice2, int voice3)
145 {
146  voice1 = (voice1 * voiceScaleS14 >> 18) + voiceDC;
147  voice2 = (voice2 * voiceScaleS14 >> 18) + voiceDC;
148  voice3 = (voice3 * voiceScaleS14 >> 18) + voiceDC;
149 
150  int Vi = 0;
151  int Vo = 0;
152 
153  (filt1 ? Vi : Vo) += voice1;
154 
155  (filt2 ? Vi : Vo) += voice2;
156 
157  // NB! Voice 3 is not silenced by voice3off if it is routed
158  // through the filter.
159  if (filt3)
160  {
161  Vi += voice3;
162  }
163  else if (!voice3off)
164  {
165  Vo += voice3;
166  }
167 
168  (filtE ? Vi : Vo) += ve;
169 
170  const int oldVhp = Vhp;
171  Vhp = currentSummer[currentResonance[Vbp] + Vlp + Vi];
172  Vlp = bpIntegrator->solve(Vbp);
173  Vbp = hpIntegrator->solve(oldVhp);
174 
175  if (lp)
176  {
177  Vo += Vlp;
178  }
179 
180  if (bp)
181  {
182  Vo += Vbp;
183  }
184 
185  if (hp)
186  {
187  Vo += Vhp;
188  }
189 
190  return currentGain[currentMixer[Vo]] - (1 << 15);
191 }
192 
193 } // namespace reSIDfp
194 
195 #endif
196 
197 #endif