logo
Main Page | Namespaces | Classes | Compounds | Files | Compound Members | Related

sampler.cpp

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

Syntopia Project. Visit the web page, or the SourceForge page.
Docs made by Doxygen. Email: Mikael Christensen