Link search Menu Expand Document

S2E1 Found Shapes

maps: S2E1

nb. descriptive hyperlinks connect to timestamped moments in the video above

an overview of the concepts that will be covered:

  • sequins
  • clocks
  • between the two: instant sequencer-style things

within the episode, Trent executes crow commands via druid on the left side of the screen while taking longform notes in a text editor on the right side of the screen. also within the episode, Trent receives a package – it is unknown what the package contains. perhaps it’s unimportant, but it seems to have captured the imagination of the live viewers.

clean slate

to begin, let’s make sure our crow isn’t doing anything else but what we tell it to by executing the following in druid:

crow.reset()

making events happen in musical time

crow v3 borrows the concept of a ‘clock’ from norns. this just means that crow has a built-in understanding of tempo (eg. 98 bpm), which means you can execute events on a quantized beat/tick (either on a recurring timed loop or as a single execution). these events can be notes or modulations or anything you want – the important thing is that you can lock these to occur in musical time. this is super rad, because it allows you execute part of a program in specified intervals, whereas ‘normal’ program flow tries to execute all events as instantaneously as possible.

we do this by using a function named clock.run, which lets crow know to look out for a few things:

  • an event we’d like to execute in musical time
  • to which beat interval we’d like to sync this event’s execution
  • whether that event should execute again and again, or just once

watch Trent explain and set up a clock.run function. note that Trent is writing this in the text editor, which can be uploaded to crow as a script later on. for the purposes of this document, we’ll be executing single lines via druid.

check + change tempo

to check the current tempo of your crow, execute:

print(clock.tempo)

to change the tempo to (for example) 150 bpm, simply execute:

clock.tempo = 150

since clock.tempo is just a variable, it can also be used in equations like this:

ii.wdel.time(60/clock.tempo) -- sets w/'s delay time to a quarter note length at the current bpm

or like this:

clock.tempo = clock.tempo/2

special w/ delay time tips

make a note every beat

at this point in the video, Trent uses a special protocol and command to communicate to another module’s (w/) digital synthesis mode:

clock.run(function() while true do clock.sync(1); ii.wsyn.play_note(0,0.9) end end)

if you don’t have access to this module, here’s a version of the code he’s written which will send v/8 CV to crow output 1 and a trigger pulse to crow output 2:

clock.run(function() while true do clock.sync(1); output[1].volts = 0.9; output[2](pulse()) end end)

to clear all running clocks, execute:

clock.cleanup()

establishing a sequence with sequins

watch Trent get bored and figure out how to solve his boredom with sequins.

sequins is a library that’s built in crow v3. it provides a framework to store values, sequence them, and pass these values to other functions across crowspace.

to define a sequence, we create a variable which stores and accesses a sequins. try executing this in druid:

mys = sequins{0,2,4,7,9}

this establishes mys as a sequins-capable function. we assigned mys a table of semitones, which will automatically be stepped through every time we execute mys().

so, to iterate through the table, execute:

print( mys() )

…again and again and again.

you’ll get:

> print( mys() )
0

> print( mys() )
2

> print( mys() )
4

every time we execute mys(), it will return the next step’s value, eg:

> print( mys(), mys(), mys() )
7 9 0 

while it’s easier to think about sequences in semitones, you’ll often want to pass raw voltage to your crow destinations. to convert a semitone to voltage, just divide it by 12, eg

> print( mys()/12 )
0.3333333

running our sequence

watch Trent spice things up

prettified w/syn code:

mys = sequins{0,2,4,7,9}

clock.run(
  function()
    while true do
      clock.sync(1)
      ii.wsyn.play_note(mys()/12,0.9)
    end
  end
)

one-line w/syn code:

mys = sequins{0,2,4,7,9}; clock.run(function() while true do clock.sync(1); ii.wsyn.play_note(mys()/12,0.9) end end)

if you don’t have access to this module, here’s a version of the code he’s written which will send v/8 CV to crow output 1 and a trigger pulse to crow output 2.

prettified v/8 + pulse code:

mys = sequins{0,2,4,7,9}

clock.run(
  function()
    while true do
      clock.sync(1)
      output[1].volts = mys()/12
      output[2](pulse())
    end
  end
)

one-line v/8 + pulse code:

mys = sequins{0,2,4,7,9}; clock.run(function() while true do clock.sync(1); output[1].volts = mys()/12; output[2](pulse()) end end)

changing sequence step size

watch Trent change the size of the sequins step

to modify the step size of a sequins while its running, execute:

mys:step(2)

…which will increment by 2 steps instead of the default 1.

creating ‘presets’ + switching between them

watch Trent duplicate a sequins current configuration

since a sequins is just a variable (for us so far, mys), we can copy it for further experimentation or posterity very easily.

to make a copy of the current sequence, execute:

mys1 = mys

this allows us to freely redefine mys while the sequence is running:

mys = sequins{0,3,6,9,12,15,18,21}

notice that when we redefine mys, it steps by 1 (even if you had previously applied a step modification). this is because we are forcing mys to forget what it used to know, which includes the step size. if you execute:

mys = mys1

you’ll get back to your previous settings, including any step size mods!

sequins-ing time

watch Trent use another sequins to modify clock.sync

let’s stop our currently running clocks:

clock.cleanup()

and use myt to sequence the clock.sync() division while mys sequences pitch.

prettified w/syn code:

mys = sequins{0,2,4,7,9}
myt = sequins{1,1,1,1/2,1/2}

clock.run(
  function()
    while true do
      clock.sync(myt())
      ii.wsyn.play_note(mys()/12,0.9)
    end
  end
)

one-line w/syn code:

mys = sequins{0,2,4,7,9}; myt = sequins{1,1,1,1/2,1/2}; clock.run(function() while true do clock.sync(myt()); ii.wsyn.play_note(mys()/12,0.9) end end)

if you don’t have access to this module, here’s a version of the code he’s written which will send v/8 CV to crow output 1 and a trigger pulse to crow output 2.

prettified v/8 + pulse code:

mys = sequins{0,2,4,7,9}
myt = sequins{1,1,1,1/2,1/2}

clock.run(
  function()
    while true do
      clock.sync(myt())
      output[1].volts = mys()/12
      output[2](pulse())
    end
  end
)

one-line v/8 + pulse code:

mys = sequins{0,2,4,7,9}; myt = sequins{1,1,1,1/2,1/2}; clock.run(function() while true do clock.sync(myt()); output[1].volts = mys()/12; output[2](pulse()) end end)

to get a little funky, try changing myt’s step size using what we’ve learned so far!

replacing (only) the values in a sequins

watch Trent replace the values in our time sequins without overwriting the other settings

to retain the current step and step size settings, but change the values in our myt sequins, execute:

myt:settable{1,1/2,1/2,1/4,1/4,1/8,1/8,1/4}

additional techniques

for the rest of the episode, Trent digs into some extended techniques which mix + remix the concepts above. rather than repeat the baseline information which enables these explorations, we’ll link to moments of particular impact: