Coding in Time with the @ Scheduler

One idea I have for my theoretical computer music language is having scheduling built right into the syntax, with the hopes that it will add the right balance of functionality and clarity.

I like the idea of having a score language separate from the orchestra language, though I’ve learned over the years that this approach acts as a bottle neck. The @ scheduler is a potential solution to bring both together, without losing the purpose of the score.

Instead of going into great detail on how the @ scheduler might work, I’ll just present the following four examples.

Example 1 — Nested Time:

do_something()     # Do something at beat 0, (@0 assumed)
@2 do_something()  # Do something at beat 2

@5:
    do_something()     # Do something at beat 5: 5 + 0, (@0 assumed)
    @3 do_something()  # Do something at beat 8: 5 + 3
    
    @4:                    # Block starts at beat 9: 5 + 4
        do_something()     # Do something at beat 9: 5 + 4 + 0, (@0 assumed)
        @1 do_something()  # Do something at beat 10: 5 + 4 + 1

Example 2 — Changing values mid-event:

def foo():
    freq = 440                                 # Initial frequency
    @1 freq *= 2                               # Frequncy doubles at time 1
    output Wavetable.osc(1, freq, sine(8192))  # Output signal

Example 3 — Scheduler error:

def foo():
    @1 freq = 440
    output Wavetable.osc(1, freq, sine(8192))  # Broken, freq doesn't exist

Example 4 — Organized score + generated events:

def hat_eights():
    for i in range(0, 8):
        @(i / 2.0) hat()

@0:
    hat_eights()
    @0 kick()
    @1 snare()
    @2 kick()
    @3 snare()
    
@4:
    hat_eights()
    @0 kick()
    @1 snare()
    @2 kick()
    @2.5 kick()
    @3 snare()

That last example reminds me of Max Mathews’ Radio Baton Conductor language.