No, not an lfo…. an not just about me!
After releasing a new Pikobeats firmware for scarp late last year, I was diverted by other things. Hardware. Children. Heating.
An then, much to my delight Vadims (ledlaux) contacted me to let me know that he had built a synth using my Arduino ports of Mutable Instruments code. Now, he had already helped me get more FM engines running in Plaits, and demonstrated another approach to rendering. But this is a whole synth: https://github.com/ledlaux/vija-pico-synth It is polyphonic.
Nice news! This got me back on track with my ’tiny’ modular Mutable Instruments synth, MarvelousMI … here with keep.
Ok, it’s getting there. Keep, which is not tuned to any scale, but by simple even divisions (mixed up with potentiometers) of the incoming timing frequency still sounds kind of in tune :) Plaits chord voice coming from MarvelousMI
But, that wasn’t the first thing the butt-kicking provoked. I finally started implemneting ADSR envelopes everywhere. I had gotten stuck, being a purist. I wanted to use the original envelope implementations from the MI modules. Today, after a last crack at disentangling the envelopes, I realized. Stop it. Now, ledlaux, in his vija-pico-synth had implemented an AD envelope. Butm, I didn’t like it. And that led me to something I had forgotten about, namely Nigel Remon’s nice series on Envelope Generators: beginning with https://www.earlevel.com/main/2013/06/01/envelope-generators/ and ending with his code https://www.earlevel.com/main/2013/06/03/envelope-generators-adsr-code/
In any case, I just used his code :) It’s nice to use. So, if you’re looking for a, c++, implementation what includes going from an exponential to a linear shape and has control of ADSR, try it. An example in arduino (pi pico 2350) land.
#include "ADSR.h"
ADSR *env = new ADSR();
// initialize enveloope settings
env->setAttackRate(.01 * SAMPLERATE); // .01 second
env->setDecayRate(.3 * SAMPLERATE);
env->setReleaseRate(4 * SAMPLERATE);
env->setSustainLevel(.8);
// trigger/gate input
env->gate(true);
// gate off
env->gate(true);
// use the ouput
for (size_t i = 0; i < AUDIO_BLOCK; ++i) {
int16_t sample = (int16_t) ( (float) voice.out_buffer[i].out * env->process() ) ;
shared_buffer[i] = sample;
}
Oh. i haven’t finished the docs yet … (ducks’n’runs) ….. in fact, I’m so behind, I need to weep. Beer first..
Obligatory links to my store sites.
and tindie