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 02 of 10

Numbers and expressions

In the quickstart, one line did all the work: if eq mod i 4 1: tr.add i. This study teaches you to read and write that kind of line: arithmetic, comparisons and logic. On the way, you build off-beat hats and accents from nothing but numbers.

Prefix notation

OType writes the operation first, then its values. There are no parentheses and no precedence to remember: each operation knows how many values it takes, and takes the ones that follow it.

add 1 mul 2 3

add  needs two values:
  1          the first
  mul 2 3    the second, itself an operation: 2 × 3 = 6
= 1 + 6 = 7

To see it for yourself, store the result in a variable and show it with msg, which writes a short text in the box at the end of the run (the simulator prints it too):

Listing 2-1 · Seeing a value
def math
  menu "LEARN" >> "MATH"
  a add 1 mul 2 3
  msg "A IS" a
Output · what the simulator prints for $ otype.py run math
math  seed 1 (--seed)  pattern A01 len 16 (default)  track 1
(no track holds anything)
      X trig  ! one-shot  o trigless trig  - trigless lock  l locks only  . none
part:  tempo 120
msg:   "A IS 7"
end box: "A IS 7" (the last msg, instead of DONE)
cost: 6/6   random draws: rand 0  toss 0  prob 0  drunk 0  file 0

a add 1 mul 2 3 is an assignment: a variable name, then a value. Variables have their own study; for now, a is a box that holds a number.

Read a long expression the same way: find the first operation, give it its values one by one, and when a value is itself an operation, complete that one first. eq mod i 4 1 is eq of two values: mod i 4 and 1. So it asks “is the remainder of i by 4 equal to 1?”.

Numbers

Every value is a whole number from −32768 to 32767. There are no fractions: a division drops them, so div 7 2 is 3 and div -7 2 is −3. A result beyond the range stops at its edge (mul 300 300 is 32767) instead of wrapping around, and the arithmetic never fails: dividing by zero gives 0.

writeormeans
add x y+ x yx + y
sub x y- x yx − y
mul x y* x yx × y
div x y/ x yx ÷ y, without the fraction (0 if y is 0)
mod x y% x ythe remainder, never negative: mod -1 4 is 3
min x y · max x ythe smaller · the larger
abs x · neg xwithout its sign · with the opposite sign
lim x lo hix, kept between lo and hi
wrap x lo hix, wrapped around into lo … hi

The symbols are only another spelling: + 1 * 2 3 is the same line as add 1 mul 2 3. A minus sign glued to a number, -3, is a negative number; spaced, - 3 1, it is a subtraction.

True and false

OType has no separate true and false: 0 is false, any other number is true. A comparison gives 1 when it holds and 0 when it does not.

writeoris 1 when
eq x y== x yx equals y
ne x y!= x yx differs from y
lt x y · gt x y< · >x is less · greater than y
le x y · ge x y<= · >=x is at most · at least y
ez x · nz xx is zero · x is not zero

Comparisons combine with logic: and x y, or x y, xor x y (one of the two, not both) and not x. Both sides of and and or are always computed.

Off-beat hats are the odd steps that are not on a beat: an odd step, and not a beat.

Listing 2-2 · Off-beat hats from two conditions
def offbeats
  menu "LEARN" >> "OFFBEATS"
  tr.clr
  l 1 16: if and eq mod i 2 1 ne mod i 4 1: tr.add i
Output · what the simulator prints for $ otype.py run offbeats
offbeats  seed 1 (--seed)  pattern A01 len 16 (default)  track 1
T1  1   5   9   13
    ..X...X...X...X.
      X trig  ! one-shot  o trigless trig  - trigless lock  l locks only  . none
part:  tempo 120
cost: 224/272   random draws: rand 0  toss 0  prob 0  drunk 0  file 0

Read the condition from the left: and takes two values, eq mod i 2 1 (i is odd) and ne mod i 4 1 (i is not 1, 5, 9 or 13). Steps 3, 7, 11 and 15 remain.

Choosing a value

? c a b is worth a when c is true, otherwise b. Only the chosen side is computed. Here it gives each step a volume: loud on the beats, soft in between.

Listing 2-3 · Accents: a volume lock chosen by ?
def accents
  menu "LEARN" >> "ACCENTS"
  tr.clr
  l 1 16:
    tr.add i
    pl.set i amp.vol ? eq mod i 4 1 127 60
Output · what the simulator prints for $ otype.py run accents -v
accents  seed 1 (--seed)  pattern A01 len 16 (default)  track 1
T1  1   5   9   13
    XXXXXXXXXXXXXXXX
    step 1: amp.vol 127   step 2: amp.vol 60   step 3: amp.vol 60   step 4: amp.vol 60
    step 5: amp.vol 127   step 6: amp.vol 60   step 7: amp.vol 60   step 8: amp.vol 60
    step 9: amp.vol 127   step 10: amp.vol 60   step 11: amp.vol 60   step 12: amp.vol 60
    step 13: amp.vol 127   step 14: amp.vol 60   step 15: amp.vol 60   step 16: amp.vol 60
      X trig  ! one-shot  o trigless trig  - trigless lock  l locks only  . none
part:  tempo 120
cost: 320/320   random draws: rand 0  toss 0  prob 0  drunk 0  file 0

Two new things here. The line l 1 16: ends with its :, so the loop repeats the indented lines below it, a block, instead of the rest of the line. And pl.set s param value writes a parameter lock on a step: amp.vol is the volume of the AMP page.

Rhythms in one word

Some operations are whole rhythms. er k n s is 1 when step s plays in a Euclidean rhythm of k hits spread over n steps:

Listing 2-4 · Five hits over sixteen steps
def five_of_16
  menu "LEARN" >> "EUCLID"
  tr.clr
  l 1 16: if er 5 16 i: tr.add i
Output · what the simulator prints for $ otype.py run five_of_16
five_of_16  seed 1 (--seed)  pattern A01 len 16 (default)  track 1
T1  1   5   9   13
    X...X..X..X..X..
      X trig  ! one-shot  o trigless trig  - trigless lock  l locks only  . none
part:  tempo 120
cost: 180/224   random draws: rand 0  toss 0  prob 0  drunk 0  file 0

dr.v c s gives a velocity from one of eight ready-made curves, step by step; you will see it in the tracks and steps study.

What you learned

prefix notation
the operation first, then exactly as many values as it takes
add sub mul div mod
arithmetic on whole numbers, also + - * / %
min max abs neg lim wrap
bounds and signs
eq ne lt gt le ge ez nz
comparisons: 1 or 0
and or xor not
logic; 0 is false, anything else true
? c a b
a if c, else b
er k n s
a Euclidean rhythm, step by step
pl.set s p v
a parameter lock on step s
msg …
a text at the end of the run

Try it

  • Compute sub 10 mul 2 add 1 2 in your head, then check it with msg.
  • Write the snare of a backbeat: a trig on steps 5 and 13 only, in one if.
  • Make the accents grow through the bar: a volume of add 40 mul i 5.