Main Page | Namespaces | Classes | Compounds | Files | Compound Members | Related sampler.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 00008 #include "Sampler.h" 00009 #include "math.h" 00010 #include <iostream> 00011 #include "SynthVoice.h" 00012 00013 // FMOSC ---------------------------------------------------------------------------------------------------------- 00014 00015 namespace SynthCore { 00016 00017 void Sampler::setMidiNote(int note) { 00018 sample = mySampleMap->getSamples(note); 00019 } 00020 00021 Module * Sampler::newInstance(SynthVoice * S1) { return new Sampler(S1); } 00022 00023 Module * Sampler::sharedClone() { 00024 Sampler * S = new Sampler(hostVoice); 00025 S->ModID = ModID; 00026 S->firstVoice = false; 00027 00028 S->freq = freq; 00029 S->interpolationType = interpolationType; 00030 00031 if (S->mySampleMap != 0) delete S->mySampleMap; 00032 S->mySampleMap = mySampleMap; 00033 return S; 00034 } 00035 00036 Sampler::Sampler(SynthVoice * S1) { 00037 freqs = new FreqTable(); 00038 hostVoice = S1; 00039 00040 Output1 = new Output(this); 00041 00042 freq = 440.0; 00043 pos = 0; 00044 00045 interpolationType = spline5Point; 00046 factoryWaveform = sawtooth; 00047 00048 mySampleMap = new SampleMap(); 00049 00050 setSawtooth(1024); // Init with triangle waveform. 00051 00052 sample = mySampleMap->getSamples(40); 00053 00054 MAX = MIN = 0.0f; // For debugging 00055 } 00056 00057 Sampler::~Sampler() { 00058 delete Output1; 00059 delete mySampleMap; 00060 delete (freqs); 00061 } 00062 00063 00064 00065 std::string Sampler::getXML(int indent ) { 00066 00067 std::string S = Utils::space(indent) + "<Module ID=\""+Utils::intToString((int)this)+"\" >"+ Utils::newline(); 00068 S += Utils::space(indent+2) + "<TypeID>" + typeid(*this).name() + "</TypeID>" + Utils::newline(); 00069 00070 S += saveParameter("interpolationType",interpolationType, indent+2); 00071 S += saveParameter("factoryWaveform",factoryWaveform, indent+2); 00072 00073 00074 S += Output1->getXML("Output1", indent+2); 00075 00076 S += saveID(indent+2); 00077 S += Utils::space(indent) + "</Module>" + Utils::newline(); 00078 return S; 00079 } 00080 00081 00082 void Sampler::loadXML(XMLNode * n, bool firstPass) { 00083 cout << "Parsing Sampler XML" << endl; 00084 00085 string TypeID = n->getTagText("TypeID") ; 00086 if (typeid(*this).name() != TypeID) { 00087 throw parseError("Trying to put "+TypeID+" into "+typeid(*this).name()); 00088 } 00089 00090 00091 00092 if (firstPass) { 00093 loadParameter("interpolationType",interpolationType, n); 00094 loadParameter("factoryWaveform",factoryWaveform, n); 00095 Output1->loadXML("Output1",n); 00096 } 00097 }; 00098 00099 00100 void Sampler::setTriangle(int length) { 00101 factoryWaveform = triangle; 00102 mySampleMap->clean(); 00103 for (int n=21; n<109; n++) 00104 { 00105 // find no harmonics; 00106 int maxPartials = freqs->getMaxPartialsFromMidi(n); 00107 mySampleMap->map[n] = Fourier::triangle(length,maxPartials,6); 00108 } 00109 sample = mySampleMap->getSamples(40); 00110 } 00111 00112 void Sampler::setSawtooth(int length) { 00113 factoryWaveform = sawtooth; 00114 mySampleMap->clean(); 00115 for (int n=21; n<109; n++) 00116 { 00117 // find no harmonics; 00118 int maxPartials = freqs->getMaxPartialsFromMidi(n); 00119 mySampleMap->map[n] = Fourier::sawtooth(length,maxPartials,6); 00120 } 00121 sample = mySampleMap->getSamples(40); 00122 } 00123 00124 void Sampler::setSquare(int length) { 00125 factoryWaveform = square; 00126 mySampleMap->clean(); 00127 for (int n=21; n<109; n++) 00128 { 00129 // find no harmonics; 00130 int maxPartials = freqs->getMaxPartialsFromMidi(n); 00131 mySampleMap->map[n] = Fourier::square(length,maxPartials,6); 00132 } 00133 sample = mySampleMap->getSamples(40); 00134 } 00135 00136 00137 void Sampler::setSine(int length) { 00138 factoryWaveform = sine; 00139 mySampleMap->clean(); 00140 for (int n=21; n<109; n++) 00141 { 00142 // find no harmonics; 00143 int maxPartials = freqs->getMaxPartialsFromMidi(n); 00144 mySampleMap->map[n] = Fourier::sine(length,maxPartials,6); 00145 } 00146 sample = mySampleMap->getSamples(40); 00147 } 00148 00149 00150 void Sampler::setWave4(int length) { 00151 factoryWaveform = wave4; 00152 mySampleMap->clean(); 00153 for (int n=21; n<109; n++) 00154 { 00155 // find no harmonics; 00156 int maxPartials = freqs->getMaxPartialsFromMidi(n); 00157 mySampleMap->map[n] = Fourier::wave4(length,maxPartials,6); 00158 } 00159 sample = mySampleMap->getSamples(40); 00160 } 00161 00162 00163 void Sampler::setWave1(int length) { 00164 factoryWaveform = wave1; 00165 mySampleMap->clean(); 00166 for (int n=21; n<109; n++) 00167 { 00168 // find no harmonics; 00169 int maxPartials = freqs->getMaxPartialsFromMidi(n); 00170 mySampleMap->map[n] = Fourier::wave1(length,maxPartials,6); 00171 } 00172 sample = mySampleMap->getSamples(40); 00173 } 00174 00175 00176 void Sampler::setWave2(int length) { 00177 factoryWaveform = wave2; 00178 mySampleMap->clean(); 00179 for (int n=21; n<109; n++) 00180 { 00181 // find no harmonics; 00182 int maxPartials = freqs->getMaxPartialsFromMidi(n); 00183 mySampleMap->map[n] = Fourier::wave2(length,maxPartials,6); 00184 } 00185 sample = mySampleMap->getSamples(40); 00186 } 00187 00188 00189 void Sampler::setWave3(int length) { 00190 factoryWaveform = wave4; 00191 mySampleMap->clean(); 00192 for (int n=21; n<109; n++) 00193 { 00194 // find no harmonics; 00195 int maxPartials = freqs->getMaxPartialsFromMidi(n); 00196 mySampleMap->map[n] = Fourier::wave3(length,maxPartials,6); 00197 } 00198 sample = mySampleMap->getSamples(40); 00199 } 00200 00201 00202 void Sampler::resetPhase() { 00203 pos = 0.0f; 00204 } 00205 00206 void Sampler::newMidiEvent() { 00207 freq = hostVoice->getMidiFreq(); 00208 setMidiNote(hostVoice->getMidiNote()); 00209 } 00210 00211 void Sampler::update() { 00212 00213 // Add phase to phase position: 00214 pos += freq / (48000.0f/1024.0f); 00215 00216 // Check wrap-around. 00217 if (pos > 1024.0f) { pos -= 1024.0f; } 00218 00219 00220 //fractpart = (pos - (float) n); 00221 float half = 0.5; 00222 float fractpart ; 00223 float posi = pos; 00224 int n; 00225 00226 // fast float->int conversion 00227 _asm{ 00228 fld posi 00229 fsub half 00230 fistp n ; fist / fistp does NOT round value stored on stack, must reload it. 00231 fild n 00232 fsubr posi 00233 fstp fractpart 00234 } 00235 00236 switch (interpolationType) { 00237 case cubicHermite: 00238 // now do the interpolation 00239 Output1->write( 00240 ((( 00241 ( ( ( ( 3.0f* ( sample[n+1] - sample[n+2])) - sample[n] ) + sample[n+3] ) * 0.5f * fractpart) 00242 + ((2.0f* sample[n+2]) + sample[n]) - (((5.0f* sample[n+1])+ sample[n+3])*0.5f) ) * fractpart) 00243 + ((sample[n+2]-sample[n])*0.5f))*fractpart + sample[n+1] 00244 ); 00245 break; 00246 00247 00248 case spline5Point: 00249 { 00250 float p0 = sample[n]; 00251 float p1 = sample[n+1]; 00252 float p2 = sample[n+2]; 00253 float p3 = sample[n+3]; 00254 float p4 = sample[n+4]; 00255 float p5 = sample[n+5]; 00256 00257 Output1->write( 00258 p2 + 0.04166666666*fractpart*((p3-p1)*16.0+(p0-p4)*2.0 00259 + fractpart *((p3+p1)*16.0-p0-p2*30.0- p4 00260 + fractpart *(p3*66.0-p2*70.0-p4*33.0+p1*39.0+ p5*7.0- p0*9.0 00261 + fractpart *( p2*126.0-p3*124.0+p4*61.0-p1*64.0- p5*12.0+p0*13.0 00262 + fractpart *((p3-p2)*50.0+(p1-p4)*25.0+(p5-p0)*5.0))))) 00263 ); 00264 } 00265 break; 00266 00267 case none: 00268 Output1->write( sample[n] ); 00269 break; 00270 00271 case linear: 00272 Output1->write( fractpart*(sample[n+1]+sample[n])+sample[n] ); 00273 break; 00274 00275 case pureSine: 00276 Output1->write( (float) cos( 2*(pos/1024.0f)*3.14159276) ); 00277 break; 00278 00279 00280 default: 00281 break; 00282 } 00283 00284 if (Output1->read() < MIN) { MIN = Output1->read(); } 00285 if (Output1->read() > MAX) { 00286 MAX = Output1->read(); 00287 std::cout << "--------------------MAX FOUND: " << MAX << " MIN = " << MIN << " AT n = " << n << " | SAMPLE[n] = " << sample[n] 00288 << " pos = " << pos << " posi = " << posi << " fractpart = " << fractpart << std::endl; 00289 } 00290 } 00291 00292 00293 }; // end of namespace: SynthCore Docs made by Doxygen. Email: Mikael Christensen |