Skip to content

stmcall

Saves the state of a runner under a name.

The saved state can be restored later with stmrecall.

Syntax

kdone = stmcall(irunner, Sname, ktrig)
kdone stmcall irunner, Sname, ktrig

Initialization

irunner -- a runner handle, returned by stminstance.

Performance

Sname -- the name of the saved state, from 1 to 63 characters. A name works as a save slot: saving under a name that already exists in the runner replaces that state.

ktrig -- the action happens when ktrig becomes greater than 0, that is on the first pass where it is positive after being 0 or less. A trigger that is positive on the very first pass also counts. Holding ktrig high does not repeat the action.

kdone -- 1 on the pass where the state is saved, 0 otherwise.

The saved state is the current node, the previous node, the pending request and the clock (tick count, graph time and node time). The event history and the paused state are not saved. Saving also works while the runner is paused.

A runner keeps up to 100 names. When it is full, saving under a new name replaces the oldest one. On a deleted runner, stmcall does nothing and outputs 0.

This opcode changes the runner, so it counts as a writer: a runner accepts writers from one instrument instance at a time. See Writers and observers.

Examples

A runner walks a chain of sections, one per control period. Its state at Verse is saved with stmcall and restored twice with stmrecall, so the walk from Verse is repeated with the same node and the same clock. It uses the file stm-checkpoint.csd.

Saving and restoring the state of a runner.
<CsoundSynthesizer>
<CsOptions>
-n -d -m0
</CsOptions>
<CsInstruments>
sr = 48000
ksmps = 480
nchnls = 1
0dbfs = 1

; stmcall saves the state of a runner under a name, stmrecall brings it
; back. The runner walks a chain of sections, one per control period.
; The state at "Verse" is saved, and recalled twice from "Outro", so the
; walk from "Verse" is repeated with the same node and the same clock.
; A name works as a save slot: each save under "verse" replaces the last.

builder:i = stmcreate()
stmaddnode(builder, "Intro")
stmaddnode(builder, "Verse")
stmaddnode(builder, "Chorus")
stmaddnode(builder, "Outro")
stmaddedge(builder, "Intro", "Verse")
stmaddedge(builder, "Verse", "Chorus")
stmaddedge(builder, "Chorus", "Outro")
gi_runner@global:i = stminstance(stmcompile(builder))

instr 1
  r:i = gi_runner
  cycle:k init 0
  cycle += 1

  node:S = stmcurrent(r)
  tick:k = stmtick(r)

  ; save each time the walk is on Verse (the trigger rises on every pass)
  saved:k = stmcall(r, "verse", strcmpk(node, "Verse") == 0 ? 1 : 0)

  ; one step along the chain per control period
  if strcmpk(node, "Intro") == 0 then
    stmnext(r, "Verse")
  elseif strcmpk(node, "Verse") == 0 then
    stmnext(r, "Chorus")
  elseif strcmpk(node, "Chorus") == 0 then
    stmnext(r, "Outro")
  endif

  status:k, from:k, to:k = stmadvance(r)

  ; at Outro, go back to the saved state, but only twice
  repeats:k init 0
  recall:k = 0
  if strcmpk(node, "Outro") == 0 && repeats < 2 then
    recall = 1
    repeats += 1
  endif
  restored:k = stmrecall(r, "verse", recall)

  printks("cycle %2d  tick %d  %-6s  saved %d  restored %d  -> %s\n", 0, \
          cycle, tick, node, saved, restored, stmcurrent(r))
endin
</CsInstruments>
<CsScore>
i 1 0 0.10
e
</CsScore>
</CsoundSynthesizer>

Its output is:

cycle  1  tick 0  Intro   saved 0  restored 0  -> Verse
cycle  2  tick 1  Verse   saved 1  restored 0  -> Chorus
cycle  3  tick 2  Chorus  saved 0  restored 0  -> Outro
cycle  4  tick 3  Outro   saved 0  restored 1  -> Verse
cycle  5  tick 1  Verse   saved 1  restored 0  -> Chorus
cycle  6  tick 2  Chorus  saved 0  restored 0  -> Outro
cycle  7  tick 3  Outro   saved 0  restored 1  -> Verse
cycle  8  tick 1  Verse   saved 1  restored 0  -> Chorus
cycle  9  tick 2  Chorus  saved 0  restored 0  -> Outro
cycle 10  tick 3  Outro   saved 0  restored 0  -> Outro

The trigger of stmcall rises on every pass through Verse, so "verse" is saved again in cycles 5 and 8; each save replaces the previous one, here with the same state. Each recall restores the node and the tick count, so the walk from Verse repeats exactly.

See also

State Machine Graphs

stmrecall, stmreset

Credits

Author: Pasquale Mainolfi
Italy
New in Csound version 7.0
October 2026