Advertisement
Guest User

vstxsynthproc.cpp

a guest
Nov 5th, 2013
223
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.52 KB | None | 0 0
  1. //-------------------------------------------------------------------------------------------------------
  2. // VST Plug-Ins SDK
  3. // Version 2.4      $Date: 2006/11/13 09:08:27 $
  4. //
  5. // Category     : VST 2.x SDK Samples
  6. // Filename     : vstxsynthproc.cpp
  7. // Created by   : Steinberg Media Technologies
  8. // Description  : Example VstXSynth
  9. //
  10. // A simple 2 oscillators test 'synth',
  11. // Each oscillator has waveform, frequency, and volume
  12. //
  13. // *very* basic monophonic 'synth' example. you should not attempt to use this
  14. // example 'algorithm' to start a serious virtual instrument; it is intended to demonstrate
  15. // how VstEvents ('MIDI') are handled, but not how a virtual analog synth works.
  16. // there are numerous much better examples on the web which show how to deal with
  17. // bandlimited waveforms etc.
  18. //
  19. // © 2006, Steinberg Media Technologies, All Rights Reserved
  20. //-------------------------------------------------------------------------------------------------------
  21.  
  22. #include "vstxsynth.h"
  23.  
  24. enum
  25. {
  26.     kNumFrequencies = 128// 128 midi notes
  27.     kWaveSize = 4096        // samples (must be power of 2 here)
  28. };
  29.  
  30. const double midiScaler = (1. / 127.);
  31. static float sawtooth[kWaveSize];
  32. static float pulse[kWaveSize];
  33. static float freqtab[kNumFrequencies];
  34.  
  35. //-----------------------------------------------------------------------------------------
  36. // VstXSynth
  37. //-----------------------------------------------------------------------------------------
  38. void VstXSynth::setSampleRate (float sampleRate)
  39. {
  40.     AudioEffectX::setSampleRate (sampleRate);
  41.     fScaler = (float)((double)kWaveSize / (double)sampleRate);
  42. }
  43.  
  44. //-----------------------------------------------------------------------------------------
  45. void VstXSynth::setBlockSize (VstInt32 blockSize)
  46. {
  47.     AudioEffectX::setBlockSize (blockSize);
  48.     // you may need to have to do something here...
  49. }
  50.  
  51. //-----------------------------------------------------------------------------------------
  52. void VstXSynth::initProcess ()
  53. {
  54.     fPhase1 = fPhase2 = 0.f;
  55.     fScaler = (float)((double)kWaveSize / 44100.);  // we don't know the sample rate yet
  56.     noteIsOn = false;
  57.     currentDelta = currentNote = currentDelta = 0;
  58.     VstInt32 i;
  59.  
  60.     // make waveforms
  61.     VstInt32 wh = kWaveSize / 4;    // 1:3 pulse
  62.     for (i = 0; i < kWaveSize; i++)
  63.     {
  64.         sawtooth[i] = (float)(-1. + (2. * ((double)i / (double)kWaveSize)));
  65.         pulse[i] = (i < wh) ? -1.f : 1.f;
  66.     }
  67.  
  68.     // make frequency (Hz) table
  69.     double k = 1.059463094359;  // 12th root of 2
  70.     double a = 6.875;   // a
  71.     a *= k; // b
  72.     a *= k; // bb
  73.     a *= k; // c, frequency of midi note 0
  74.     for (i = 0; i < kNumFrequencies; i++)   // 128 midi notes
  75.     {
  76.         freqtab[i] = (float)a;
  77.         a *= k;
  78.     }
  79. }
  80.  
  81. //-----------------------------------------------------------------------------------------
  82. void VstXSynth::processReplacing (float** inputs, float** outputs, VstInt32 sampleFrames)
  83. {
  84.     float* out1 = outputs[0];
  85.     float* out2 = outputs[1];
  86.  
  87.     if (noteIsOn)
  88.     {
  89.         float baseFreq = freqtab[currentNote & 0x7f] * fScaler;
  90.         float freq1 = baseFreq + fFreq1;    // not really linear...
  91.         float freq2 = baseFreq + fFreq2;
  92.         float* wave1 = (fWaveform1 < .5) ? sawtooth : pulse;
  93.         float* wave2 = (fWaveform2 < .5) ? sawtooth : pulse;
  94.         float wsf = (float)kWaveSize;
  95.         float vol = (float)(fVolume * (double)currentVelocity * midiScaler);
  96.         VstInt32 mask = kWaveSize - 1;
  97.        
  98.         if (currentDelta > 0)
  99.         {
  100.             if (currentDelta >= sampleFrames)   // future
  101.             {
  102.                 currentDelta -= sampleFrames;
  103.                 return;
  104.             }
  105.             memset (out1, 0, currentDelta * sizeof (float));
  106.             memset (out2, 0, currentDelta * sizeof (float));
  107.             out1 += currentDelta;
  108.             out2 += currentDelta;
  109.             sampleFrames -= currentDelta;
  110.             currentDelta = 0;
  111.         }
  112.  
  113.         // loop
  114.         while (--sampleFrames >= 0)
  115.         {
  116.             // this is all very raw, there is no means of interpolation,
  117.             // and we will certainly get aliasing due to non-bandlimited
  118.             // waveforms. don't use this for serious projects...
  119.             (*out1++) = wave1[(VstInt32)fPhase1 & mask] * fVolume1 * vol;
  120.             (*out2++) = wave2[(VstInt32)fPhase2 & mask] * fVolume2 * vol;
  121.             fPhase1 += freq1;
  122.             fPhase2 += freq2;
  123.         }
  124.     }                      
  125.     else
  126.     {
  127.         memset (out1, 0, sampleFrames * sizeof (float));
  128.         memset (out2, 0, sampleFrames * sizeof (float));
  129.     }
  130. }
  131.  
  132. //-----------------------------------------------------------------------------------------
  133. VstInt32 VstXSynth::processEvents (VstEvents* ev)
  134. {
  135.     for (VstInt32 i = 0; i < ev->numEvents; i++)
  136.     {
  137.         if ((ev->events[i])->type != kVstMidiType)
  138.             continue;
  139.  
  140.         VstMidiEvent* event = (VstMidiEvent*)ev->events[i];
  141.         char* midiData = event->midiData;
  142.         VstInt32 status = midiData[0] & 0xf0;   // ignoring channel
  143.         if (status == 0x90 || status == 0x80)   // we only look at notes
  144.         {
  145.             VstInt32 note = midiData[1] & 0x7f;
  146.             VstInt32 velocity = midiData[2] & 0x7f;
  147.             if (status == 0x80)
  148.                 velocity = 0;   // note off by velocity 0
  149.             if (!velocity && (note == currentNote))
  150.                 noteOff ();
  151.             else
  152.                 noteOn (note, velocity, event->deltaFrames);
  153.         }
  154.         else if (status == 0xb0)
  155.         {
  156.             if (midiData[1] == 0x7e || midiData[1] == 0x7b) // all notes off
  157.                 noteOff ();
  158.         }
  159.         event++;
  160.     }
  161.     return 1;
  162. }
  163.  
  164. //-----------------------------------------------------------------------------------------
  165. void VstXSynth::noteOn (VstInt32 note, VstInt32 velocity, VstInt32 delta)
  166. {
  167.     currentNote = note;
  168.     currentVelocity = velocity;
  169.     currentDelta = delta;
  170.     noteIsOn = true;
  171.     fPhase1 = fPhase2 = 0;
  172. }
  173.  
  174. //-----------------------------------------------------------------------------------------
  175. void VstXSynth::noteOff ()
  176. {
  177.     noteIsOn = false;
  178. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement