summaryrefslogtreecommitdiff
path: root/public.sdk/samples/vst2.x/vstxsynth/source/vstxsynthproc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'public.sdk/samples/vst2.x/vstxsynth/source/vstxsynthproc.cpp')
-rw-r--r--public.sdk/samples/vst2.x/vstxsynth/source/vstxsynthproc.cpp178
1 files changed, 178 insertions, 0 deletions
diff --git a/public.sdk/samples/vst2.x/vstxsynth/source/vstxsynthproc.cpp b/public.sdk/samples/vst2.x/vstxsynth/source/vstxsynthproc.cpp
new file mode 100644
index 0000000..61debac
--- /dev/null
+++ b/public.sdk/samples/vst2.x/vstxsynth/source/vstxsynthproc.cpp
@@ -0,0 +1,178 @@
+//-------------------------------------------------------------------------------------------------------
+// VST Plug-Ins SDK
+// Version 2.4 $Date: 2006/11/13 09:08:27 $
+//
+// Category : VST 2.x SDK Samples
+// Filename : vstxsynthproc.cpp
+// Created by : Steinberg Media Technologies
+// Description : Example VstXSynth
+//
+// A simple 2 oscillators test 'synth',
+// Each oscillator has waveform, frequency, and volume
+//
+// *very* basic monophonic 'synth' example. you should not attempt to use this
+// example 'algorithm' to start a serious virtual instrument; it is intended to demonstrate
+// how VstEvents ('MIDI') are handled, but not how a virtual analog synth works.
+// there are numerous much better examples on the web which show how to deal with
+// bandlimited waveforms etc.
+//
+// © 2006, Steinberg Media Technologies, All Rights Reserved
+//-------------------------------------------------------------------------------------------------------
+
+#include "vstxsynth.h"
+
+enum
+{
+ kNumFrequencies = 128, // 128 midi notes
+ kWaveSize = 4096 // samples (must be power of 2 here)
+};
+
+const double midiScaler = (1. / 127.);
+static float sawtooth[kWaveSize];
+static float pulse[kWaveSize];
+static float freqtab[kNumFrequencies];
+
+//-----------------------------------------------------------------------------------------
+// VstXSynth
+//-----------------------------------------------------------------------------------------
+void VstXSynth::setSampleRate (float sampleRate)
+{
+ AudioEffectX::setSampleRate (sampleRate);
+ fScaler = (float)((double)kWaveSize / (double)sampleRate);
+}
+
+//-----------------------------------------------------------------------------------------
+void VstXSynth::setBlockSize (VstInt32 blockSize)
+{
+ AudioEffectX::setBlockSize (blockSize);
+ // you may need to have to do something here...
+}
+
+//-----------------------------------------------------------------------------------------
+void VstXSynth::initProcess ()
+{
+ fPhase1 = fPhase2 = 0.f;
+ fScaler = (float)((double)kWaveSize / 44100.); // we don't know the sample rate yet
+ noteIsOn = false;
+ currentDelta = currentNote = currentDelta = 0;
+ VstInt32 i;
+
+ // make waveforms
+ VstInt32 wh = kWaveSize / 4; // 1:3 pulse
+ for (i = 0; i < kWaveSize; i++)
+ {
+ sawtooth[i] = (float)(-1. + (2. * ((double)i / (double)kWaveSize)));
+ pulse[i] = (i < wh) ? -1.f : 1.f;
+ }
+
+ // make frequency (Hz) table
+ double k = 1.059463094359; // 12th root of 2
+ double a = 6.875; // a
+ a *= k; // b
+ a *= k; // bb
+ a *= k; // c, frequency of midi note 0
+ for (i = 0; i < kNumFrequencies; i++) // 128 midi notes
+ {
+ freqtab[i] = (float)a;
+ a *= k;
+ }
+}
+
+//-----------------------------------------------------------------------------------------
+void VstXSynth::processReplacing (float** inputs, float** outputs, VstInt32 sampleFrames)
+{
+ float* out1 = outputs[0];
+ float* out2 = outputs[1];
+
+ if (noteIsOn)
+ {
+ float baseFreq = freqtab[currentNote & 0x7f] * fScaler;
+ float freq1 = baseFreq + fFreq1; // not really linear...
+ float freq2 = baseFreq + fFreq2;
+ float* wave1 = (fWaveform1 < .5) ? sawtooth : pulse;
+ float* wave2 = (fWaveform2 < .5) ? sawtooth : pulse;
+ float wsf = (float)kWaveSize;
+ float vol = (float)(fVolume * (double)currentVelocity * midiScaler);
+ VstInt32 mask = kWaveSize - 1;
+
+ if (currentDelta > 0)
+ {
+ if (currentDelta >= sampleFrames) // future
+ {
+ currentDelta -= sampleFrames;
+ return;
+ }
+ memset (out1, 0, currentDelta * sizeof (float));
+ memset (out2, 0, currentDelta * sizeof (float));
+ out1 += currentDelta;
+ out2 += currentDelta;
+ sampleFrames -= currentDelta;
+ currentDelta = 0;
+ }
+
+ // loop
+ while (--sampleFrames >= 0)
+ {
+ // this is all very raw, there is no means of interpolation,
+ // and we will certainly get aliasing due to non-bandlimited
+ // waveforms. don't use this for serious projects...
+ (*out1++) = wave1[(VstInt32)fPhase1 & mask] * fVolume1 * vol;
+ (*out2++) = wave2[(VstInt32)fPhase2 & mask] * fVolume2 * vol;
+ fPhase1 += freq1;
+ fPhase2 += freq2;
+ }
+ }
+ else
+ {
+ memset (out1, 0, sampleFrames * sizeof (float));
+ memset (out2, 0, sampleFrames * sizeof (float));
+ }
+}
+
+//-----------------------------------------------------------------------------------------
+VstInt32 VstXSynth::processEvents (VstEvents* ev)
+{
+ for (VstInt32 i = 0; i < ev->numEvents; i++)
+ {
+ if ((ev->events[i])->type != kVstMidiType)
+ continue;
+
+ VstMidiEvent* event = (VstMidiEvent*)ev->events[i];
+ char* midiData = event->midiData;
+ VstInt32 status = midiData[0] & 0xf0; // ignoring channel
+ if (status == 0x90 || status == 0x80) // we only look at notes
+ {
+ VstInt32 note = midiData[1] & 0x7f;
+ VstInt32 velocity = midiData[2] & 0x7f;
+ if (status == 0x80)
+ velocity = 0; // note off by velocity 0
+ if (!velocity && (note == currentNote))
+ noteOff ();
+ else
+ noteOn (note, velocity, event->deltaFrames);
+ }
+ else if (status == 0xb0)
+ {
+ if (midiData[1] == 0x7e || midiData[1] == 0x7b) // all notes off
+ noteOff ();
+ }
+ event++;
+ }
+ return 1;
+}
+
+//-----------------------------------------------------------------------------------------
+void VstXSynth::noteOn (VstInt32 note, VstInt32 velocity, VstInt32 delta)
+{
+ currentNote = note;
+ currentVelocity = velocity;
+ currentDelta = delta;
+ noteIsOn = true;
+ fPhase1 = fPhase2 = 0;
+}
+
+//-----------------------------------------------------------------------------------------
+void VstXSynth::noteOff ()
+{
+ noteIsOn = false;
+}