libsidplayfp 1.0.3
Filter8580.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 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 FILTER8580_H
00024 #define FILTER8580_H
00025 
00026 #include "siddefs-fp.h"
00027 
00028 #include "Filter.h"
00029 
00030 namespace reSIDfp
00031 {
00032 
00046 class Filter8580 : public Filter
00047 {
00048 private:
00049     double highFreq;
00050     float Vlp, Vbp, Vhp;
00051     float ve, w0, _1_div_Q;
00052 
00053 public:
00054     Filter8580() :
00055         highFreq(12500.),
00056         Vlp(0.f),
00057         Vbp(0.f),
00058         Vhp(0.f),
00059         ve(0.f),
00060         w0(0.f),
00061         _1_div_Q(0.f) {}
00062 
00063     int clock(int voice1, int voice2, int voice3);
00064 
00065     void updatedCenterFrequency() { w0 = (float)(2.*M_PI * highFreq * fc / 2047 / 1e6); }
00066 
00067     void updatedResonance() { _1_div_Q = 1.f / (0.707f + res / 15.f); }
00068 
00069     void input(int input) { ve = input << 4; }
00070 
00071     void updatedMixing() {}
00072 
00073     void setFilterCurve(double curvePosition) { highFreq = curvePosition; }
00074 };
00075 
00076 } // namespace reSIDfp
00077 
00078 #if RESID_INLINING || defined(FILTER8580_CPP)
00079 
00080 #include <stdlib.h>
00081 #include <math.h>
00082 
00083 namespace reSIDfp
00084 {
00085 
00086 RESID_INLINE
00087 int Filter8580::clock(int voice1, int voice2, int voice3)
00088 {
00089     voice1 >>= 7;
00090     voice2 >>= 7;
00091     voice3 >>= 7;
00092 
00093     int Vi = 0;
00094     float Vo = 0.f;
00095 
00096     if (filt1)
00097     {
00098         Vi += voice1;
00099     }
00100     else
00101     {
00102         Vo += voice1;
00103     }
00104 
00105     if (filt2)
00106     {
00107         Vi += voice2;
00108     }
00109     else
00110     {
00111         Vo += voice2;
00112     }
00113 
00114     // NB! Voice 3 is not silenced by voice3off if it is routed
00115     // through the filter.
00116     if (filt3)
00117     {
00118         Vi += voice3;
00119     }
00120     else if (!voice3off)
00121     {
00122         Vo += voice3;
00123     }
00124 
00125     if (filtE)
00126     {
00127         Vi += (int)ve;
00128     }
00129     else
00130     {
00131         Vo += ve;
00132     }
00133 
00134     const float dVbp = w0 * Vhp;
00135     const float dVlp = w0 * Vbp;
00136     Vbp -= dVbp;
00137     Vlp -= dVlp;
00138     Vhp = (Vbp * _1_div_Q) - Vlp - Vi + float(rand()) / float(RAND_MAX);
00139 
00140     if (lp)
00141     {
00142         Vo += Vlp;
00143     }
00144 
00145     if (bp)
00146     {
00147         Vo += Vbp;
00148     }
00149 
00150     if (hp)
00151     {
00152         Vo += Vhp;
00153     }
00154 
00155     return (int) Vo * vol >> 4;
00156 }
00157 
00158 } // namespace reSIDfp
00159 
00160 #endif
00161 
00162 #endif