Jump to content

midi-entry / data saving

Recommended Posts

dear all


as so often i try out strange things 🙂 i switch on midi-entry, read the pitches which i enter from a keyboard. everything clear so far. I am now trying to do this in a 2-second-loop (with sleep-function), so that variable X would always be assigned new values. at the end of the loop sequence, however, X is NIL. only when I evaluate X again are the values assigned. (see video)


(the idea is... to IMPORT live-midi into a "realtime-process")


some ideas?







Link to comment
Share on other sites

I don´t know if I got the whole idea but you can send a bunch of midi notes from any DAW to Opusmodus using a virtual midi cable.

Record whatever you like onto reaper, logic, ableton live, etc and set a virtual midi output port to Opusmodus.

You can send this midi notes at 3x the speed of original tempo if you like.

The length information can be obtained only by import midi, however.




It´s a sort of "mechamical solution" but I like it

Link to comment
Share on other sites

with OSC - (with the external osc-library i've sended you) - it should work similiar?

loop-function which PRINT the revcevied osc-values over and over (it works). i would like to do that with MIDI


but i'm not a lisp pro....

(code not by me)



(defparameter *in-port* 9999)
(defparameter *in-socket* (make-socket :type :datagram :local-port *in-port* :format :binary))

(setq *osc-receive*
      (process-run-function "osc-receive-process"
        #'(lambda ()

            (loop do (print (osc::decode-message (receive-from *in-socket* 2048)) #.*terminal-io*)))))

(process-kill *osc-receive*)  ;; Prozess wieder anhalten


Link to comment
Share on other sites

I have now found a SOLUTION that might be also interesting for LIVE CODING:


With the APP OSCulator you can convert midi-input (by an external keyboard) into OSC and then read it in real time (via osc-library + code) in OPMO (see video).


Of course, it could also be done directly from OSC (then via an APP such as TouchOSC from the mobile or tablet). you just have to reread the values (by a loop-function) as you can see in the video; in this way, certain parameters of the LIVE-CODING could be controlled / influenced from the outside.






a common lisp implementation of the Open Sound Control protocol aka OSC - GitHub - zzkt/osc: a common lisp implementation of the Open Sound Control protocol aka OSC




Links your controllers to your favorite music and video software. Works with Nintendo Wiimote, iPhone and more.







left-  PROTOKOL to see what's MIDI-in

right - midi to osc (OSCulator)

bottom - OPMO with midi-data PRINT in the listener 





(defparameter *remote-host* "")
(defparameter *in-port* 1234)
(defparameter *in-socket* (make-socket :type :datagram :local-port *in-port* :format :binary))

(setq *osc-receive*
      (process-run-function "osc-receive-process"
        #'(lambda ()
            (loop do (print (osc::decode-message (receive-from *in-socket* 2048)) #.*terminal-io*))))) ;; instead of PRINT you could use SETF

(process-kill *osc-receive*)  ;; STOP "listening process"

;;; CODE by philippe kocher



Link to comment
Share on other sites

here is a short sketch of how you can integrate a midi keyboard into live coding. evaluate the BASIC SETUP as before but in a LOOP (here 10 times) the LIVE-CODING setup, so a new value X (the PITCH (midi number) from the external keyboard) is always read in (which comes from the keyboard)...  


these values can now be used on various parameters. for this sketch only pitch + tempo (see: tempo (list (* x 3))


VIDEO: at the beginnig you see data coming in from midi keyboard




some code/sketch


(defparameter *remote-host* "")
(defparameter *in-port* 1234)
(defparameter *in-socket* (make-socket :type :datagram :local-port *in-port* :format :binary))

(setq *osc-receive*
      (process-run-function "osc-receive-process"
        #'(lambda ()
              do (print (setf x (second (osc::decode-message (receive-from *in-socket* 2048)))) #.*terminal-io*)))))


(loop repeat 10
  do (progn
       (def-score test1
                  (:key-signature '(c maj)
                                  :time-signature '(4 4)
                                  :tempo (list (* x 3))
                                  :start 1 :end 4)
          :omn (make-omn :pitch (list (midi-to-pitch x))
                         :length (gen-length-cartesian 1 1 'n 'n 'q '(2 3) '(13 4) '(1 2 3 4 5 6))
                         :span :length)
          :port 4
          :channel 1
          :sound 'gm
          :program 0
          :volume 127))
       (live-coding-midi (compile-score 'test1)))
  do (print x)
  do (sleep 3))

(process-kill *osc-receive*)  ;; Prozess wieder anhalten


Link to comment
Share on other sites



OSCulator (translates MIDI to OSC)


OPMO (reading pitch (midi number) and set to variable X)


1) evaluate (setq *osc-receive*.......)

2) start/evaluate LOOP-section

3) start LIVE-CODE

4) play your midi-keyboard


=> in every cycle of LIVE-CODING the "keyboard-pitch" will be read --- to variable X -> tempo and pitch are changing (by new cycle start)


5) stop all, incl.  evaluate (process-kill *osc-receive*)

Link to comment
Share on other sites

i know, of course, that LISP is not an environment for REALTIME actions (pure data / max would be much more suitable) - so I had to outsmart the system a little to import data (from a modularsynth and other applications) almost "on the fly" to generate a LIVE-SCORE (with the influence of this datas) at the concert/on the stage....


maybe i should learn MAX... for more smart-coded REALTIME things 😄



Link to comment
Share on other sites

  • 11 months later...

You don't need to use the make-socket function anymore, it was needed only in CCL.


All you need is:


Here we assign a name Reaktor to a remote-host: and remote- port: 10000:

(defparameter reaktor '( 10000))

Here we assign an variable to our OSC thread object, this is important for sending the data  with the thread and for ending the thread:

(setf thd1 (create-osc-thread "thread1" reaktor))

To send OSC messages with the thread we call the SEND-OSC-DATA function:

(send-osc-data thd1 '((0.0 1/2) (0.0 1/2) (0.08238555 2)
                      (0.10876829 1) (0.12127061 11/2)))


Link to comment
Share on other sites

but: some other "receiver" then REAKTOR need other DATA-formats, that's the thing, i think...



and with (send-osc-data) i didn't find a solution for that.... see post...










and with (MAKE-SOCKET... ) it was possible

Link to comment
Share on other sites

with send-osc-data it don't work, of course... the code before was exactly this ...


1. you need Nik Gaffney's osc package
2. load it
(load (merge-pathnames "osc.lisp" *load-truename*))
3. define global variable to hold socket, ip-address and port-no
(defparameter *out-socket* (make-socket :type :datagram))
(defparameter *remote-host* "")
(defparameter *remote-port* 47522)
4. define a send function
(defun udpsend (&rest args)
  (let ((message (apply' osc::encode-message args)))
    (send-to *out-socket* message (length message)
             :remote-host *remote-host*
             :remote-port *remote-port*)))

;; send
  (udpsend "/beat" "defer" 0 "duration" 1 "pattern" 12)
  (udpsend "/beat" "defer" 1 "duration" 1 "pattern" 22)
  (udpsend "/beat" "defer" 2 "duration" 1 "pattern" 22)
  (udpsend "/beat" "defer" 3 "duration" 1 "pattern" 21))




ensembles performed several concerts with it, so it worked 🙂 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...

Important Information

Terms of Use Privacy Policy