Function
(set-receiver!hook stream)
Installs hook to receive stream data as soon as
it arrives from an external application. No values are returned
by set-receiver! or
by hook. Receiving remains in effect until canceled by
remove-receiver!.
The calling syntax of hook depends on stream:
Receiving is implemented in the following Lisp/OS combinations (the following only applies to the original version of cm from 2007!):
From the caller's perspective hook appears to receive data asynchronously but actually receiving is always polling in some manner; how this polling is implemented depends on what facilities the host Lisp provides. CM utilizes two different strategies for implementing non-blocking receiving:
;; Receiving input from Jackmidi (cm-incudine). ;;; open with no latency for interactive work. the input and ;;; output device ids to open will depend on your MIDI setup. (define *midi-in* (jackmidi:open :direction :input) (define *incudine-stream* (new incudine-stream)) ;;; a midi through (set-receiver! (lambda (mm ms) ms (output mm :to *incudine-stream*)) *midi-in*) ;;; play your keyboard...then (remove-receiver! *midi-in*) ;;; make a harmonizer (set-receiver! (lambda (mm ms) ms (if (or (note-on-p mm) (note-off-p mm)) (let ((k (note-on-key mm))) (output mm :to *incudine-stream*) (output (midi-copy-message mm :data1 (+ k 3)) :to *incudine-stream*) (output (midi-copy-message mm :data1 (+ k 7)) :to *incudine-stream*)))) *midi-in*) ;;; play your keyboard...then (remove-receiver! *midi-in*) (jackmidi:close *midi-in*) ;; Receiving input from Portmidi. ;;; open with no latency for interactive work. the input and ;;; output device ids to open will depend on your MIDI setup. (define *pm* (portmidi-open :input 1 :output 3 :latency 0)) ;;; a midi through (set-receiver! (lambda (mm ms) ms (output mm :to *pm*)) *pm*) ;;; play your keyboard...then (remove-receiver! *pm*) ;;; make a harmonizer (set-receiver! (lambda (mm ms) ms (if (or (note-on-p mm) (note-off-p mm)) (let ((k (note-on-key mm))) (output mm :to *pm*) (output (midi-copy-message mm :data1 (+ k 3)) :to *pm*) (output (midi-copy-message mm :data1 (+ k 7)) :to *pm*)))) *pm*) ;;; play your keyboard...then (remove-receiver! *pm*) (portmidi-close) ;; Using a receiver to trigger processes in rts. (define (tonto len knum wai amp) (process repeat len output (new midi :time (now) :duration .1 :amplitude amp :keynum (between knum (+ knum 12))) wait wai)) (define (trigger mm ms) ms (if (note-on-p mm) (sprout (tonto 10 (note-on-key mm) .1 (/ (note-on-velocity mm) 127.0))))) (define *midi-in* (jackmidi:open :direction :input) (define *incudine-stream* (new incudine-stream)) (set-receiver! #'trigger *midi-in*) ;;; play your keyboard...then (remove-receiver! *midi-in*) (rts-stop) (portmidi-close)