vsariola / sointu

Fork of 4klang that can target 386, amd64 and WebAssembly. Tools run on Windows, Mac & Linux
MIT License
250 stars 17 forks source link

Retrigger switch on oscillators? #147

Open LeStahL opened 1 week ago

LeStahL commented 1 week ago

Would it be possible to add a "retrigger" switch to oscillators, that allows non-retriggered LFOs without using an envelope-less instrument?

vsariola commented 1 week ago

Not really, not at least easily. Whenever there is a new note, the entire workspace (i.e. all state of all units) is wiped with a single rep stosd. The only exception is the delay lines, which use a different workspace to store the delay buffer, but the whole thing is such a kludge that I am worried what happens if we start storing the oscillator state there. And then it becomes a question how do we control this per oscillator (wipe, no wipe).

The usual solution is to put the LFOs in Global and send the signal elsewhere.

vsariola commented 1 week ago

There's also the additional difficulty here that we are really out of flags at the moment: oscillator has a single flag byte argument, where:

bit 7 = sample based oscillator bit 6 = sinewave bit 5 = trisaw bit 4 = pulse bit 3 = lfo enabled bit 2 = gate bits 0 - 1 = number of unisons

Now, the flags are extremely wasteful: only one of bits 2, 4, 5, 6, or 7 is ever set. But it was done like this to have maximal compressibility: this makes 0x40 (which is also 64 aka neutral value for most oscillators) indicate that the oscillator is sine, which should also be a pretty common occurrence, and also 0x20 correspond to trisaw etc.

This can be changed, to make room for one more toggleable flag, but we should really be careful to not increase size of prods. This goes back to 4klang and it looked a bit weird when I saw it, but I assume gopher did it with a good purpose (compressibility).