libsidplayfp 2.3.1
Filter8580.h
1/*
2 * This file is part of libsidplayfp, a SID player engine.
3 *
4 * Copyright 2011-2020 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 "siddefs-fp.h"
27
28#include <memory>
29
30#include "Filter.h"
31#include "FilterModelConfig8580.h"
32#include "Integrator8580.h"
33
34#include "sidcxx11.h"
35
36namespace reSIDfp
37{
38
39class Integrator8580;
40
281class Filter8580 final : public Filter
282{
283private:
284 unsigned short** mixer;
285 unsigned short** summer;
286 unsigned short** gain_res;
287 unsigned short** gain_vol;
288
289 const int voiceScaleS11;
290 const int voiceDC;
291
292 double cp;
293
295 std::unique_ptr<Integrator8580> const hpIntegrator;
296
298 std::unique_ptr<Integrator8580> const bpIntegrator;
299
300protected:
304 void updatedCenterFrequency() override;
305
311 void updateResonance(unsigned char res) override { currentResonance = gain_res[res]; }
312
313 void updatedMixing() override;
314
315public:
316 Filter8580() :
317 mixer(FilterModelConfig8580::getInstance()->getMixer()),
318 summer(FilterModelConfig8580::getInstance()->getSummer()),
319 gain_res(FilterModelConfig8580::getInstance()->getGainRes()),
320 gain_vol(FilterModelConfig8580::getInstance()->getGainVol()),
321 voiceScaleS11(FilterModelConfig8580::getInstance()->getVoiceScaleS11()),
322 voiceDC(FilterModelConfig8580::getInstance()->getVoiceDC()),
323 cp(0.5),
324 hpIntegrator(FilterModelConfig8580::getInstance()->buildIntegrator()),
325 bpIntegrator(FilterModelConfig8580::getInstance()->buildIntegrator())
326 {
327 setFilterCurve(cp);
328 input(0);
329 }
330
331 ~Filter8580();
332
333 unsigned short clock(int voice1, int voice2, int voice3) override;
334
335 void input(int sample) override { ve = (sample * voiceScaleS11 * 3 >> 11) + mixer[0][0]; }
336
342 void setFilterCurve(double curvePosition);
343};
344
345} // namespace reSIDfp
346
347#if RESID_INLINING || defined(FILTER8580_CPP)
348
349namespace reSIDfp
350{
351
352RESID_INLINE
353unsigned short Filter8580::clock(int voice1, int voice2, int voice3)
354{
355 voice1 = (voice1 * voiceScaleS11 >> 15) + voiceDC;
356 voice2 = (voice2 * voiceScaleS11 >> 15) + voiceDC;
357 // Voice 3 is silenced by voice3off if it is not routed through the filter.
358 voice3 = (filt3 || !voice3off) ? (voice3 * voiceScaleS11 >> 15) + voiceDC : 0;
359
360 int Vi = 0;
361 int Vo = 0;
362
363 (filt1 ? Vi : Vo) += voice1;
364 (filt2 ? Vi : Vo) += voice2;
365 (filt3 ? Vi : Vo) += voice3;
366 (filtE ? Vi : Vo) += ve;
367
368 Vhp = currentSummer[currentResonance[Vbp] + Vlp + Vi];
369 Vbp = hpIntegrator->solve(Vhp);
370 Vlp = bpIntegrator->solve(Vbp);
371
372 if (lp) Vo += Vlp;
373 if (bp) Vo += Vbp;
374 if (hp) Vo += Vhp;
375
376 return currentGain[currentMixer[Vo]];
377}
378
379} // namespace reSIDfp
380
381#endif
382
383#endif