Main Page | Namespaces | Classes | Compounds | Files | Compound Members | Related filter.cpp00001 // 00002 // SYNTOPIA. See http://Syntopia.sourceforge.net for details and documentation. 00003 // 00004 // Author of this file: Mikael Hvidtfeldt Christensen (mikaelc@users.sourceforge.net) 00005 // 00006 00007 #include "filters.h" 00008 #include "math.h" 00009 #include "SynthVoice.h" 00010 00011 // Filters ---------------------------------------------------------- 00012 // BiQuad ---------------------------------------------------------------------------------------------------------- 00013 00014 namespace SynthCore { 00015 00016 Module * BiQuad::newInstance(SynthVoice * S1) { 00017 return new BiQuad(S1); 00018 } 00019 00020 Module * BiQuad::sharedClone() { 00021 BiQuad * BQ = new BiQuad(hostVoice); 00022 00023 BQ->dry = dry; 00024 BQ->filterType = filterType; 00025 BQ->freq = freq; 00026 BQ->rez = rez; 00027 00028 BQ->ModID = ModID; 00029 BQ->firstVoice = false; 00030 return BQ; 00031 } 00032 00033 BiQuad::BiQuad(SynthVoice * S1) { 00034 hostVoice = S1; 00035 00036 Output1 = new Output(this); 00037 Input1 = new Input(this); 00038 myFilter = new BiFilter(); 00039 myFilter2 = new BiFilter(); 00040 00041 dry=0.5f; 00042 00043 filterType = lowpass; 00044 00045 UpdateCounter = 0; 00046 00047 FreqInput = new Input(this); FreqInput->manualUpdate = true; 00048 RezInput = new Input(this); RezInput->manualUpdate = true; 00049 00050 freq = 1000.0f; rez = 0.5f; 00051 00052 updateFreqAndRez(); 00053 00054 HACK = false; 00055 } 00056 00057 BiQuad::~BiQuad() 00058 { 00059 delete Output1; 00060 delete Input1; 00061 delete FreqInput; 00062 delete RezInput; 00063 delete myFilter; 00064 delete myFilter2; 00065 }; 00066 00067 00068 00069 void BiQuad::setDry(float s) 00070 { 00071 dry = s; 00072 } 00073 00074 std::string BiQuad::getXML(int indent ) { 00075 00076 std::string S = Utils::space(indent) + "<Module ID=\""+Utils::intToString((int)this)+"\" >"+ Utils::newline(); 00077 S += Utils::space(indent+2) + "<TypeID>" + typeid(*this).name() + "</TypeID>" + Utils::newline(); 00078 00079 S += saveParameter("Dry",dry, indent+2); 00080 S += saveParameter("Rez",rez, indent+2); 00081 S += saveParameter("Freq",freq, indent+2); 00082 S += Output1->getXML("Output1", indent+2); 00083 S += Input1->getXML("Input1", indent+2); 00084 S += FreqInput->getXML("FreqInput", indent+2); 00085 S += RezInput->getXML("RezInput", indent+2); 00086 S += saveID(indent+2); 00087 S += Utils::space(indent) + "</Module>" + Utils::newline(); 00088 return S; 00089 } 00090 00091 void BiQuad::loadXML(XMLNode * n, bool firstPass) { 00092 cout << "Parsing sampler XML" << endl; 00093 00094 string TypeID = n->getTagText("TypeID") ; 00095 if (typeid(*this).name() != TypeID) { 00096 throw parseError("Trying to put "+TypeID+" into "+typeid(*this).name()); 00097 } 00098 00099 00100 00101 00102 if (firstPass) { 00103 loadParameter("Dry",dry, n); 00104 loadParameter("Rez",rez, n); 00105 loadParameter("Freq",freq, n); 00106 Output1->loadXML("Output1", n); 00107 } else { 00108 Input1->loadXML("Input1", n); 00109 FreqInput->loadXML("FreqInput", n); 00110 RezInput->loadXML("RezInput", n); 00111 } 00112 }; 00113 00114 void BiQuad::update() { 00115 00116 // We only update every 1000 sample (48 times per second). 00117 UpdateCounter++; 00118 if (UpdateCounter>1000) { 00119 UpdateCounter = 0; rez = 0.4505f; 00120 if (FreqInput->ConFrom != 0) freq = FreqInput->updateRead()*4000.0f + hostVoice->getMidiFreq()+200.0f; 00121 if (RezInput->ConFrom != 0) rez = RezInput->updateRead(); 00122 if (!HACK) updateFreqAndRez(); 00123 } 00124 00125 00126 dry = 0.0f; // HACK 00127 Output1->value= Input1->ConFrom->value*dry 00128 + myFilter->read( myFilter2->read(Input1->ConFrom->value) ) * (1.0f-dry) ; 00129 } 00130 00131 00132 void BiQuad::updateFreqAndRez() 00133 { 00134 switch (filterType) { 00135 case lowpass: 00136 myFilter->lowpassFreqAndQ(freq,rez); 00137 break; 00138 00139 case highpass: 00140 myFilter->highpassFreqAndQ(freq,rez); 00141 break; 00142 00143 case notch: 00144 myFilter->notchFreqAndQ(freq,rez); 00145 break; 00146 00147 case allpass: 00148 myFilter->allpassFreqAndQ(freq,rez); 00149 break; 00150 00151 case bandpass2: 00152 myFilter->bandpass2FreqAndQ(freq,rez); 00153 break; 00154 00155 case bandpass1: 00156 myFilter->bandpass1FreqAndQ(freq,rez); 00157 break; 00158 00159 case bypass: 00160 myFilter->bypassFreqAndQ(freq,rez); 00161 break; 00162 00163 case highShelf: 00164 myFilter->highShelfFreqAndQAndA(freq,rez, 1.4f); 00165 break; 00166 00167 case lowShelf: 00168 myFilter->lowShelfFreqAndQAndA(freq,rez, 1.4f); 00169 break; 00170 00171 case peakingEQ: 00172 myFilter->peakingEQFreqAndQAndA(freq,rez, 1.4f); 00173 break; 00174 00175 default: 00176 // This ought not to happen 00177 break; 00178 } 00179 00180 // Set second filter equal to first one. 00181 myFilter2->clone(myFilter); 00182 00183 } 00184 00185 void BiQuad::setFreqAndRez(float frequence, float resonance) 00186 { // Set frequency and resonance. 00187 freq = frequence; rez = resonance; 00188 updateFreqAndRez(); 00189 } 00190 00191 00192 00193 00194 }; // end of namespace: SynthCore Docs made by Doxygen. Email: Mikael Christensen |