samer@0: (import "samer.midi.*") samer@1: (import "javax.sound.midi.*") samer@0: samer@0: (define (tomidi in) samer@0: (letrec ( samer@0: (nout 49) ; room for 4 octaves samer@0: (patch (Matrix. "Synth" nout (.size in))) samer@0: (out (VVector. "sout" nout)) samer@0: (trigger (Trigger. out 1.0)) ; could use Latch instead samer@0: (events (.output trigger)) samer@0: (synth (MidiSynth. events))) samer@0: samer@0: (addtasks samer@0: (MatrixTimesVector. out patch in) samer@0: trigger synth) samer@0: samer@0: (matexec patch "load") samer@0: (exec synth "open") samer@0: (expose synth) samer@0: synth samer@0: ) samer@0: ) samer@0: samer@0: ; (import "javax.sound.midi.*") samer@0: samer@0: ; (define _synth null) samer@0: ; (define (synth) (set! _synth (javax.sound.midi.MidiSystem.getSynthesizer))) samer@0: ; (define (c0) (vector-ref (.getChannels _synth) 0)) samer@0: ; (define (open) (.open _synth)) samer@0: ; (define (close) (.close _synth)) samer@0: ; (define (on pitch) (.noteOn (c0) pitch 80)) samer@0: ; (define (off pitch) (.noteOff (c0) pitch 0)) samer@0: samer@0: samer@0: ;; trigger midi events from a signal using an 2 sample window and samer@0: ;; an onset map. samer@0: samer@0: (define (midirec L) samer@0: (define sigwin (SignalWindow. L 2)) samer@0: (define onset-map (OnsetMap. (.output sigwin))) samer@0: (define rec (MidiRecorderBase.)) samer@0: (define imap (LinearMap. 128)) samer@0: (define vel-map samer@0: (samer.core.util.VMap. imap (Node. "velmap"))) samer@0: samer@0: (matexec (.getBinMatrix onset-map) "load") samer@0: (Shell.exposeCommands rec) samer@0: (compound-task samer@0: sigwin samer@0: (.flushTask sigwin) samer@0: onset-map samer@0: (task samer@0: (if (.isOnset onset-map) samer@0: (.noteOn rec 0 (.clipInt imap (.get L)) 80) samer@0: ; (.noteOff rec 0 64) samer@0: ) samer@0: (.tick rec) samer@0: ) samer@0: ) samer@0: )