summaryrefslogtreecommitdiff
path: root/public.sdk/samples/vst2.x/vstxsynth/source
diff options
context:
space:
mode:
authorpepper <pepper@chimecrisis.com>2015-01-31 21:41:28 -0800
committerpepper <pepper@chimecrisis.com>2015-01-31 21:41:28 -0800
commit97587996ee9db30ce00190bdcedd8210490b99f5 (patch)
treed8554969ac496be3a1b02a159f2a4b5b79f9492e /public.sdk/samples/vst2.x/vstxsynth/source
backup vst 2.4
Diffstat (limited to 'public.sdk/samples/vst2.x/vstxsynth/source')
-rw-r--r--public.sdk/samples/vst2.x/vstxsynth/source/gmnames.h222
-rw-r--r--public.sdk/samples/vst2.x/vstxsynth/source/vstxsynth.cpp392
-rw-r--r--public.sdk/samples/vst2.x/vstxsynth/source/vstxsynth.h139
-rw-r--r--public.sdk/samples/vst2.x/vstxsynth/source/vstxsynthproc.cpp178
4 files changed, 931 insertions, 0 deletions
diff --git a/public.sdk/samples/vst2.x/vstxsynth/source/gmnames.h b/public.sdk/samples/vst2.x/vstxsynth/source/gmnames.h
new file mode 100644
index 0000000..78821fc
--- /dev/null
+++ b/public.sdk/samples/vst2.x/vstxsynth/source/gmnames.h
@@ -0,0 +1,222 @@
+//-------------------------------------------------------------------------------------------------------
+// VST Plug-Ins SDK
+// Version 2.4 $Date: 2006/11/13 09:08:27 $
+//
+// Category : VST 2.x SDK Samples
+// Filename : gmnames.h
+// Created by : Steinberg Media Technologies
+// Description : Example VstXSynth
+//
+// © 2006, Steinberg Media Technologies, All Rights Reserved
+//-------------------------------------------------------------------------------------------------------
+
+#ifndef __gmnames__
+#define __gmnames__
+
+static const long kNumGmCategories = 17;
+
+static const char* GmCategories[kNumGmCategories] =
+{
+ "Piano",
+ "Percussion",
+ "Organ",
+ "Guitar",
+ "Bass",
+ "Strings",
+ "Ensemble",
+ "Brass",
+ "Reed",
+ "Pipe",
+ "Synth Lead",
+ "SynthPad",
+ "Synth Effects",
+ "Ethnic",
+ "Percussive",
+ "Effects",
+ "DrumSets"
+};
+
+static short GmCategoriesFirstIndices [kNumGmCategories + 1] =
+{
+ 0, 7, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128
+};
+
+static const char* GmNames [128] =
+{
+ // Piano
+ "Acoustic Grand Piano",
+ "Bright Acoustic Piano",
+ "Electric Grand Piano",
+ "Honky-tonk Piano",
+ "Electric Piano 1",
+ "Electric Piano 2",
+ "Harpsichord",
+
+ // Percussion
+ "Clavi", // 7
+ "Celesta",
+ "Glockenspiel",
+ "Music Box",
+ "Vibraphone",
+ "Marimba",
+ "Xylophone",
+ "Tubular Bells",
+ "Dulcimer",
+
+ // Organ
+ "Drawbar Organ", // 16
+ "Percussive Organ",
+ "Rock Organ",
+ "Church Organ",
+ "Reed Organ",
+ "Accordion",
+ "Harmonica",
+ "Tango Accordion",
+
+ // Gitar
+ "Acoustic Guitar (nylon)", // 24
+ "Acoustic Guitar (steel)",
+ "Electric Guitar (jazz)",
+ "Electric Guitar (clean)",
+ "Electric Guitar (muted)",
+ "Overdriven Guitar",
+ "Distortion Guitar",
+ "Guitar harmonics",
+
+ // Bass
+ "Acoustic Bass", // 32
+ "Electric Bass (finger)",
+ "Electric Bass (pick)",
+ "Fretless Bass",
+ "Slap Bass 1",
+ "Slap Bass 2",
+ "Synth Bass 1",
+ "Synth Bass 2",
+
+ // strings
+ "Violin", // 40
+ "Viola",
+ "Cello",
+ "Contrabass",
+ "Tremolo Strings",
+ "Pizzicato Strings",
+ "Orchestral Harp",
+ "Timpani",
+
+ // Ensemble
+ "String Ensemble 1", // 48
+ "String Ensemble 2",
+ "SynthStrings 1",
+ "SynthStrings 2",
+ "Choir Aahs",
+ "Voice Oohs",
+ "Synth Voice",
+ "Orchestra Hit",
+
+ // Brass
+ "Trumpet", // 56
+ "Trombone",
+ "Tuba",
+ "Muted Trumpet",
+ "French Horn",
+ "Brass Section",
+ "SynthBrass 1",
+ "SynthBrass 2",
+
+ // Reed
+ "Soprano Sax", // 64
+ "Alto Sax",
+ "Tenor Sax",
+ "Baritone Sax",
+ "Oboe",
+ "English Horn",
+ "Bassoon",
+ "Clarinet",
+
+ // Pipe
+ "Piccolo", // 72
+ "Flute",
+ "Recorder",
+ "Pan Flute",
+ "Blown Bottle",
+ "Shakuhachi",
+ "Whistle",
+ "Ocarina",
+
+ // Synth Lead
+ "Lead 1 (square)", // 80
+ "Lead 2 (sawtooth)",
+ "Lead 3 (calliope)",
+ "Lead 4 (chiff)",
+ "Lead 5 (charang)",
+ "Lead 6 (voice)",
+ "Lead 7 (fifths)",
+ "Lead 8 (bass + lead)",
+
+ // Synth Pad
+ "Pad 1 (new age)", // 88
+ "Pad 2 (warm)",
+ "Pad 3 (polysynth)",
+ "Pad 4 (choir)",
+ "Pad 5 (bowed)",
+ "Pad 6 (metallic)",
+ "Pad 7 (halo)",
+ "Pad 8 (sweep)",
+
+ // Synth Fx
+ "FX 1 (rain)", // 96
+ "FX 2 (soundtrack)",
+ "FX 3 (crystal)",
+ "FX 4 (atmosphere)",
+ "FX 5 (brightness)",
+ "FX 6 (goblins)",
+ "FX 7 (echoes)",
+ "FX 8 (sci-fi)",
+
+ // Ethnic
+ "Sitar", // 104
+ "Banjo",
+ "Shamisen",
+ "Koto",
+ "Kalimba",
+ "Bag pipe",
+ "Fiddle",
+ "Shanai",
+
+ // Percussive
+ "Tinkle Bell", // 112
+ "Agogo",
+ "Steel Drums",
+ "Woodblock",
+ "Taiko Drum",
+ "Melodic Tom",
+ "Synth Drum",
+ "Reverse Cymbal",
+
+ // Effects
+ "Guitar Fret Noise", // 120
+ "Breath Noise",
+ "Seashore",
+ "Bird Tweet",
+ "Telephone Ring",
+ "Helicopter",
+ "Applause",
+ "Gunshot"
+};
+
+static const char* GmDrumSets[11] =
+{
+ "Standard",
+ "Room",
+ "Power",
+ "Electronic",
+ "Analog",
+ "Jazz",
+ "Brush",
+ "Orchestra",
+ "Clavinova",
+ "RX",
+ "C/M"
+};
+
+#endif
diff --git a/public.sdk/samples/vst2.x/vstxsynth/source/vstxsynth.cpp b/public.sdk/samples/vst2.x/vstxsynth/source/vstxsynth.cpp
new file mode 100644
index 0000000..f23cd02
--- /dev/null
+++ b/public.sdk/samples/vst2.x/vstxsynth/source/vstxsynth.cpp
@@ -0,0 +1,392 @@
+//-------------------------------------------------------------------------------------------------------
+// VST Plug-Ins SDK
+// Version 2.4 $Date: 2006/11/13 09:08:27 $
+//
+// Category : VST 2.x SDK Samples
+// Filename : vstxsynth.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"
+#include "gmnames.h"
+
+//-------------------------------------------------------------------------------------------------------
+AudioEffect* createEffectInstance (audioMasterCallback audioMaster)
+{
+ return new VstXSynth (audioMaster);
+}
+
+//-----------------------------------------------------------------------------------------
+// VstXSynthProgram
+//-----------------------------------------------------------------------------------------
+VstXSynthProgram::VstXSynthProgram ()
+{
+ // Default Program Values
+ fWaveform1 = 0.f; // saw
+ fFreq1 =.0f;
+ fVolume1 = .33f;
+
+ fWaveform2 = 1.f; // pulse
+ fFreq2 = .05f; // slightly higher
+ fVolume2 = .33f;
+
+ fVolume = .9f;
+ vst_strncpy (name, "Basic", kVstMaxProgNameLen);
+}
+
+//-----------------------------------------------------------------------------------------
+// VstXSynth
+//-----------------------------------------------------------------------------------------
+VstXSynth::VstXSynth (audioMasterCallback audioMaster)
+: AudioEffectX (audioMaster, kNumPrograms, kNumParams)
+{
+ // initialize programs
+ programs = new VstXSynthProgram[kNumPrograms];
+ for (VstInt32 i = 0; i < 16; i++)
+ channelPrograms[i] = i;
+
+ if (programs)
+ setProgram (0);
+
+ if (audioMaster)
+ {
+ setNumInputs (0); // no inputs
+ setNumOutputs (kNumOutputs); // 2 outputs, 1 for each oscillator
+ canProcessReplacing ();
+ isSynth ();
+ setUniqueID ('VxS2'); // <<<! *must* change this!!!!
+ }
+
+ initProcess ();
+ suspend ();
+}
+
+//-----------------------------------------------------------------------------------------
+VstXSynth::~VstXSynth ()
+{
+ if (programs)
+ delete[] programs;
+}
+
+//-----------------------------------------------------------------------------------------
+void VstXSynth::setProgram (VstInt32 program)
+{
+ if (program < 0 || program >= kNumPrograms)
+ return;
+
+ VstXSynthProgram *ap = &programs[program];
+ curProgram = program;
+
+ fWaveform1 = ap->fWaveform1;
+ fFreq1 = ap->fFreq1;
+ fVolume1 = ap->fVolume1;
+
+ fWaveform2 = ap->fWaveform2;
+ fFreq2 = ap->fFreq2;
+ fVolume2 = ap->fVolume2;
+
+ fVolume = ap->fVolume;
+}
+
+//-----------------------------------------------------------------------------------------
+void VstXSynth::setProgramName (char* name)
+{
+ vst_strncpy (programs[curProgram].name, name, kVstMaxProgNameLen);
+}
+
+//-----------------------------------------------------------------------------------------
+void VstXSynth::getProgramName (char* name)
+{
+ vst_strncpy (name, programs[curProgram].name, kVstMaxProgNameLen);
+}
+
+//-----------------------------------------------------------------------------------------
+void VstXSynth::getParameterLabel (VstInt32 index, char* label)
+{
+ switch (index)
+ {
+ case kWaveform1:
+ case kWaveform2:
+ vst_strncpy (label, "Shape", kVstMaxParamStrLen);
+ break;
+
+ case kFreq1:
+ case kFreq2:
+ vst_strncpy (label, "Hz", kVstMaxParamStrLen);
+ break;
+
+ case kVolume1:
+ case kVolume2:
+ case kVolume:
+ vst_strncpy (label, "dB", kVstMaxParamStrLen);
+ break;
+ }
+}
+
+//-----------------------------------------------------------------------------------------
+void VstXSynth::getParameterDisplay (VstInt32 index, char* text)
+{
+ text[0] = 0;
+ switch (index)
+ {
+ case kWaveform1:
+ if (fWaveform1 < .5)
+ vst_strncpy (text, "Sawtooth", kVstMaxParamStrLen);
+ else
+ vst_strncpy (text, "Pulse", kVstMaxParamStrLen);
+ break;
+
+ case kFreq1: float2string (fFreq1, text, kVstMaxParamStrLen); break;
+ case kVolume1: dB2string (fVolume1, text, kVstMaxParamStrLen); break;
+
+ case kWaveform2:
+ if (fWaveform2 < .5)
+ vst_strncpy (text, "Sawtooth", kVstMaxParamStrLen);
+ else
+ vst_strncpy (text, "Pulse", kVstMaxParamStrLen);
+ break;
+
+ case kFreq2: float2string (fFreq2, text, kVstMaxParamStrLen); break;
+ case kVolume2: dB2string (fVolume2, text, kVstMaxParamStrLen); break;
+ case kVolume: dB2string (fVolume, text, kVstMaxParamStrLen); break;
+ }
+}
+
+//-----------------------------------------------------------------------------------------
+void VstXSynth::getParameterName (VstInt32 index, char* label)
+{
+ switch (index)
+ {
+ case kWaveform1: vst_strncpy (label, "Wave 1", kVstMaxParamStrLen); break;
+ case kFreq1: vst_strncpy (label, "Freq 1", kVstMaxParamStrLen); break;
+ case kVolume1: vst_strncpy (label, "Levl 1", kVstMaxParamStrLen); break;
+ case kWaveform2: vst_strncpy (label, "Wave 2", kVstMaxParamStrLen); break;
+ case kFreq2: vst_strncpy (label, "Freq 2", kVstMaxParamStrLen); break;
+ case kVolume2: vst_strncpy (label, "Levl 2", kVstMaxParamStrLen); break;
+ case kVolume: vst_strncpy (label, "Volume", kVstMaxParamStrLen); break;
+ }
+}
+
+//-----------------------------------------------------------------------------------------
+void VstXSynth::setParameter (VstInt32 index, float value)
+{
+ VstXSynthProgram *ap = &programs[curProgram];
+ switch (index)
+ {
+ case kWaveform1: fWaveform1 = ap->fWaveform1 = value; break;
+ case kFreq1: fFreq1 = ap->fFreq1 = value; break;
+ case kVolume1: fVolume1 = ap->fVolume1 = value; break;
+ case kWaveform2: fWaveform2 = ap->fWaveform2 = value; break;
+ case kFreq2: fFreq2 = ap->fFreq2 = value; break;
+ case kVolume2: fVolume2 = ap->fVolume2 = value; break;
+ case kVolume: fVolume = ap->fVolume = value; break;
+ }
+}
+
+//-----------------------------------------------------------------------------------------
+float VstXSynth::getParameter (VstInt32 index)
+{
+ float value = 0;
+ switch (index)
+ {
+ case kWaveform1: value = fWaveform1; break;
+ case kFreq1: value = fFreq1; break;
+ case kVolume1: value = fVolume1; break;
+ case kWaveform2: value = fWaveform2; break;
+ case kFreq2: value = fFreq2; break;
+ case kVolume2: value = fVolume2; break;
+ case kVolume: value = fVolume; break;
+ }
+ return value;
+}
+
+//-----------------------------------------------------------------------------------------
+bool VstXSynth::getOutputProperties (VstInt32 index, VstPinProperties* properties)
+{
+ if (index < kNumOutputs)
+ {
+ vst_strncpy (properties->label, "Vstx ", 63);
+ char temp[11] = {0};
+ int2string (index + 1, temp, 10);
+ vst_strncat (properties->label, temp, 63);
+
+ properties->flags = kVstPinIsActive;
+ if (index < 2)
+ properties->flags |= kVstPinIsStereo; // make channel 1+2 stereo
+ return true;
+ }
+ return false;
+}
+
+//-----------------------------------------------------------------------------------------
+bool VstXSynth::getProgramNameIndexed (VstInt32 category, VstInt32 index, char* text)
+{
+ if (index < kNumPrograms)
+ {
+ vst_strncpy (text, programs[index].name, kVstMaxProgNameLen);
+ return true;
+ }
+ return false;
+}
+
+//-----------------------------------------------------------------------------------------
+bool VstXSynth::getEffectName (char* name)
+{
+ vst_strncpy (name, "VstXSynth", kVstMaxEffectNameLen);
+ return true;
+}
+
+//-----------------------------------------------------------------------------------------
+bool VstXSynth::getVendorString (char* text)
+{
+ vst_strncpy (text, "Steinberg Media Technologies", kVstMaxVendorStrLen);
+ return true;
+}
+
+//-----------------------------------------------------------------------------------------
+bool VstXSynth::getProductString (char* text)
+{
+ vst_strncpy (text, "Vst Test Synth", kVstMaxProductStrLen);
+ return true;
+}
+
+//-----------------------------------------------------------------------------------------
+VstInt32 VstXSynth::getVendorVersion ()
+{
+ return 1000;
+}
+
+//-----------------------------------------------------------------------------------------
+VstInt32 VstXSynth::canDo (char* text)
+{
+ if (!strcmp (text, "receiveVstEvents"))
+ return 1;
+ if (!strcmp (text, "receiveVstMidiEvent"))
+ return 1;
+ if (!strcmp (text, "midiProgramNames"))
+ return 1;
+ return -1; // explicitly can't do; 0 => don't know
+}
+
+//-----------------------------------------------------------------------------------------
+VstInt32 VstXSynth::getNumMidiInputChannels ()
+{
+ return 1; // we are monophonic
+}
+
+//-----------------------------------------------------------------------------------------
+VstInt32 VstXSynth::getNumMidiOutputChannels ()
+{
+ return 0; // no MIDI output back to Host app
+}
+
+// midi program names:
+// as an example, GM names are used here. in fact, VstXSynth doesn't even support
+// multi-timbral operation so it's really just for demonstration.
+// a 'real' instrument would have a number of voices which use the
+// programs[channelProgram[channel]] parameters when it receives
+// a note on message.
+
+//------------------------------------------------------------------------
+VstInt32 VstXSynth::getMidiProgramName (VstInt32 channel, MidiProgramName* mpn)
+{
+ VstInt32 prg = mpn->thisProgramIndex;
+ if (prg < 0 || prg >= 128)
+ return 0;
+ fillProgram (channel, prg, mpn);
+ if (channel == 9)
+ return 1;
+ return 128L;
+}
+
+//------------------------------------------------------------------------
+VstInt32 VstXSynth::getCurrentMidiProgram (VstInt32 channel, MidiProgramName* mpn)
+{
+ if (channel < 0 || channel >= 16 || !mpn)
+ return -1;
+ VstInt32 prg = channelPrograms[channel];
+ mpn->thisProgramIndex = prg;
+ fillProgram (channel, prg, mpn);
+ return prg;
+}
+
+//------------------------------------------------------------------------
+void VstXSynth::fillProgram (VstInt32 channel, VstInt32 prg, MidiProgramName* mpn)
+{
+ mpn->midiBankMsb =
+ mpn->midiBankLsb = -1;
+ mpn->reserved = 0;
+ mpn->flags = 0;
+
+ if (channel == 9) // drums
+ {
+ vst_strncpy (mpn->name, "Standard", 63);
+ mpn->midiProgram = 0;
+ mpn->parentCategoryIndex = 0;
+ }
+ else
+ {
+ vst_strncpy (mpn->name, GmNames[prg], 63);
+ mpn->midiProgram = (char)prg;
+ mpn->parentCategoryIndex = -1; // for now
+
+ for (VstInt32 i = 0; i < kNumGmCategories; i++)
+ {
+ if (prg >= GmCategoriesFirstIndices[i] && prg < GmCategoriesFirstIndices[i + 1])
+ {
+ mpn->parentCategoryIndex = i;
+ break;
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+VstInt32 VstXSynth::getMidiProgramCategory (VstInt32 channel, MidiProgramCategory* cat)
+{
+ cat->parentCategoryIndex = -1; // -1:no parent category
+ cat->flags = 0; // reserved, none defined yet, zero.
+ VstInt32 category = cat->thisCategoryIndex;
+ if (channel == 9)
+ {
+ vst_strncpy (cat->name, "Drums", 63);
+ return 1;
+ }
+ if (category >= 0 && category < kNumGmCategories)
+ vst_strncpy (cat->name, GmCategories[category], 63);
+ else
+ cat->name[0] = 0;
+ return kNumGmCategories;
+}
+
+//------------------------------------------------------------------------
+bool VstXSynth::hasMidiProgramsChanged (VstInt32 channel)
+{
+ return false; // updateDisplay ()
+}
+
+//------------------------------------------------------------------------
+bool VstXSynth::getMidiKeyName (VstInt32 channel, MidiKeyName* key)
+ // struct will be filled with information for 'thisProgramIndex' and 'thisKeyNumber'
+ // if keyName is "" the standard name of the key will be displayed.
+ // if false is returned, no MidiKeyNames defined for 'thisProgramIndex'.
+{
+ // key->thisProgramIndex; // >= 0. fill struct for this program index.
+ // key->thisKeyNumber; // 0 - 127. fill struct for this key number.
+ key->keyName[0] = 0;
+ key->reserved = 0; // zero
+ key->flags = 0; // reserved, none defined yet, zero.
+ return false;
+}
diff --git a/public.sdk/samples/vst2.x/vstxsynth/source/vstxsynth.h b/public.sdk/samples/vst2.x/vstxsynth/source/vstxsynth.h
new file mode 100644
index 0000000..6212cac
--- /dev/null
+++ b/public.sdk/samples/vst2.x/vstxsynth/source/vstxsynth.h
@@ -0,0 +1,139 @@
+//-------------------------------------------------------------------------------------------------------
+// VST Plug-Ins SDK
+// Version 2.4 $Date: 2006/11/13 09:08:27 $
+//
+// Category : VST 2.x SDK Samples
+// Filename : vstxsynth.h
+// 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
+//-------------------------------------------------------------------------------------------------------
+
+#ifndef __vstxsynth__
+#define __vstxsynth__
+
+#include "public.sdk/source/vst2.x/audioeffectx.h"
+
+//------------------------------------------------------------------------------------------
+enum
+{
+ // Global
+ kNumPrograms = 128,
+ kNumOutputs = 2,
+
+ // Parameters Tags
+ kWaveform1 = 0,
+ kFreq1,
+ kVolume1,
+
+ kWaveform2,
+ kFreq2,
+ kVolume2,
+
+ kVolume,
+
+ kNumParams
+};
+
+//------------------------------------------------------------------------------------------
+// VstXSynthProgram
+//------------------------------------------------------------------------------------------
+class VstXSynthProgram
+{
+friend class VstXSynth;
+public:
+ VstXSynthProgram ();
+ ~VstXSynthProgram () {}
+
+private:
+ float fWaveform1;
+ float fFreq1;
+ float fVolume1;
+
+ float fWaveform2;
+ float fFreq2;
+ float fVolume2;
+
+ float fVolume;
+ char name[kVstMaxProgNameLen+1];
+};
+
+//------------------------------------------------------------------------------------------
+// VstXSynth
+//------------------------------------------------------------------------------------------
+class VstXSynth : public AudioEffectX
+{
+public:
+ VstXSynth (audioMasterCallback audioMaster);
+ ~VstXSynth ();
+
+ virtual void processReplacing (float** inputs, float** outputs, VstInt32 sampleFrames);
+ virtual VstInt32 processEvents (VstEvents* events);
+
+ virtual void setProgram (VstInt32 program);
+ virtual void setProgramName (char* name);
+ virtual void getProgramName (char* name);
+ virtual bool getProgramNameIndexed (VstInt32 category, VstInt32 index, char* text);
+
+ virtual void setParameter (VstInt32 index, float value);
+ virtual float getParameter (VstInt32 index);
+ virtual void getParameterLabel (VstInt32 index, char* label);
+ virtual void getParameterDisplay (VstInt32 index, char* text);
+ virtual void getParameterName (VstInt32 index, char* text);
+
+ virtual void setSampleRate (float sampleRate);
+ virtual void setBlockSize (VstInt32 blockSize);
+
+ virtual bool getOutputProperties (VstInt32 index, VstPinProperties* properties);
+
+ virtual bool getEffectName (char* name);
+ virtual bool getVendorString (char* text);
+ virtual bool getProductString (char* text);
+ virtual VstInt32 getVendorVersion ();
+ virtual VstInt32 canDo (char* text);
+
+ virtual VstInt32 getNumMidiInputChannels ();
+ virtual VstInt32 getNumMidiOutputChannels ();
+
+ virtual VstInt32 getMidiProgramName (VstInt32 channel, MidiProgramName* midiProgramName);
+ virtual VstInt32 getCurrentMidiProgram (VstInt32 channel, MidiProgramName* currentProgram);
+ virtual VstInt32 getMidiProgramCategory (VstInt32 channel, MidiProgramCategory* category);
+ virtual bool hasMidiProgramsChanged (VstInt32 channel);
+ virtual bool getMidiKeyName (VstInt32 channel, MidiKeyName* keyName);
+
+private:
+ float fWaveform1;
+ float fFreq1;
+ float fVolume1;
+ float fWaveform2;
+ float fFreq2;
+ float fVolume2;
+ float fVolume;
+ float fPhase1, fPhase2;
+ float fScaler;
+
+ VstXSynthProgram* programs;
+ VstInt32 channelPrograms[16];
+
+ VstInt32 currentNote;
+ VstInt32 currentVelocity;
+ VstInt32 currentDelta;
+ bool noteIsOn;
+
+ void initProcess ();
+ void noteOn (VstInt32 note, VstInt32 velocity, VstInt32 delta);
+ void noteOff ();
+ void fillProgram (VstInt32 channel, VstInt32 prg, MidiProgramName* mpn);
+};
+
+#endif
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;
+}