Question

I am having trouble understanding a particular area of code in the Steinberg VST Synth example

In this function:


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));
}

}

The way I understand the function is that if a midi note is currently on, we need to copy our wave table into the outputs array to pass back to the VstHost. What I don't understand specifically is what the area in the

if (currentDelta > 0)
conditional block is doing. It seems like its just writing zeros to the output arrays...

A full version of the file can be found at http://pastebin.com/SdAXkRyW

Was it helpful?

Solution

The incomming MIDI NoteOn event can have an offset relative to the start of the buffers you receive (called deltaFrames). The currentDelta keeps track of when the note should play relative to the start of the buffers received.

So if the currentDelta > sampleFrames, that means the note should not play in this cycle (future) - early exit.

If the currentDelta is within range of this cycle then the memory is cleared up to the moment the note should produce output (memset) and the pointers are manipulated to make it look like the buffers begin right on the spot where the sound should play - length -sampleFrames- is also adjusted.

Then in the loop the sound is produced.

Hope it helps. Marc

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top