Skip to content

99 Firmware Reference

Scott Wilson edited this page Nov 26, 2020 · 4 revisions

CLASSES

Clocks

Clocks represent a beat-based device that can be used to drive any device that requires beats and/or a regular clock signal. Note that not all devices require clocks, but those that do are typically sequencers, triggers, or synchronized LFOs of some sort.

Any number of independent clocks may be defined in a C++ sketch, but only one clock per program is supported using JSON notation.

FixedClock

Represents a beat clock that has a fixed tempo and a given number of beats per measure or phrase.

Parameter Description
tempo tempo per division in BPM
beats divisions per measure/phrase
JSON
{
        "type" : "FixedClock",
        "tempo" : 120,
        "beats" : 16            
}
C++
Clock* FixedClock::create(tempo, beats);

RandomTempoClock

The RandomTempoClock is a clock whose tempo varies randomly within a specified range from measure to measure. With more extreme settings you can easily achieve a drunken walk. At more subtle settings, the clock produces a more human feel where the tempo will change by only a BPM or two from measure to measure.

Parameter Description
minTempo minimum tempo per division in BPM
maxTempo maximum tempo per division in BPM
beats divisions per measure/phrase
JSON
{
        "type" : "RandomTempoClock",
        "minTempo" : 30,
        "maxTempo" : 240,
        "beats" : 16            
 },
C++
Clock* randomclock = RandomTempoClock::create(40, 100, 8);

VariableClock

The VariableClock is a clock whose tempo is voltage controlled and can vary from a minimum value to a maximum value.

Parameter Description
minTempo minimum tempo per division in BPM
maxTempo maximum tempo per division in BPM
tempoInput analog input for tempo voltage control
beats divisions per measure/phrase

JSON

{
        "type" : "VariableClock",
        "minTempo" : 30,
        "maxTempo" : 240,
        "tempoInput" : 1,
        "beats" : 16            
},

C++

Clock* c = VariableClock::create(25, 525, DUE_IN_A00, 16);

Devices

ByteBeat

The Bytebeat device is an oscillator that generates sounds using a small C function that uses bitwise logic and math. The sounds can range from noisy and glitchy to something not unlike a chiptune osc. There is currently only a limited selection of algorithms, but they can easily be added if you take a look at the MW thread.

Audio Sample

Parameter Description
dacOutput Audio jack to use for output
sampleRate Input to use for sample frequency
analogInput1 Optional. Input to use for parameter 1
analogInput2 Optional. Input to use for parameter 2
analogInput3 Optional. Input to use for parameter 3
algorithm Index of algorithm to use
offset Sample offset. Useful when you have two oscs with the same parameters for stereo spread.
JSON
    {
        "type" : "ByteBeat",
        "dacOutput" : 1,
        "sampleRate" : 1,
        "analogInput1" : 2,
        "analogInput2" : 3,
        "analogInput3" : 4,
        "algorithm" : 1,
        "offset" : 1
    }       
C++
VCO* bytebeat0 = ByteBeat::create(DUE_DAC0, DUE_IN_A00, 0, DUE_IN_A02, DUE_IN_A04, DUE_IN_A06, 0);

CVNoteSequencer

CVNoteSequencer is a voltage-controlled sequencer whose sequence index is determined by a control voltage between 0 and 5V. This means that you can “play” a sequence manually, using one of the analog inputs, just as if you were dragging a bow across a string. This sequencer is very playable and could benefit from any number of continuous CV-generation devices – ribbons, mod wheels, pedals, thermometers, etc.

The sequencer is setup just like a standard NoteSequencer, but rather than a clock division value, an analog input is defined.

Voltage Controlled Sequencer Audio Sample

This demo consists of the JSON example below with the CV output routed to a Z3000mII. The sin signal is routed to an Intellijel µfold. The trigger output is routed to a Function which is then modulating the µfold. All of this is then coated in a hefty portion of delay and reverb.

As the notes change, you can hear that the triggered Function initiates a slow modulation in the harmonic content of the signal.

Voltage Controlled Sequencer Audio Sample 2

The second demo is also included in the sample JSON files, but is routed slightly differently. Rather than manually modulating the CV input, a Dixie in a very slow LFO mode is routed to the analog input, attenuated and modulates the position of the sequence. When a note change is triggered, a gate signal goes out on digital 01 and is routed to an ADSR which is sent to a VCA. The note CV output is sent to an E350 Morphing Terrarium which is then also sent to a slightly overdriven SeM20 before recording and having some delay and reverb added.

Parameter Description
analogOutput Analog output to use for CV output
analogInput Analog input for CV control of the sequence postion
gateOutput Optional. Digital output to use for note triggers
gateDuration Optional. Duration in milliseconds of gate output
root Scale root note
scale Scale name
randomize specifies whether or not the notes sequence should be played in random order
notes sequence of notes for the note sequencer
JSON
    {
        "type" : "CVNoteSequencer",
        "analogOutput" : 2,
        "analogInput" : 1,
        "gateOutput" : 1,
        "gateLength" : 125,
        "root" : "C",
        "scale" : "major",
        "randomize" : false,
        "notes" : [
 
            [1,1], [1,3], [1,5], [1,1],
            [1,3], [1,5], [1,1], [1,5],
            [2,1], [2,3], [2,5], [2,1],
            [2,3], [2,5], [2,1], [2,5],
            [3,1], [3,3], [3,5], [3,1],
            [3,3], [3,5], [3,1], [3,5]
 
        ]
    }       
C++
    /* Set up the note data for the sequence */
    SequenceNote notelist[34] = { {1,1}, {1,3}, {1,5}, {1,1}, {1,3}, {1,5}, {1,1}, {1,5}, 
                                  {2,1}, {2,3}, {2,5}, {2,1}, {2,3}, {2,5}, {2,1}, {2,5}, 
                                  {3,1}, {3,3}, {3,5}, {3,1}, {3,3}, {3,5}, {3,1}, {3,5}, 
                                  {4,1}, {4,3}, {4,5}, {4,1}, {4,3}, {4,5}, {4,1}, {5,1} };
 
    /* Add the raw array to a vector for easier transport */
    NoteSequenceData* notes = new NoteSequenceData(notelist, notelist + 34);
 
    /* Build our note-based seuqnce */
    Sequencer* sequencer = CVNoteSequencer::create(notes, C, MAJOR, DUE_SPI_4822_02, DUE_IN_A02);

CVSequencer

The CVSequencer is your run-of-the-mill CV sequencer. Or not. The CVSequencer can operate as a clocked sequencer operating over a number of preset voltages. The preset list of voltages may be randomized, but fixed values, or it may generate completely random voltages over a specified range.

Parameter Description
analogOutput Analog output to use for CV output
gateOutput Optional. Digital output to use for note triggers
gateDuration Optional. Duration in milliseconds of gate output
division note division where quarter notes are equal to clock ticks
randomize specifies whether or not the notes sequence should be played in random order
values sequence of integer millivolt values for the note sequencer
min minimum value when used as a random CV
max maximum value when used as a random CV
JSON
        {
            "type" : "CVSequencer",
            "division" : "sixteenth",
            "analogOutput" : 2,
            "randomize" : false,
            "gateOutput" : 1,
            "gateLength" : 20,
            "values" : [
 
                0, 1000, 2000, 3000, 4000, 5000
 
            ]
        },
 
        {
            "type" : "CVSequencer",
            "division" : "triplet eighth",
            "analogOutput" : 3,
            "gateOutput" : 2,
            "gateLength" : 125,
            "min" : 0,
            "max" : 5000
        }       
C++
Sequencer* cvsequencer = CVSequencer::create(800, 1000, DIV_QUARTER, DUE_SPI_4822_03);

DiscreteNoise

DiscreteNoise is an oscillator that generates signal with random values that change at a variable sample rate. The resulting sound is very chiptune-y.

Discrete Noise Audio Sample

Parameter Description
dacOutput audio jack to use for output
analogInput input to use for sample frequency
JSON
    {
        "type" : "DiscreteNoise",
        "dacOutput" : 1,
        "analogInput" : 1,
    }       
C++
VCO* vco = DiscreteNoise::create(DUE_DAC0, DUE_IN_A00);

DrumTriggerSequencer

The DrumTriggerSequencer is like a cross between a trigger sequencer and a CV sequencer. It simulates the voltage pulses that are generated by piezo sensors typically used in electronic drums. When paired with a drum-to-midi box like the Alesis Trigger IO, you can use your ‘b to generate drum patterns in BFD, EZDrummer, or any other VST/RTAS based drums.

You will need one separate instance per drum track.

While the DrumTriggerSequencer will generate a static pattern, the ProbabilityDrumTriggerSequencer below for a similar sequencer with a little more entropy.

Parameter Description
division note division where quarter notes are equal to clock ticks
analogOutput the analog output to use for the trigger
triggers an array of integers specifying the amplitude of the trigger in millivolts
JSON
        {
            "type" : "DrumTriggerSequencer",
            "division" : "sixteenth",
            "analogOutput" : 3,
            "triggers" : [
 
                1000, 0, 0, 0, 5000, 0, 2500, 0, 1000, 0, 0, 2500, 0, 1000, 0, 1000
 
            ]
        },
 
        {
            "type" : "DrumTriggerSequencer",
            "division" : "sixteenth",
            "analogOutput" : 4,
            "triggers" : [
 
                1000, 0, 0, 0, 5000, 0, 2500, 0, 1000, 0, 0, 2500, 0, 1000, 0
 
            ]
        }

EFLooper

The EFLooper is a CV generator that uses an envelope follower type algorithm to average the magnitude of a signal over a specified window. This can be especially useful for generating modulation signals based on rhythmic loops with a fair amount of space in them. There are three controls available to this device.

The window size control specifies the number of samples that will be averaged per millisecond. Because the output samples are fixed at once per millisecond, increasing the number of samples that are averaged will effectively speed up and slow down the modulation signal. At 1mV, one sample will be averaged per millisecond. At 5V, 500 samples will be averaged per millisecond.

The scale control increases the gain of the signal after the averaging process. For some dynamic material, averaging it will effectively decrease the amplitude, so this can be used to bring it back up to a useful modulation level. 200mV will result in unity gain. 5V will produce a gain of 25.

The threshold control acts as a noise gate or downward expander. When the average signal drops below a given level, it is completely muted. This can be used to either reduce noise or to create a modulation signal with a greater dynamic range.

EFLooper Audio Sample

This demo uses the signal from a calm rain (rain.raw) as a control signal that is modulating the wave address of a Piston Honda.

Parameter Description
subfolder Folder underneath the "loops" folder where the sample is organized
filename Filename of the loop sample
analogOutput 1 or 2 to specify which audio output to use
windowsize Analog input to use for the windowsize
scale Analog input to use for the scale
threshold Analog input to use for the threshold
JSON
    {
        "type" : "EFLooper",
        "subfolder" : "noise",
        "filename" : "rain.raw",
        "windowsize" : 1,
        "scale" : 3,
        "threshold" : 5,
        "analogOutput" : 16
    }

C++

EFLooper* lfo1 = EFLooper::create(DUE_SPI_4822_15, DUE_IN_A00, DUE_IN_A02, DUE_IN_A04, "noise", "rain.raw");

Looper

The Looper is a sample playback device that will play back a sound file located within the “loops” folder of the SD card. There are a number loops included on the SD card you can use to experiment with different textures. Melodic, noisy, metallic, and rhythmic. A text file is included describing each of the included sounds.

You can easily create your own as long as the sound files are in the following format:

  • mono, single channel
  • Raw PCM data
  • 16 bit signed values
  • little-endian
  • Sample rates of 10kHz, 12kHz, 24kHz, 44.1kHz, 48kHz

We are using raw audio files because of their simplicity. WAV and AIFF files as they are extremely flexible formats that can include any number of encoding methods that may or may not be easily decoded on the fly with our little microcontroller. So, to make things most efficient, we just ask that you pre-encode the signals to the raw data that the microcontroller would use anyway. Most audio editors are able to export sounds in this format including Audacity, Audition, and any number of others.

You can always find the latest SD card image on github if you would like to make sure you have the most recent example loops.

Looper Music Box Audio Sample

In this demo we have a sample of a music box on DAC1 and the sound of rain from DAC2. A few random CV sources have also been set up as modulation sources. The music box is routed into a µfold whose folds and symmetry values are being modulated. From there, the audio is routed to a Z2040 filter. The rain sound is filtered through an SeM20 whose cutoff frequency is also modulated. It’s all been recorded and treated with some delay and reverb.

Looper Glitched Audio Sample

When the glitch input is triggered, the sound file will seek to a random spot in the loop, creating glitches. In this case, I have a random trigger sequence set up and patched into the trigger input, providing a CV-controllable probability that at any given 16th note, the loop may be glitched. This is recorded directly from the DAC output without any filters, but with a little reverb and delay added in the box.

    {
        "type" : "Looper",
        "subfolder" : "noise",
        "filename" : "rain.raw",
        "samplerate" : "24000",
        "dacOutput" : 2
    }
C++
Looper* looper2 = Looper::create(DUE_DAC0, "mech", "mech01.raw", SR_24000);

MorphingNoteSequencer

The Morphing Note Sequencer is a CV sequencer whose values are defined by notes, just like the standard NoteSequencer, however the MorphinNoteSequencer will periodically swap two of the notes in the sequence, slowly morphing into another sequence entirely.

The percentage likelihood that any note will be swapped is determined by the chaos value. Slower, more evolving sequences are achieved with values from 2 to 5. A value of 20 will create a rapidly evolving sequence whose phrases will bear some resemblance to the previous. Above 25, and the randomness takes over to the point where there is little to no predictability at all.

The reset pin will reset the morphed sequence back to the original and while it is in a positive state, will prevent any further modifications of the sequence.

Morphing Note Squencer Audio Sample

This demo is the JSON code below with the CV output going to a Dixie II. The gate output is routed to an MFB ADSR and the VCA is an Intellijel hexVCA. The sound is dry to make clear the original pattern and the morphed modifications as they progress.

Parameter Description
analogOutput Analog output to use for CV output
gateOutput Optional. Digital output to use for note triggers
gateDuration Optional. Duration in milliseconds of gate output
root Scale root note
scale Scale name
chaos Percentage likelihood of a note swap taking place
division note division where quarter notes are equal to clock ticks
notes sequence of notes for the note sequencer
reset digital input pin used to either reset the morphed sequence or prevent further morphing from happening.
JSON
    {
        "type" : "MorphingNoteSequencer",
        "analogOutput" : 2,
        "gateOutput" : 1,
        "gateLength" : 20,
        "chaos" : 5,
        "root" : "C",
        "scale" : "major",
        "division" : "sixteenth",
        "reset" : 1,
        "notes" : [
 
            [1,1], [0,0], [1,2], [1,3],
            [1,4], [1,5], [0,0], [1,6],
            [1,7], [2,1], [2,2], [0,0],
            [2,3], [2,4], [2,5], [2,6],
            [2,7], [3,1]
 
        ]
    }
C++
    SequenceNote notelist[34] = { {1,1}, {1,1}, {1,5}, {1,1}, {1,1}, {1,3}, {1,3}, {1,5}, 
                                  {2,1}, {2,1}, {2,5}, {2,1}, {2,3}, {2,3}, {2,1}, {2,1}, 
                                  {1,1}, {3,1}, {3,1}, {3,5}, {3,1}, {3,1}, {3,3}, {3,1}, 
                                  {2,5}, {2,5}, {2,1}, {2,3}, {2,3}, {2,1}, {2,1}, {2,3} };
 
    std::vector<SequenceNote>* notes = new vector&lt;SequenceNote&gt;(notelist, notelist + 34);
 
    Sequencer* sequencer = MorphingNoteSequencer::create(notes, C, MAJOR, 25, DIV_SIXTEENTH, DUE_SPI_4822_00, DUE_IN_D0);
 
    clock1->registerDevice(sequencer);

NoteSequencer

Note Sequencer is a CV sequencer whose values are defined by notes. Each ‘note’ consists of an octave and scale degree couplet. The octave value specifies which octave range the note should fall into where 0 = 0-1V, 1 = 1-2V, 2 = 2-3V and so on. The degree value specifies the note within the scale. The For a chromatic scale, there are 12 valid note positions. For a major or minor scale, there are 7. For a pentatonic, there are 5.

Note that the length of the sequence does not need to correlate to the length of the clock measure at all. In fact, creating a sequence whose length is completely unrelated to the clock can product very interesting results.

Note Sequencer Demo 1

Note Sequencer Demo 2

This demo is the JSON code below with the CV output going to a Z3000mkII. The gate output is routed to an MFB ADSR and the VCA is an Intellijel hexVCA. The sound is recorded dry to make clear the original sequence as well as the randomized version.

Parameter Description
analogOutput Analog output to use for CV output
gateOutput Optional. Digital output to use for note triggers
gateDuration Optional. Duration in milliseconds of gate output
root Scale root note
scale Scale name
division note division where quarter notes are equal to clock ticks
randomize specifies whether or not the notes sequence should be played in random order
notes sequence of notes for the note sequencer
JSON
    {
        "type" : "NoteSequencer",
        "analogOutput" : 2,
        "gateOutput" : 1,
        "gateLength" : 125,
        "root" : "C",
        "scale" : "major",
        "division" : "sixteenth",
        "randomize" : true,
        "notes" : [
 
            [1,1], [0,0], [1,5], [1,4],
            [1,1], [1,4], [0,0], [1,5],
            [1,1], [1,5], [1,3], [0,0],
            [1,1], [1,5], [1,4], [1,3]
 
        ]
    }       
C++
    Clock* clock1 = FixedClock::create(125, 8);
 
    SequenceNote notelist[34] = { {1,1}, {1,1}, {1,5}, {1,1}, {1,1}, {1,3}, {1,3}, {1,5}, 
                                  {2,1}, {2,1}, {2,5}, {2,1}, {2,3}, {2,3}, {2,1}, {2,1}, 
                                  {1,1}, {3,1}, {3,1}, {3,5}, {3,1}, {3,1}, {3,3}, {3,1}, 
                                  {2,5}, {2,5}, {2,1}, {2,3}, {2,3}, {2,1}, {2,1}, {2,3} };
 
    std::vector<SequenceNote>* notes = new vector&lt;SequenceNote&gt;(notelist, notelist + 34);
 
    Sequencer* sequencer = MorphingNoteSequencer::create(notes, C, MAJOR, 25, DIV_SIXTEENTH, DUE_SPI_4822_00);
    sequencer->seteg(ADSR::create(10, 250, 254, 1250, 1200, false, DUE_SPI_4822_01));
 
    clock1->registerDevice(sequencer);
 
    EventManager::registerDevice(clock1);

ProbabilityDrumTriggerSequencer

The probabilisticDrumTriggerSequencer takes modular drum trigger sequencing a step further. Rather than simply sequencing a steady digital rhythm, this sequencer creates two dimensions of unpredictability. The first is a simple probabilistic chance of whether or not a hit will occur on a given beat. The second is that the voltage generated is in a range that is able to be interpreted by any number of electronic drum trigger to MIDI converters. From there, you’ll be able to control any number of virtual instruments such as NI Battery, BFD, EZ Drummer, Slate, etc.

Alesis IO Drum Trigger Video

This demo is using an Alesis Trigger IO to control FXPansion’s BFD2 with a custom kit and very little post processing.

Parameter Description
division Note division where quarter notes are equal to clock ticks
triggerOutput Digital output for trigger signal
probabilityModifier Analog input to use as a probability modifier
triggers Array of probabilities between 0 and 100.
velocities Array of voltages in mV from 0 to 5000
velocityRange value in millivolts of which you wish the amplitude to vary per trigger
JSON
    {
        "name" : "snare",
        "type" : "ProbabilityDrumTriggerSequencer",
        "division" : "sixteenth",
        "analogOutput" : 3,
        "probabilityModifier" : 3,
        "velocityRange" : 250,
        "triggers" :   [ 0, 0, 0, 5,        75, 0, 0, 0,    0, 0, 0, 8,     75, 0, 0, 1000 ],
        "velocities" : [ 0, 0, 0, 1000,     5000, 0, 0, 0,  0, 0, 0, 1500,  5000, 0, 0, 1000 ]
    }
C++
    int snaretriggers[16] =   { 0, 0, 1,  0,  75,  0,  1,  0, 0, 1,  20,  0,  75,  1, 0, 15 };
    int snarevelocities[16] = { 0, 0, 75, 75, 400, 75, 75, 0, 0, 75, 200, 75, 400, 1, 1, 75 };
    TriggerSequenceData* snaretriggerdata = new TriggerSequenceData(snaretriggers, snaretriggers + 16);
    TriggerSequenceData* snarevelocitydata = new TriggerSequenceData(snarevelocities, snarevelocities + 16);
    ProbabilityDrumTriggerSequencer* snaresequencer = ProbabilityDrumTriggerSequencer::create(snaretriggerdata, snarevelocitydata, 25, DIV_SIXTEENTH, DUE_SPI_4822_00);
    snaresequencer->setProbabilityModifier(DUE_IN_A01);
    vclock->registerDevice(snaresequencer);

ProbabilityTriggerSequencer

This sequencer is just like the trigger sequencer, explained below, but rather than being a sequence of binary on/off, the notation includes a percentage probability that the trigger will fire for that step.

An additional parameter may be defined which associates a probability modifier input to the sequence. This input, when placed at the 12:00 position (2.5V) will leave the probabilities unmodified. As you decrease the CV, the probability will decrease. As you increase the CV, the probability will also increase. If a sequence contains a probability of 0, then the even will never occur, even if the modifier is turned all the way up.

Probability Trigger Sequencer Audio Sample

This demo uses the code referenced below to generate a probabilistic drum sequence. There are four tracks: snare, closed hi-hat, open hi-hat, and kick. The only drum module I have is an LDB-1e. The trigger sequences are defined as a set of probabilities. The kick and snare are each 16 beats long, so retain a fixed relationship. The open hi-hat is 15 beats long, so plays against the 16 beat sequence nicely. The open hit-hat, however is 7 beats long and only occurs once, so it adds a nice random-but-not-ness to the whole thing.

Each of the tracks has its own probability control. Turning the CV down decreases the probability of any given hit and turning it up, increases the chances. This sequence is then routed to a ring-mod whose carrier wave is a dixie II sine wave. The pitch of the sine wave is modulated by one of the random CV sequences on the quarter triplet. A Z2040 then filters the output and its frequency is modulated by yet another random CV sequencer on the half note. Recorded and treated with a nice dose of TC4000 reverb and Echoboy delay.

Probability Trigger Sequencer Audio Sample 2

This is a very simple program and patch. The probability trigger sequencer is triggering an ADSR. There is a simple random note sequencer synchronized to the probability sequencer which is controlling the pitch of a Piston Honda. A random CV sequencer is controlling the wave address. As the trigger sequencer controller is modulated, the envelope opens more often.

Parameter Description
division Note division where quarter notes are equal to clock ticks
triggerOutput Digital output for trigger signal
probabilityModifier Analog input to use as a probability modifier
triggers Array of probabilities between 0 and 100.
JSON
    {
        "name" : "snare",
        "type" : "ProbabilityTriggerSequencer",
        "division" : "sixteenth",
        "digitalOutput" : 1,
        "probabilityModifier" : 1,
        "triggers" :   [ 0, 5, 0, 5, 80, 0, 0, 15, 0, 0, 0, 5, 80, 5, 5, 0 ]
    }

RandomLoopingShiftRegister

The RandomLoopingShiftRegister is built around a binary shift register. The last 12 bits of the register drive a DAC and the input of the shift register is fed with a mix of noise and the output of the shift register. This is not completely unlike the operation of the Turing Machine by MTM or the Doepfer A-149-1. The main difference is that, since this version is implemented in software, there is a bit more flexibility with things like the length of the shift register or how the shift register can be realized as CV.

The basic operation is fairly simple. At initialization, a set of random bits are placed into the shift register. At each clock cycle, a bit is shifted off the end of the register and a new bit is placed on the head of the register. The CV output is always based on the last 12 bits and therefore changes with every clock cycle.

There is only a single control that affects the output. At fully counter-clockwise (0V CV), as each bit is shifted off the end of the register, it is copied exactly to the head. This creates a looping CV sequence that repeats periodically depending on the actual length of the sequence. As the CV raises above 0V, there is a chance that a bit will be flipped as it is copied from the tail to the head. This effectively is introducing some randomness to the loop. At low values, it creates an evolving sequence. At the 12:00 position (2.5V), the probability of a bit being flipped is 50% which effectively creates a completely random sequence. At fully clockwise, the chance of a bit being flipped becomes 100%, which creates a looped CV sequence that is a palindrome of itself.

While the primary output of this sequencer is just a CV output, we are also able to quantize the output to a scale or even tap into the individual bits of the shift register to treat as gates or triggers.

Random Looping Shift Register Audio Sample

This demo is a very simple setup with the CV out being quantized and routed to a saw osc. The delayed CV is routed to a LP filter. Some of the triggers are then routed to a drum module.

Alanesque Video Demo

This demo shows an early prototype of the nw2s::b running the Alanesque demo. Some of the trigger outputs are wired to an LDB-1e while the quantized output is driving a VCO and some of the other CV outputs are driving various filters.

Parameter Description
size Length in bits of the shift register
division Note division where quarter notes are equal to clock ticks
controlInput Analog input to use for probability control
analogOutput raw CV output of the sequencer
delayedOutput Optional. CV output delayed by a number of beats
cvDelay Optional. Number of beats to delay the secondary CV signal
trigger1 Optional. Digital output for bit 1
trigger2 Optional. Digital output for bit 2
trigger3 Optional. Digital output for bit 3
trigger4 Optional. Digital output for bit 4
trigger5 Optional. Digital output for bit 5
trigger6 Optional. Digital output for bit 6
trigger7 Optional. Digital output for bit 7
trigger8 Optional. Digital output for bit 8
logicalAND1 Optional. Digital output for bits 1 and 3 logically ANDed
logicalAND2 Optional. Digital output for bits 1 and 4 logically ANDed
logicalAND3 Optional. Digital output for bits 1, 3, and 5 logically ANDed
logicalAND4 Optional. Digital output for bits 1, 2, 4, and 8 logically ANDed

TriggeredNoteSequencer

The TriggeredNoteSequencer is just like the NoteSequencer except that rather than deriving it’s clock signal from internal code, it uses an external trigger to advance to the next step in the sequence.

Parameter Description
analogOutput Analog output to use for CV output
triggerInput Digital input to use for clock signal
gateOutput Optional. Digital output to use for note triggers
gateLength Optional. Duration in milliseconds of gate output
root Scale root note
scale Scale name
randomize specifies whether or not the notes sequence should be played in random order
notes sequence of notes for the note sequencer
JSON
    {
        "type" : "TriggerNoteSequencer",
        "analogOutput" : 2,
        "triggerInput" : 1,
        "gateOutput" : 1,
        "gateLength" : 125,
        "root" : "C",
        "scale" : "major",
        "randomize" : true,
        "notes" : [
 
            [1,1], [0,0], [1,5], [1,4],
            [1,1], [1,4], [0,0], [1,5],
            [1,1], [1,5], [1,3], [0,0],
            [1,1], [1,5], [1,4], [1,3]
 
        ]
    }
C++
    SequenceNote notelist1[4] = { {1,1}, {1,4}, {1,1}, {1,5} };
    NoteSequenceData* notes1 = new NoteSequenceData(notelist1, notelist1 + 4);
    sequencer1 = TriggeredNoteSequencer::create(notes1, C, Key::SCALE_MAJOR, DUE_IN_D0, DUE_SPI_4822_15);

TriggerSequencer

A Trigger sequence can be used for triggering envelopes, drums, or as clocks. The operation of this is very simple. It is a sequence whose values are either 1 or 0. When the sequence hits a 1, the trigger fires. When it’s 0, the trigger does not fire.

Trigger Sequence Audio Sample

This demo uses the code referenced below to generate three trigger tracks for snare, hi-hat, and bass. All I have access to is an LDB-1e, so bear with the drum sound. If you didn’t notice yourself, count the hi-hat beats. You may think, oh he messed up. There’s only 15 hi-hat beats and everything else has 16. Yeah, doesn’t matter. What that does is create a 16 beat snare and kick pattern and a hi-hat pattern that repeats every 15 beats, playing against the snare and kick. I’ve added another random CV generator that is driving a filter on the half note. From there, the signal is recorded, processed with UBK-1 (love that thing!), a little TC4000 reverb and touch of delay.

Parameter Description
division Note division where quarter notes are equal to clock ticks
triggerOutput Digital output for trigger signal
triggers Array of 1s and 0s
JSON
    {
        "name" : "snare",
        "type" : "TriggerSequencer",
        "division" : "sixteenth",
        "triggerOutput" : 1,
        "triggers" : [
 
            0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0
 
        ]
    }

CONSTANTS

Clock Divisions

Note that the quarter note is always 1:1 with the clock tempo and all other clock divisions/multiples are relative to that.

JSON C++
whole DIV_WHOLE
half DIV_HALF
dotted half DIV_HALF_DOT
quarter DIV_QUARTER
dotted quarter DIV_QUARTER_DOT
quarter triplet DIV_QUARTER_TRIPLET
eighth DIV_EIGHTH
dotted eighth DIV_EIGHTH_DOT
triplet eighth DIV_EIGHTH_TRIPLET
sixteenth DIV_SIXTEENTH
dotted sixteenth DIV_SIXTEENTH_DOT
sixteenth triplet DIV_SIXTEENTH_TRIPLET
thirtysecond DIV_THIRTYSECOND
dotted thirtysecond DIV_THIRTYSECOND_DOT
thirtysecond triplet DIV_THIRTYSECOND_TRIPLET

If you look at the code for these, you see that they are all simply integer constants. I purposefully did not make them typesafe (enums) to give the end user a little more flexibility in defining clock divisions for their sequences.

The value of the integer is simply the decimal fraction (or multiple) of a beat timed to the clock tick. I multiply by 1000 to avoid floating point math and find that effectively having three decimal places of precision is sufficient for millisecond-accurate timing.

Let’s say you want an eighth note pentuplet (Does that exist?). Take the quarternote value and divide by 5. 200 would be its clock division.

Scale Types

JSON C++
major MAJOR
minor MINOR
chromatic CHROMATIC

Note Names

JSON C++
C C
C# C_SHARP
Db D_FLAT
D D
D# D_SHARP
Eb E_FLAT
E E
E# E_SHARP
F F
F# F_SHARP
Gb G_FLAT
G G
G# G_SHARP
Ab A_FLAT
A A
A# A_SHARP
Bb B_FLAT
B B
B# B_SHARP

Analog Input

JSON C++
1 DUE_IN_A00
2 DUE_IN_A01
3 DUE_IN_A02
4 DUE_IN_A03
5 DUE_IN_A04
6 DUE_IN_A05
7 DUE_IN_A06
8 DUE_IN_A07
9 DUE_IN_A08
10 DUE_IN_A09
11 DUE_IN_A10
12 DUE_IN_A11

Analog Output

Note: I’ll be renaming these since I have a finalized panel design.

JSON C++
1 DUE_SPI_4822_00
2 DUE_SPI_4822_01
3 DUE_SPI_4822_02
4 DUE_SPI_4822_03
5 DUE_SPI_4822_04
6 DUE_SPI_4822_05
7 DUE_SPI_4822_06
8 DUE_SPI_4822_07
9 DUE_SPI_4822_08
10 DUE_SPI_4822_09
11 DUE_SPI_4822_10
12 DUE_SPI_4822_11
13 DUE_SPI_4822_12
14 DUE_SPI_4822_13
15 DUE_SPI_4822_14
16 DUE_SPI_4822_15

Digital Input

Note: I’ll be renaming these since I have a finalized panel design.

JSON C++
1 DUE_IN_D0
2 DUE_IN_D1
3 DUE_IN_D2
4 DUE_IN_D3
5 DUE_IN_D4
6 DUE_IN_D5
7 DUE_IN_D6
8 DUE_IN_D7

Digital Output

Note: I’ll be renaming these since I have a finalized panel design.

JSON C++
1 DUE_OUT_D00
2 DUE_OUT_D01
3 DUE_OUT_D02
4 DUE_OUT_D03
5 DUE_OUT_D04
6 DUE_OUT_D05
7 DUE_OUT_D06
8 DUE_OUT_D07
9 DUE_OUT_D08
10 DUE_OUT_D09
11 DUE_OUT_D10
12 DUE_OUT_D11
13 DUE_OUT_D12
14 DUE_OUT_D13
15 DUE_OUT_D14
16 DUE_OUT_D15