Shipping will be unavailable from Dec 21 to Jan 3. Orders placed during that time will be shipped the week of Jan 3.

A Detailed Look at the Clocks

Before we take a look at the next round of MIDI support updates, I wanted to take a little time to talk about the different clocks available on the 'b. For most modules, their role is clear. There are clock generators. There are clocked devices. Clocks feed clocked devices. Generally there is little in between. Yes, there are some clock dividers and shuffle generators, but those still qualify as clock generators and generally feed clocked/triggered devices. The 'b is a tad bit more complicated. It can be a clock generator. It can be a clocked device. Not only that, but there are algorithms and sketches that can be clocked either from an external source or from one of the internal clocks. In some cases, the behavior may change depending on how it's clocked. So we'll try to clarify things a little by describing the architecture of timing within the 'b framework as well as give some concrete examples of how you might be able to perform some common and no-so-common tasks using the various clocks in combination with some of the various devices available to you with in the 'b framework. ## Timing Architecture In the 'b framework EventManager is the great overlord. the event manager is the orchestrator of all code - either directly or indirectly. Any device that needs to do periodic work on a millisecond-scale timeframe needs to register itself with the EventManager. Typically the types of devices that will register with the EventManager are clocks and non-clocked devices like MIDI controllers or free-running oscillators. Devices that need a clock, like sequencers, are typically registered to the clock device rather than directly to the event manager. When a clock is registered to the event manager, the event manager simply updates the clock with millisecond ticks. When a beat device is registered to a clock, the clock will typically need one piece of information from the device: it's clock division. This tells the clock how often it should trigger an event on the child device. If it's a quarter note, then it will get called once per beat. If 8th note triplets, then it will get called three times per beat. Half note? every two beats. And so on. If you are working within the JSON framework, device registration is taken care of for you. If you are building out sketches on your own using the building blocks, or even writing your own building blocks, then it really helps to understand the inner workings as you will be in control of who is responsible for timing who. ## Fixed Clock The fixed clock of course is the simplest and needs no explanation. You specify the BPM and it ticks away until you stop supplying sufficient electrons. Here's a sample program using the fixed clock to drive a morphing note sequencer: { "program" : { "name" : "Morphing Sequence Demo 1", "clock" : { "type" : "FixedClock", "tempo" : 120, "beats" : 16 }, "devices" : [ { "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] ] } ] } } ## Random Clock The random clock is a very interesting beast. The random clock will generate random tempos within a given range. This provides some slop in the tempo from measure to measure. Technically the range can be as wide as you like, however, it's strengths are generating subtle shifts in tempo to give a human feel to the music. The following sample uses a random clock to drive a series of triggers set up as a clock divider/multiplier: { "program" : { "name" : "Random Tempo Clock Demo 1", "clock" : { "type" : "RandomTempoClock", "minTempo" : 118, "maxTempo" : 122, "beats" : 16 }, "devices" : [ { "type" : "Trigger", "division" : "whole", "triggerOutput" : 1 }, { "type" : "Trigger", "division" : "half", "triggerOutput" : 2 }, { "type" : "Trigger", "division" : "quarter", "triggerOutput" : 3 }, { "type" : "Trigger", "division" : "quarter triplet", "triggerOutput" : 4 }, { "type" : "Trigger", "division" : "dotted eighth", "triggerOutput" : 5 }, { "type" : "Trigger", "division" : "eighth", "triggerOutput" : 6 }, { "type" : "Trigger", "division" : "eighth triplet", "triggerOutput" : 7 }, { "type" : "Trigger", "division" : "sixteenth", "triggerOutput" : 8 } ] } } ## Variable Clock The variable clock is a clock with voltage-controlled tempo. This is fairly straightforward in practice and shouldn't need too much explanation. The variable clock has a programmable minimum and maximum tempo. It responds from 0 to 5V at the analog inputs where 0V produces the minimum tempo and 5V produces the maximum tempo. Here's an example with the variable clock driving a basic note sequencer: { "program" : { "name" : "Sequence Demo 1", "clock" : { "type" : "VariableClock", "minTempo" : 30, "maxTempo" : 240, "tempoInput" : 1, "beats" : 16 }, "devices" : [ { "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] ] } ] } } ## Tap Tempo Clock The tap-tempo clock is - obviously - a clock whose tempo is defined by tapping a digital input. The tempo is defined by two taps and the duration in time defines what a "quarter" note is. Once two taps have been received, the clock will continue at that tempo. Typically you would just tap a few times until the tempo is comfortable and then leave it as-is. The only limiting factor is that the clock will only listen for a second tap up to four seconds after the first. After that period, the timer is reset. A device will only be notified of the new tempo when it plays its next note. Since the tempo can change at any moment, there is one potential side effect of this. When you are attempting to change tempos, the devices tied to the clocks may have beats occurring at different points in the measure. For example, one device could be playing dotted sixteenth notes and another is playing whole notes. The tempo for the dotted 16th device will change at the next note trigger - which will happen fairly quickly after the tempo change, whereas the whole note will not find out about the new tempo until the next fourth beat comes around. By then the dotted 16th sequence will have taken off to the moon and back. So to help keep things synchronized, I've added a toggle that will allow you do indicate if you wish to have all of the clock's devices receive a reset() signal when the tempo is set. It's a toggle because it may not be something that you want to happen every time depending on how your program is set up. Here's a sample of the tap tempo clock configured to tap tempo a clocked random CV source. { "program" : { "name" : "CV Sequence Demo 1", "clock" : { "type" : "TapTempoClock", "tapInput" : 1, "resetInput" : 2, "beats" : 16 }, "devices" : [ { "type" : "CVSequencer", "division" : "triplet eighth", "analogOutput" : 3, "gateOutput" : 2, "gateLength" : 125, "min" : 0, "max" : 5000 } ] } } ## Passthrough Clock And the odd man out is the passthrough Clock. This clock doesn't pay attention to tempo or clock divisions. No matter if the device is registered as a whole note or a 32nd note clock division, it will get called every time the clock's input is triggered. This effectively makes each device tied to the passthrough clock work as if it were a standalone euro module that was being clocked by an external device. This clock is particularly useful for clocking to a shuffled/swung clock. This program demonstrates a Turing Machine clocked by an external source: { "program" : { "name" : "Alanesque", "clock" : { "type" : "PassthruClock", "tapInput" : 1, "beats" : 16 }, "devices" : [ { "type" : "RandomLoopingShiftRegister", "size" : 32, "division" : "sixteenth", "controlInput" : 2, "analogOutput" : 15, "delayedOutput" : 16, "delay" : 12, "triggerOutput1" : 5, "triggerOutput2" : 6, "triggerOutput3" : 7, "triggerOutput4" : 8, "triggerOutput5" : 9, "triggerOutput6" : 10, "triggerOutput7" : 11, "triggerOutput8" : 12, "logicalAND1" : 13, "logicalAND2" : 14, "logicalAND3" : 15, "logicalAND4" : 16 } ] } } Some upcoming clock additions will be support for USB MIDI clocking and swing settings for some of the internal clocks.

Leave a comment

Please note, comments must be approved before they are published