OTYPElearn1.1scripting for the octatrackoctatrack

The studies
  1. Learn OType
  2. 01Quickstart
  3. 02Numbers and expressions
  4. 03Decisions and loops
  5. 04Variables and memory
  6. 05Tracks and steps
  7. 06Functions
  8. 07Asking the player
  9. 08Chance you can repeat
  10. 09Live scripts
  11. 10When something is wrong
  12. 11Appendix: scope at a glance

study 05 of 10

Tracks and steps

So far every function worked on “the track”: the current one, the track you were on when you opened the menu. tr.add 5 never says which track, and that is on purpose. Operations act on a context: a set of tracks, a set of steps, and a source of chance. This study changes the context to write a beat on three tracks at once.

Choosing the tracks: trk

trk takes one to eight track numbers, or cur (the current track), or all. Like a modifier, it governs the rest of its line or the block below:

Listing 5-1 · Kick, snare and hats on tracks 1, 2 and 3
def beat
  menu "LEARN" >> "BEAT"
  trk 1 2 3: tr.clr
  trk 1: l 1 16: if eq mod i 4 1: tr.add i
  trk 2:
    tr.add 5
    tr.add 13
  trk 3: l 1 16: if er 11 16 i: tr.add i
Output · what the simulator prints for $ otype.py run beat -v
beat  seed 1 (--seed)  pattern A01 len 16 (default)  track 1
T1  1   5   9   13
    X...X...X...X...
T2  1   5   9   13
    ....X.......X...
T3  1   5   9   13
    X.XX.XX.XX.XX.XX
      X trig  ! one-shot  o trigless trig  - trigless lock  l locks only  . none
part:  tempo 120
cost: 520/588   random draws: rand 0  toss 0  prob 0  drunk 0  file 0

With several tracks, OType runs what trk governs once per track, in the order written: trk 1 2 3: tr.clr clears track 1, then 2, then 3. Everything inside a pass, a loop or a random draw, runs again for the next track.

For the rest of the block

trk can also stand alone, without a colon. It then sets the tracks until the end of the block it is in:

Listing 5-2 · trk as a statement
def on_track_2
  menu "LEARN" >> "TRACK 2"
  trk 2                 # from here to the end of the function
  tr.clr
  tr.add 1
  tr.add 9

Either way, a block hands its context back when it ends: after trk 2: and its block, the next line is on the tracks it was on before.

Choosing the steps: steps and step

The context also holds a set of steps, at first every step of the pattern. steps changes it:

writethe steps become
steps allevery step
steps 9 16steps 9 to 16
steps has.trigthose of the current steps that hold a trig
steps is.emptythose of the current steps that are empty
step 5step 5 alone

A range replaces the steps; a test such as has.trig narrows the ones you already have. Operations that work on many steps at once, and each:, use this set:

Listing 5-3 · Accents on the hats, wherever their trigs fall
def hat_accents
  menu "LEARN" >> "HAT ACCENT"
  trk 3:
    tr.clr
    l 1 16: if er 11 16 i: tr.add i
    steps has.trig:
      each: pl.set i amp.vol dr.v 1 i
Output · what the simulator prints for $ otype.py run hat_accents -v
hat_accents  seed 1 (--seed)  pattern A01 len 16 (default)  track 1
T3  1   5   9   13
    X.XX.XX.XX.XX.XX
    step 1: amp.vol 127   step 3: amp.vol 80   step 4: amp.vol 80   step 6: amp.vol 80
    step 7: amp.vol 80   step 9: amp.vol 127   step 10: amp.vol 80   step 12: amp.vol 80
    step 13: amp.vol 127   step 15: amp.vol 80   step 16: amp.vol 80
      X trig  ! one-shot  o trigless trig  - trigless lock  l locks only  . none
part:  tempo 120
cost: 283/674   random draws: rand 0  toss 0  prob 0  drunk 0  file 0

each: visits the steps that hold a trig, and dr.v 1 i reads curve 1, accents on the beats, at step i.

Locks go where the trigs are

On the Octatrack, a lock belongs to a trig. OType follows the machine: a lock written on an empty step is skipped, and the simulator counts it.

Listing 5-4 · Sixteen locks asked, two written
def two_locks
  menu "LEARN" >> "TWO LOCKS"
  tr.clr
  tr.add 1
  tr.add 9
  l 1 16: pl.set i amp.vol 64
Output · what the simulator prints for $ otype.py run two_locks -v
two_locks  seed 1 (--seed)  pattern A01 len 16 (default)  track 1
T1  1   5   9   13
    X.......X.......
    step 1: amp.vol 64   step 9: amp.vol 64
      X trig  ! one-shot  o trigless trig  - trigless lock  l locks only  . none
part:  tempo 120
cost: 216/216   random draws: rand 0  toss 0  prob 0  drunk 0  file 0
two_locks: 14 skipped, no trig (pl.set line 6 x14)

To lock a step without playing it, first make it a trigless lock: tl.add s.

A function inherits the context

When one of your functions calls another, the called function starts with a copy of the caller's context: the same tracks and steps. Whatever it changes stays inside it. This is what lets the next study write a function once and use it on any track.

What you learned

trk 1 2: · trk cur · trk all
the tracks, one pass per track
trk 2 alone
the tracks until the end of the block
steps a b · steps has.trig · step s
the steps: a range, a test, one step
each:
visit the steps of the context
dr.v c s
a velocity from a ready-made curve
tl.add s
a trigless lock: a step that can hold locks without playing

Try it

  • Put the snare of beat on track 2 with a single if inside a loop.
  • Lock a random volume on every trig of tracks 1 to 4 with steps has.trig and rrand 60 127.
  • Use steps 9 16 to clear only the second half of the bar with tr.clr.