Skip to content

stmresume

Resumes a paused runner.

Syntax

stmresume(irunner, ktrig)
stmresume irunner, ktrig

Initialization

irunner -- a runner handle, returned by stminstance.

Performance

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.

Resuming clears the pending request and records a resume event (kind 6). The runner continues from the node it was paused on, and its clock moves again from the next stmadvance. A runner that is not paused is not affected.

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

One instrument drives a runner through transitions, a pause, a resume and a deletion. A second instrument watches it with stmonenter, stmonexit and stmevent. It uses the file stm-events.csd.

Watching transitions and events.
<CsoundSynthesizer>
<CsOptions>
-n -d -m0
</CsOptions>
<CsInstruments>
sr = 48000
ksmps = 480
nchnls = 1
0dbfs = 1

; Watching a runner: stmonenter and stmonexit fire on transitions, and
; stmevent reads every runner event in order, including pause, resume
; and delete. The writer and the observers are in different instruments.

; A <-> B, plus a self edge on B
builder:i = stmcreate()
stmaddnode(builder, "A")    ; id 0
stmaddnode(builder, "B")    ; id 1
stmaddedge(builder, "A", "B")
stmaddedge(builder, "B", "A")
stmaddedge(builder, "B", "B")
gi_runner@global:i = stminstance(stmcompile(builder))

; the writer: a scripted sequence of requests and controls
instr 1
  r:i = gi_runner
  cycle:k init 0
  cycle += 1

  if cycle == 1 then
    stmnext(r, "B")
  elseif cycle == 2 then
    stmnext(r, "B")               ; self transition
  elseif cycle == 4 then
    stmnext(r, "A")               ; ignored: the runner is paused
  elseif cycle == 6 then
    stmnext(r, "A")
  elseif cycle == 8 then
    stmnext(r, "B")               ; ignored: the runner is deleted
  endif

  stmpause(r, cycle == 3 ? 1 : 0)
  stmresume(r, cycle == 5 ? 1 : 0)
  stmdelete(r, cycle == 7 ? 1 : 0)

  status:k, from:k, to:k = stmadvance(r)
  printks("cycle %d: advance status %d\n", 0, cycle, status)
endin

; an observer, scheduled after the writer in each control period
instr 2
  r:i = gi_runner
  enterB:k = stmonenter(r, "B")
  exitB:k = stmonexit(r, "B")
  if enterB == 1 || exitB == 1 then
    printks("  enter B %d, exit B %d\n", 0, enterB, exitB)
  endif

  ; drain every event published since the previous pass
  more:k = 1
  while more == 1 do
    kind:k, seq:k, lost:k, more, from:k, to:k = stmevent(r)
    if more == 1 then
      printks("  event %d: kind %d, %d -> %d, overflow %d\n", 0, seq, kind, from, to, lost)
    endif
  od
endin
</CsInstruments>
<CsScore>
i 1 0 0.09
i 2 0 0.09
e
</CsScore>
</CsoundSynthesizer>

Its output is:

cycle 1: advance status 1
  enter B 1, exit B 0
  event 1: kind 1, 0 -> 1, overflow 0
cycle 2: advance status 3
  enter B 1, exit B 1
  event 2: kind 2, 1 -> 1, overflow 0
cycle 3: advance status 5
  event 3: kind 5, 1 -> 1, overflow 0
cycle 4: advance status 5
cycle 5: advance status 0
  event 4: kind 6, 1 -> 1, overflow 0
cycle 6: advance status 1
  enter B 0, exit B 1
  event 5: kind 1, 1 -> 0, overflow 0
cycle 7: advance status 6
  event 6: kind 7, 0 -> 0, overflow 0
cycle 8: advance status 6
cycle 9: advance status 6

Event kinds: 1 transition, 2 self transition, 5 pause, 6 resume, 7 delete. The self transition in cycle 2 fires both the enter and the exit trigger of B. The request in cycle 4 is ignored because the runner is paused, and the one in cycle 8 because it is deleted. Pause, resume and delete appear as events but do not fire the enter and exit triggers.

See also

State Machine Graphs

stmpause, stmadvance

Credits

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