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