libsidplayfp 1.0.3
|
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