libsidplayfp  1.0.3
Filter6581.h
00001 /*
00002  * This file is part of libsidplayfp, a SID player engine.
00003  *
00004  * Copyright 2011-2013 Leandro Nini <drfiemost@users.sourceforge.net>
00005  * Copyright 2007-2010 Antti Lankila
00006  * Copyright 2004,2010 Dag Lem <resid@nimrod.no>
00007  *
00008  * This program is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00021  */
00022 
00023 #ifndef FILTER6581_H
00024 #define FILTER6581_H
00025 
00026 #include "siddefs-fp.h"
00027 
00028 #include "Filter.h"
00029 #include "FilterModelConfig.h"
00030 
00031 namespace reSIDfp
00032 {
00033 
00034 class Integrator;
00035 
00047 class Filter6581 : public Filter
00048 {
00049 private:
00051     int Vhp;
00052 
00054     int Vbp;
00055 
00057     int Vlp;
00058 
00060     int ve;
00061 
00062     const int voiceScaleS14, voiceDC, vo_T16;
00063 
00065     unsigned short* currentGain;
00066 
00068     unsigned short* currentMixer;
00069 
00071     unsigned short* currentSummer;
00072 
00074     unsigned short* currentResonance;
00075 
00077     Integrator* hpIntegrator;
00078 
00080     Integrator* bpIntegrator;
00081 
00082     const unsigned int* f0_dac;
00083 
00084     unsigned short** mixer;
00085     unsigned short** summer;
00086     unsigned short** gain;
00087 
00088 public:
00089     Filter6581() :
00090         Vhp(0),
00091         Vbp(0),
00092         Vlp(0),
00093         ve(0),
00094         voiceScaleS14(FilterModelConfig::getInstance()->getVoiceScaleS14()),
00095         voiceDC(FilterModelConfig::getInstance()->getVoiceDC()),
00096         vo_T16(FilterModelConfig::getInstance()->getVO_T16()),
00097         currentGain(0),
00098         currentMixer(0),
00099         currentSummer(0),
00100         currentResonance(0),
00101         hpIntegrator(FilterModelConfig::getInstance()->buildIntegrator()),
00102         bpIntegrator(FilterModelConfig::getInstance()->buildIntegrator()),
00103         f0_dac(FilterModelConfig::getInstance()->getDAC(FilterModelConfig::getInstance()->getDacZero(0.5))),
00104         mixer(FilterModelConfig::getInstance()->getMixer()),
00105         summer(FilterModelConfig::getInstance()->getSummer()),
00106         gain(FilterModelConfig::getInstance()->getGain())
00107     {
00108         input(0);
00109     }
00110 
00111     ~Filter6581();
00112 
00113     int clock(int voice1, int voice2, int voice3);
00114 
00115     void input(int sample) { ve = (sample * voiceScaleS14 * 3 >> 10) + mixer[0][0]; }
00116 
00120     void updatedCenterFrequency();
00121 
00128     void updatedResonance() { currentResonance = gain[~res & 0xf]; }
00129 
00130     void updatedMixing();
00131 
00132 public:
00138     void setFilterCurve(double curvePosition);
00139 };
00140 
00141 } // namespace reSIDfp
00142 
00143 #if RESID_INLINING || defined(FILTER6581_CPP)
00144 
00145 #include "Integrator.h"
00146 
00147 namespace reSIDfp
00148 {
00149 
00150 RESID_INLINE
00151 int Filter6581::clock(int voice1, int voice2, int voice3)
00152 {
00153 
00154     const int v1 = (voice1 * voiceScaleS14 >> 18) + voiceDC;
00155     const int v2 = (voice2 * voiceScaleS14 >> 18) + voiceDC;
00156     const int v3 = (voice3 * voiceScaleS14 >> 18) + voiceDC;
00157 
00158     int Vi = 0;
00159     int Vo = 0;
00160 
00161     if (filt1)
00162     {
00163         Vi += v1;
00164     }
00165     else
00166     {
00167         Vo += v1;
00168     }
00169 
00170     if (filt2)
00171     {
00172         Vi += v2;
00173     }
00174     else
00175     {
00176         Vo += v2;
00177     }
00178 
00179     // NB! Voice 3 is not silenced by voice3off if it is routed
00180     // through the filter.
00181     if (filt3)
00182     {
00183         Vi += v3;
00184     }
00185     else if (!voice3off)
00186     {
00187         Vo += v3;
00188     }
00189 
00190     if (filtE)
00191     {
00192         Vi += ve;
00193     }
00194     else
00195     {
00196         Vo += ve;
00197     }
00198 
00199     const int oldVhp = Vhp;
00200     Vhp = currentSummer[currentResonance[Vbp] + Vlp + Vi];
00201     Vlp = bpIntegrator->solve(Vbp + vo_T16) - vo_T16;
00202     Vbp = hpIntegrator->solve(oldVhp + vo_T16) - vo_T16;
00203 
00204     if (lp)
00205     {
00206         Vo += Vlp;
00207     }
00208 
00209     if (bp)
00210     {
00211         Vo += Vbp;
00212     }
00213 
00214     if (hp)
00215     {
00216         Vo += Vhp;
00217     }
00218 
00219     return currentGain[currentMixer[Vo]] - (1 << 15);
00220 }
00221 
00222 } // namespace reSIDfp
00223 
00224 #endif
00225 
00226 #endif