Breakpoint demolog, day 9

Another day working on the synth. It's shaping out quite nicely, I think. Which is a bit of a pun since I have added some wave shaping features today :-P

Today's new features:

Implemented velocity support i.e. note volumes! Hooray for sound dynamics!

Added wave mix parameter

What this does is simply decide how the two oscillators are mixed together. The default is Add - i.e. just adds both channels together. There's also substract, which is like the values of OSC1 minus the values of OSC2, and multiply (OSC1*OSC2) and the craziest one, divide! This one generates quite strange/distorted sounds. I had been wanting to do something like this in the previous incarnation of this synth, but had to postpone it for later. Well, the time has come!

Added noise

For now it's just white noise (I think it is white noise... I'm generating it with rand(); I'm not sure about its probabilistic distribution). I might look into different colours later.

The way the noise is mixed with the oscillators can also be controlled with the noise mix parameter, a bit like the way the oscillators can be shaped. I.e. noise can be added, mixed (proportion/amount is controllable too), or multiply the previous mix.

The noise will be handy for building hi hat and snare sounds -- once I have the envelopes fully in place!

Added envelopes

I have ported and slightly optimised the envelope code I had, but I still haven't had time to hook the envelopes into the synth. That'll be a thing for tomorrow.

In the meantime, I have devised a way for keeping track of which position we are in (sample and time based). The relevance of this is that when jamming with the synth (i.e. with Renoise not playing anything), the VSTi host doesn't update the sample position values. So no envelope at all would get updated if I was depending on those values (which would be zero all the time). Obviously I can't use time() like before, because that would make operations like rendering to WAV totally buggy due to wrong envelope updating.

This is the key snippet for getting the current time:


float SorolletVoice::getTime()
{
    float time;

    if(mlfCurrentSamplePosition == 0.0f)
    {
        if(mlfInternalSamplePosition > 0.0f)
        {
            time = mlfInternalSamplePosition * mfInvSampleRate;
        }
        else
        {
            time = 0.0f;
        }
    }
    else
    {
        time = mfCurrentTime;
    }
    return time;
}

mlfCurrentSamplePosition is retrieved from the VST host, with the getTimeInfo function. mlfInternalSamplePosition is the internal count that I update each time a buffer is requested. I'm not sure if this is the best solution, but when playing, both values were identical, so I guess/hope/expect I'm doing things right.

Super screenshot of the parameters: Sorollet VST 20100210

And another sample sound, this time playing with noise and wave-shaped waves.