Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //-------------------------------------------------------------------------------------------------------
- // 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;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement