[chuck-users] MIDI Synthesizer

z at chickenz.fr z at chickenz.fr
Wed Aug 24 15:55:08 EDT 2011


Hi !

I'm currently having some fun with ChucK and my keyboard, and thought it would
be nice to share my little experiments.
It's a polyphonic synthesizer class that can easily be overridden. Here is an
example:

    Gain g => dac;

    // we create the synthesizer
    Synth synth;

    // connect all its voices to the gain
    synth.connect(g);

    // set the device number
    0 => int device;

    // start the synth
    synth.start(device);

    // and that's all.
    while(true)
        day => now;

There, you have a basic synthesizer with some SinOscs that you can control
with your little MIDI keyboard (or a virtual keyboard connected with jack,
that's your business). There is 20 voices by default, which means you can
press 20 keys at the same time (if you want to use your toes, for example).

Now, you want to add a vibrato and a tremolo, and you want to control them with
a potentiometer or a cursor. No problem !
First, get the identifier of the controls on your MIDI controller (with the
mididump.ck script, for instance).

    Gain g => dac;

    Synth synth;
    // The default synth contains 3 lfos (low frequency oscillators), but you
    // can do what you want with it. The first one is automatically chucked to
    // the oscillators
    synth.connect(g);

    // This class contains some control handlers, and can be easily extended
    MIDIControls ctl;

    // First we want to connect a potentiometer to the first lfo's frequency,
    // and we want it to vary between 0 and 50.
    // My first potentiometer has the codes (176, 75)
    spork ~ ctl.handler_osc_freq(synth.lfo_1, 0, 50, 176, 75);

    // The next potentiometer will be binded to its gain
    // this way, the frequency will vary between f - lfo.gain and f + lfo.gain
    // where f is the frequency of the note pressed
    spork ~ ctl.handler_gain(synth.lfo_1, 0, 50, 176, 76);

    // Then, we are gonna add a tremolo
    // For two oscillators, it's easy to sync the output of the first to the
    // frequency of the other. But to sync an oscillator and a gain, you will
    // need a shred. Fortunately, I made one, it works like that :
    spork ~ modulate_gain(synth.lfo_2, synth.g);
    // The lfo_2 is now connected to the internal gain of the synth

    // And then, we bind two more potentiometers
    spork ~ ctl.handler_osc_freq(synth.lfo_2, 0, 50, 176, 77);
    spork ~ ctl.handler_gain(synth.lfo_2, 0, 7, 176, 78);

    // The synth is where it all happen, where the midi data is fetched and
    // handled.
    // We need to add our new bindings :
    synth.controls(ctl.ctrl);

    synth.start(0);

    while(true)
        day => now;

Now, by extending Synth and MIDIControls, you do all kinds of fun things. One
sinus oscillator per voice is a little flat, so you can change it to a Triosc :

    class TriSynth extends Synth {
        // We can change the envelope
        80::ms => adsr_attack;
        .3 => adsr_sustain;
        30::ms => adsr_release;

        // and the default oscillator type
        fun Osc get_osc() {
            TriOsc s;
            return s;
        }
    }

And then, use it just like the Synth class.

I also did a Synth with more than one Wave per Voice, there is an example in the
source file, and I also did a little video (with a gruesome quality) here:
    http://www.youtube.com/watch?v=FqN11uGK-kI
(also, plotting of the wave's shape with gnuplot)

Finally, I did a looper (not with LiSa, I have channels and sample rate issues
on my computer) that can play some tracks in a loop and do stuff to it.
Unfortunately, there is no recording possible for the moment.
Silly video example here (might cause ear bleeding):
    http://www.youtube.com/watch?v=QRduB9wbj8w

There is lots and lots of possibilities to improve it, and I won't be able to
think about every one of them.
I'm also struggling with the public class system and trying to turn this file
into a library.

My little project could really use some more documentation, but my english is
quite french, so to speak, therefore I'm afraid to induce more confusion than
clarity, but I will try.

The code : https://bitbucket.org/synzack/chuck/src/6d447a4651b4/midi.ck
The repo : https://bitbucket.org/synzack/chuck/


Hope you like it,
 z^ck


More information about the chuck-users mailing list