From f3a6b660d68c4cb3372014fc4d1046e600422ced Mon Sep 17 00:00:00 2001 From: Christopher Arndt Date: Sat, 27 May 2023 16:22:06 +0200 Subject: [PATCH] feat: add MIDI receiver example showing use of threading/channels Signed-off-by: Christopher Arndt --- examples/jacket_midi_print_threading.nim | 130 +++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 examples/jacket_midi_print_threading.nim diff --git a/examples/jacket_midi_print_threading.nim b/examples/jacket_midi_print_threading.nim new file mode 100644 index 0000000..e11fe1f --- /dev/null +++ b/examples/jacket_midi_print_threading.nim @@ -0,0 +1,130 @@ +# This requires the 'threading' module and either nim 1.9+ +# or --threads:on: +# +# nimble install threading +# + +import std/[isolation, logging, os, strformat] +import threading/channels +import signal +import jacket + +var + jclient: ClientP + event: MidiEvent + midiPort: PortP + midiEventChan: Chan[MidiEvent] + midiEventPrinter: Thread[void] + status: cint + exitSignalled: bool = false + +var log = newConsoleLogger(when defined(release): lvlInfo else: lvlDebug) + + +proc cleanup() = + debug "Cleaning up..." + + if jclient != nil: + debug "Deactivating JACK client..." + discard jclient.deactivate() + + if midiEventPrinter.running: + debug "Stopping MIDI event printer thread..." + # Receiving an invalid event causes receiving thread to wake up and + # break its endless loop + event.size = 0 + midiEventChan.send(event) + + midiEventPrinter.joinThread() + + if jclient != nil: + debug "Closing JACK client..." + discard jclient.clientClose() + jclient = nil + + debug "Bye." + +proc errorCb(msg: cstring) {.cdecl.} = + # Suppress verbose JACK error messages when server is not available by + # default. Pass ``lvlAll`` when creating the logger to enable them. + debug "JACK error: " & $msg + +proc signalCb(sig: cint) {.noconv.} = + info "Received signal: " & $sig + exitSignalled = true + +proc shutdownCb(arg: pointer = nil) {.cdecl.} = + info "JACK server has shut down." + exitSignalled = true + +proc midiEventPrinterProc() = + var event: MidiEvent + + while true: + midiEventChan.recv(event) + + if event.size == 0: + break + elif event.size <= 3: + for i in 0..