Filter.h
/*
* This file is part of libsidplayfp, a SID player engine.
*
* Copyright 2011-2025 Leandro Nini <drfiemost@users.sourceforge.net>
* Copyright 2007-2010 Antti Lankila
* Copyright 2004 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 FILTER_H
#define FILTER_H
#include "FilterModelConfig.h"
#include "Voice.h"
#include "siddefs-fp.h"
namespace reSIDfp
{
class Filter
{
private:
unsigned short* mixer;
unsigned short* summer;
unsigned short* resonance;
unsigned short* volume;
FilterModelConfig& fmc;
unsigned short* currentMixer = nullptr;
unsigned short* currentSummer = nullptr;
unsigned short* currentResonance = nullptr;
unsigned short* currentVolume = nullptr;
protected:
int Vhp = 0;
int Vbp = 0;
int Vlp = 0;
private:
int Ve = 0;
unsigned int fc = 0;
bool filt1 = false;
bool filt2 = false;
bool filt3 = false;
bool filtE = false;
bool voice3off = false;
protected:
bool hp = false;
bool bp = false;
bool lp = false;
private:
unsigned char vol = 0;
bool enabled = true;
unsigned char filt = 0;
private:
inline int getNormalizedVoice(Voice& v) const
{
return fmc.getNormalizedVoice(v.output(), v.envelope()->output());
}
// If voice 3 is off we still need to clock the waveform generator
inline int getSilentVoice(Voice& v) const
{
v.wave()->output();
return 0;
}
protected:
virtual void updateCenterFrequency() = 0;
void updateResonance(unsigned char res) { currentResonance = resonance + (res * (1<<16)); }
void updateMixing();
inline unsigned int getFC() const { return fc; }
virtual int solveIntegrators() = 0;
public:
Filter(FilterModelConfig& fmc);
virtual ~Filter() = default;
unsigned short clock(Voice& v1, Voice& v2, Voice& v3);
void enable(bool enable);
void reset();
void writeFC_LO(unsigned char fc_lo);
void writeFC_HI(unsigned char fc_hi);
void writeRES_FILT(unsigned char res_filt);
void writeMODE_VOL(unsigned char mode_vol);
void input(short input) { Ve = fmc.getNormalizedVoice(input/32768.f, 0); }
};
} // namespace reSIDfp
#if RESID_INLINING || defined(FILTER_CPP)
namespace reSIDfp
{
RESID_INLINE
unsigned short Filter::clock(Voice& voice1, Voice& voice2, Voice& voice3)
{
const int V1 = getNormalizedVoice(voice1);
const int V2 = getNormalizedVoice(voice2);
// Voice 3 is silenced by voice3off if it is not routed through the filter.
const int V3 = (filt3 || !voice3off) ? getNormalizedVoice(voice3) : getSilentVoice(voice3);
int Vsum = 0;
int Vmix = 0;
(filt1 ? Vsum : Vmix) += V1;
(filt2 ? Vsum : Vmix) += V2;
(filt3 ? Vsum : Vmix) += V3;
(filtE ? Vsum : Vmix) += Ve;
Vhp = currentSummer[currentResonance[Vbp] + Vlp + Vsum];
Vmix += solveIntegrators();
return currentVolume[currentMixer[Vmix]];
}
} // namespace reSIDfp
#endif
#endif
reSIDfp::EnvelopeGenerator::output
unsigned int output() const
Definition EnvelopeGenerator.h:130
reSIDfp::FilterModelConfig
Definition FilterModelConfig.h:40
reSIDfp::Filter
Definition Filter.h:38
reSIDfp::Filter::hp
bool hp
Highpass, bandpass, and lowpass filter modes.
Definition Filter.h:90
reSIDfp::Filter::Vbp
int Vbp
Filter bandpass state.
Definition Filter.h:64
reSIDfp::Filter::updateResonance
void updateResonance(unsigned char res)
Definition Filter.h:129
reSIDfp::Filter::writeFC_LO
void writeFC_LO(unsigned char fc_lo)
Definition Filter.cpp:75
reSIDfp::Filter::writeRES_FILT
void writeRES_FILT(unsigned char res_filt)
Definition Filter.cpp:87
reSIDfp::Filter::writeFC_HI
void writeFC_HI(unsigned char fc_hi)
Definition Filter.cpp:81
reSIDfp::Filter::Vhp
int Vhp
Filter highpass state.
Definition Filter.h:61
reSIDfp::Filter::clock
unsigned short clock(Voice &v1, Voice &v2, Voice &v3)
Definition Filter.h:214
reSIDfp::Filter::Vlp
int Vlp
Filter lowpass state.
Definition Filter.h:67
reSIDfp::Filter::enable
void enable(bool enable)
Definition Filter.cpp:125
reSIDfp::Filter::reset
void reset()
Definition Filter.cpp:139
reSIDfp::Filter::updateCenterFrequency
virtual void updateCenterFrequency()=0
reSIDfp::Filter::updateMixing
void updateMixing()
Definition Filter.cpp:51
reSIDfp::Filter::input
void input(short input)
Definition Filter.h:203
reSIDfp::Filter::writeMODE_VOL
void writeMODE_VOL(unsigned char mode_vol)
Definition Filter.cpp:104
reSIDfp::Filter::getFC
unsigned int getFC() const
Definition Filter.h:139
reSIDfp::Voice
Definition Voice.h:37
reSIDfp::Voice::output
RESID_INLINE float output()
Definition Voice.h:65
reSIDfp::WaveformGenerator::output
unsigned int output()
Definition WaveformGenerator.h:352