diff options
Diffstat (limited to 'vendor/vstsdk2.4/public.sdk/samples/vst2.x/vstxsynth/source/vstxsynthproc.cpp')
| -rw-r--r-- | vendor/vstsdk2.4/public.sdk/samples/vst2.x/vstxsynth/source/vstxsynthproc.cpp | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/vendor/vstsdk2.4/public.sdk/samples/vst2.x/vstxsynth/source/vstxsynthproc.cpp b/vendor/vstsdk2.4/public.sdk/samples/vst2.x/vstxsynth/source/vstxsynthproc.cpp new file mode 100644 index 0000000..61debac --- /dev/null +++ b/vendor/vstsdk2.4/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; +} |
