# 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..