Registers are a thing that's part of Runt. Basically, it's a global array of runt_stacklet types. Using this, one is able to push stuff on to the stack, pop it off, and store it indefinitely until it is written again.

The number of registers that runt has is defined by the compile time-macro RUNT_REGISTER_SIZE. By default, this value is 16. If you need to change this, you must recompile runt, not just the macro.


regget and regset are used to store and retrieve items in the registers.


cabget and cabset are specialized versions of regget and regset, used to store held patchwerk cables.

dynamic cable generation with mkcab

Keeping track of registers for cables can be tedious work. Luckily, there is an operation which automates this a little bit.

The scheme function monolith:mkcab can be used to store and hold a signal. It will return a register number that can be used with cabget, and then cleared with cabclr when it is finished.

The first argument is a lambda for the signal, and the second argument is the suggested starting register. The function works by going through each

In the example below, a single oscillator using phase distortion synthesis is modulated with a LFO signal stored in register lfo. let* is ideal to use because it allows mkcab to sequentially set values.

(define (phasedist-voice)
  (gen_sine (ftnew 8192))
  (regset zz 0)
  (let* ((note 58)
         (ft (lambda () (regget 0)))
         (lfo (monolith:mkcab
               (lambda ()
                 (biscale (oscf (/ 1 28) 0 ft) 0 1)) 0)))
    (phasor (mtof
                 (oscf (scale (cabget lfo) 4 6) 0 ft)
                 (scale (cabget lfo) 0 0.3)) note)) 0)
    (pdhalf zz (scale (cabget lfo) 0 0.8))
    (oscfext zz ft)
    (mul zz 0.3)
    (cabclr lfo))
    (out zz))