Filter8580.h
/*
* This file is part of libsidplayfp, a SID player engine.
*
* Copyright 2011-2022 Leandro Nini <drfiemost@users.sourceforge.net>
* Copyright 2007-2010 Antti Lankila
* Copyright 2004,2010 Dag Lem <resid@nimrod.no>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef FILTER8580_H
#define FILTER8580_H
#include "siddefs-fp.h"
#include <memory>
#include "Filter.h"
#include "FilterModelConfig8580.h"
#include "Integrator8580.h"
#include "sidcxx11.h"
namespace reSIDfp
{
class Integrator8580;
class Filter8580 final : public Filter
{
private:
unsigned short** mixer;
unsigned short** summer;
unsigned short** gain_res;
unsigned short** gain_vol;
const int voiceScaleS11;
const int voiceDC;
double cp;
std::unique_ptr<Integrator8580> const hpIntegrator;
std::unique_ptr<Integrator8580> const bpIntegrator;
protected:
void updatedCenterFrequency() override;
void updateResonance(unsigned char res) override { currentResonance = gain_res[res]; }
void updatedMixing() override;
public:
Filter8580() :
mixer(FilterModelConfig8580::getInstance()->getMixer()),
summer(FilterModelConfig8580::getInstance()->getSummer()),
gain_res(FilterModelConfig8580::getInstance()->getGainRes()),
gain_vol(FilterModelConfig8580::getInstance()->getGainVol()),
voiceScaleS11(FilterModelConfig8580::getInstance()->getVoiceScaleS11()),
voiceDC(FilterModelConfig8580::getInstance()->getNormalizedVoiceDC()),
cp(0.5),
hpIntegrator(FilterModelConfig8580::getInstance()->buildIntegrator()),
bpIntegrator(FilterModelConfig8580::getInstance()->buildIntegrator())
{
setFilterCurve(cp);
input(0);
}
~Filter8580();
unsigned short clock(int voice1, int voice2, int voice3) override;
void input(int sample) override { ve = (sample * voiceScaleS11 * 3 >> 11) + mixer[0][0]; }
void setFilterCurve(double curvePosition);
};
} // namespace reSIDfp
#if RESID_INLINING || defined(FILTER8580_CPP)
namespace reSIDfp
{
RESID_INLINE
unsigned short Filter8580::clock(int voice1, int voice2, int voice3)
{
voice1 = (voice1 * voiceScaleS11 >> 15) + voiceDC;
voice2 = (voice2 * voiceScaleS11 >> 15) + voiceDC;
// Voice 3 is silenced by voice3off if it is not routed through the filter.
voice3 = (filt3 || !voice3off) ? (voice3 * voiceScaleS11 >> 15) + voiceDC : 0;
int Vi = 0;
int Vo = 0;
(filt1 ? Vi : Vo) += voice1;
(filt2 ? Vi : Vo) += voice2;
(filt3 ? Vi : Vo) += voice3;
(filtE ? Vi : Vo) += ve;
Vhp = currentSummer[currentResonance[Vbp] + Vlp + Vi];
Vbp = hpIntegrator->solve(Vhp);
Vlp = bpIntegrator->solve(Vbp);
if (lp) Vo += Vlp;
if (bp) Vo += Vbp;
if (hp) Vo += Vhp;
return currentGain[currentMixer[Vo]];
}
} // namespace reSIDfp
#endif
#endif