A Sample script for the not-things TimeSeq module.
With the introduction of clocks in script version v1.3.0 (TimeSeq v2.0.8), it has become easier to create scripts that set up one or more dedicated clock outputs. While the end result is the same as a clock that was set up using timelines, lanes, segments and actions (as demonstrated in the Creating Clock Signals using Timelines sample), the new clocks feature will require less scripting setup to get the same clock output signal. This script starts by recreating the same clock signal as the old sample page, but using clocks with clock lanes and durations instead of timelines with lanes, segments and actions. It will then add an example of a more complex clock signal, demonstrating its usage as a more complex gate/trigger sequencer.
Since we want to send the clock outputs as polyphonic channels on the first output port, we’ll have to set up this polyphony first. We’ll do this using the global-actions property of the TimeSeq script. Actions in the global-actions list are executed when a script is loaded or reset, so setting up the polyphony here will initialize that port and make polyphony on it available throughout the rest of the script:
"global-actions": [
{
"set-polyphony": {
"index": 1,
"channels": 5
}
}
]
The set-polyphony action specifies that the first output port should contain five polyphonic channels, which is how many clock signals we’ll generate in this sample.
Instead of a timelines list, this script will contain a clocks list. The different clock lanes will be added to this clocks list, just like regular lanes would get added to a timeline.
The first clock we’ll set up is one that will use a 120 Beats per Minutes (bpm) time scale, with 4 Beats per Bar (bpb):
{
"time-scale": { "bpm": 120, "bpb": 4 },
"lanes": [
]
}
This time-scale definition will set how beats and bars will be interpreted in all clock lanes that are part of that clock.
For the first lane in this clock, we’ll create a clock signal that fires on every beat of the 120 bpm. Just like all other lanes that will be added to this script, it will be set to auto-start, and since a clock lane always loops, the clock is always running:
{
"auto-start": true,
"durations": [ { "beats": 1 } ],
"output": { "index": 1, "channel": 1 }
}
In the durations property of the clock lane, a single 1-beat duration is included. This tells TimeSeq that it should send a looping gate signal that lasts 1 beat to the port specified in the output property: the first channel of the first output port. This gate signal will be high for the first half of the beat, and low for the second half of that beat.
The beat property of the clock lane duration can also be set to decimal numbers. In the second lane we’ll set the beats to a value of 1.75:
{
"durations": [ { "beats": 1.75 } ],
"output": { "index": 1, "channel": 2 },
"gate-high-ratio": 0.66
}
Since the clock lane auto-start property defaults to true, we can omit it from the lane and still have the lane start automatically when the script loads.
This clock lane will create a clock beat that lasts one and three quarters of the 120 bpm that is specified on the clock (so slower then the previous lane, but not quite double as long). The clock signal will be sent to the second channel of the first output port.
The gate-high-ratio property will control how long the clock signal will remain high (as a value between 0 and 1). The 0.66 value used here will cause it to remain high for 66% of the segment duration, and low for 34% of the segment duration. This can be useful in certain scenarios, like when the clock signal is used for generating an ADSR envelope, and the sustain section of the envelope should be longer or shorter.
Since both a bpm and a bpb is specified on the time-scale of this clock, a slow clock signal can also be expressed in bars:
{
"durations": [ { "beats": 0, "bars": 4 } ],
"output": { "index": 1, "channel": 5 },
"gate-high-ratio": 0.25
}
This clock will trigger every 4 bars on channel 5 of the first output port. When left on its default setting, this clock signal would remain high for 2 bars, and low for 2 bars. But with the gate-high-ratio of 0.25 that is used here, it will only remain high for a quarter for the duration, and low for the remainder of the clock duration.
Because a script can have multiple clocks, the clock signals in a script don’t all have to use the same bpm. This second clock will use 90 Beats per Minute, and contain a clock lane that triggers the clock once for each of these 90 beats. The output is sent to third channel of output port 1:
{
"time-scale": { "bpm": 90 },
"lanes": [
{
"durations": [ { "beats": 1 } ],
"output": { "index": 1, "channel": 3 }
}
]
}
Since the duration in this clock doesn’t use a bars time unit, we don’t specify a bpb on the clock time-scale.
The third clock will be a bit more off-beat compared to the other clocks: the others were a multiple of 30, while this final clock will use a bpm of 70. It will again trigger on every beat of these 70 Beats per Minute, and send that clock signal to the fourth channel of the first output port.
{
"time-scale": { "bpm": 70, "bpb": 4 },
"lanes": [
{
"durations": [ { "beats": 1 } ],
"output": { "index": 1, "channel": 4 }
}
]
}
The full clock script can be found in clock.json.
The clock.vcv patch will split up the five clock signals from the polyphonic output port and use each of the clock signals to generate a separate ADSR Envelope. This Envelope will be used to control the volume of five VCOs (each playing a different note).
The clock signals themselves will also be shown on oscilloscopes: the four shorter clocks are combined on the Count Modula Oscilloscope, and the slow clock on a VCV Scope.
So far, all clock lanes have had a single duration in the durations property. This results in a constant looping clock signal, each gate lasting for the same duration. Since this durations property is an array, it is possible to also create more complex looping clock trigger/gate signals using the clocks feature. If more durations are added to the list, TimeSeq will step through each of them in order, and create clock signals for each of them, one after the other, resulting in a repeating pattern:
{
"lanes": [
{
"durations": [
{ "millis": 250 },
{ "millis": 125 },
{ "millis": 125 },
{ "millis": 250 },
{ "millis": 500 },
{ "millis": 250 },
{ "millis": 500 }
],
"output": 2
}
]
}
This clock signal uses milliseconds instead of beats, so there is no time-scale definition needed for the clock. The clock lane contains a list of millisecond durations that will create a recognizable looping pattern when played.
This clock, combined with the previous clock signals, can be found in the complex-clock.json script.
The complex-clock.vcv patch adds it as an additional VCO on top of the other ones.
Since duration in TimeSeq supports Variable-length durations, it is also possible to bring variation in a clock signal. As an example, we’ll start from the clock we defined earlier. The last element in the durations array will be replaced with a randomly generated duration instead of the fixed 500 millisecond duration:
{
"lanes": [
{
"durations": [
{ "millis": 250 },
{ "millis": 125 },
{ "millis": 125 },
{ "millis": 250 },
{ "millis": 500 },
{ "millis": 250 },
{ "millis": {
"rand": {
"lower": { "voltage": 500, "no-limit": true },
"upper": { "voltage": 2000, "no-limit": true }
}
} }
],
"output": 2
}
]
}
In this clock, the last duration will be a random value between 500 and 2000 (milliseconds), causing the gap between two repetitions of the pattern to change each time.
When you listen to the envelopes generated by the gate signal, you will hear that the different steps in the sequence generate different length notes. Since the gate currently stays high for half the duration of the output gate, and the gates have different durations, the generated envelope signals also have different durations. The gate-high-ratio property of the clock lane can modify the length of these envelopes relative to the duration of the gate signal, but it can not change that different length gates will also result in different length envelopes. While this might be desired in some scenarios, there are other scenarios where the “gate high” duration is constant over all gates (and thus the duration of the “low” part of the gates causes the different total gate durations). This can be achieved using the gate-high-duration property. It expects the same duration object as segments use, and expresses an absolute gate high duration:
{
"lanes": [
{
"durations": [
{ "millis": 250 },
{ "millis": 125 },
{ "millis": 125 },
{ "millis": 250 },
{ "millis": 500 },
{ "millis": 250 },
{ "millis": 500 }
],
"gate-high-duration": { "millis": 75 },
"output": 2
}
]
}
With the setting of the gate-high-duration to a fixed 75 milliseconds, all generated gates will have the same gate high duration, regardless of their individual 125, 250 or 500 millisecond durations. Only the low parts of the gates have different durations.
The full script with the constant gate high duration can be found in the gate-high-duration.json script.
The updated patch can be found at gate-high-duration.vcv.