/cl-alsaseq

Common Lisp interface to ALSA MIDI.

Primary LanguageCommon Lisp

cl-alsaseq

This is cl-alsaseq, a Common Lisp library for accessing the ALSA MIDI interface. With it, you can send and receive MIDI messages to and from any program or device that is supported by ALSA.

This library was originally written by Richard Venn, however after he deleted his GitHub account (and the original repo for this project with it), I (modula t.) re-hosted it.

I’m making a few improvements here and there to the system, however most major improvements will instead be done as part of cl-alsa-midi.

If you’re just using the library for your own projects and need something stable, use cl-alsaseq. cl-alsaseq’s API should remain stable, but it will not be submitted to Quicklisp.

If you’re intending to make improvements to the code of the library, consider adding them to cl-alsa-midi instead, as I intend to deprecate cl-alsaseq in favor of it, as it (and its API) will be vastly simpler and its code should be much improved. After cl-alsa-midi’s API is improved and stabilized, it will be submitted to Quicklisp.

Example

(ql:quickload :cl-alsaseq) ; Load the system.

;; Define a basic handler function for MIDI input.
(defun midi-map (messages)
  (dolist (message messages)
    (let* ((event-type (getf message :event-type))
           (event-data (getf message :event-data))
           (source (car (getf message :source)))
           (destination (car (getf message :dest))))
      (declare (ignorable source destination))
      (format t "~A: ~S~%"
              (case event-type
                (:snd_seq_event_noteon "Note on")
                (:snd_seq_event_noteoff "Note off")
                (:snd_seq_event_controller "CC")
                (t event-type))
              event-data))))

;; Start the ALSA MIDI client with midi-map function as input handler.
(midihelper:start-midihelper :master 96 'midi-map)

;; ...Then connect the "CL" ALSA MIDI source to the destination of your choice.
;; I usually use Qjackctl to manage MIDI connections.

(defparameter *midi-channel* 0)

(midihelper:send-event (midihelper:ev-noteon *midi-channel* 69 127)) ; Send a MIDI note on event. 69 is the note number, 127 is the velocity

(midihelper:send-event (midihelper:ev-noteoff *midi-channel* 69 127)) ; Send a MIDI note off to stop the previous note.

(midihelper:send-event (midihelper:ev-pgmchange *midi-channel* 2)) ; Send a program change message to switch to program #2.