changelog shortlog graph tags branches changeset files file revisions raw help

Mercurial > core / annotate lisp/lib/dat/midi.lisp

changeset 698: 96958d3eb5b0
parent: 4e6838e03f61
author: Richard Westhaver <ellis@rwest.io>
date: Fri, 04 Oct 2024 22:04:59 -0400
permissions: -rw-r--r--
description: fixes
237
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
1
 ;;; dat/midi.lisp --- MIDI data
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
2
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
3
 ;;;  (c) copyright 2003 by Mathieu Chabanne, Camille Constant,
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
4
 ;;;                        Emmanuel Necibar and Stephanie Recco
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
5
 ;;;
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
6
 ;;;  (c) copyright 2003 by Robert Strandh (strandh@labri.fr)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
7
 ;;;
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
8
 ;;;  (c) copyright 2007 by David Lewis, Marcus Pearce, Christophe
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
9
 ;;;                        Rhodes and contributors
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
10
 ;;;
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
11
 ;;; This library is free software; you can redistribute it and/or
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
12
 ;;; modify it under the terms of version 2 of the GNU Lesser General
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
13
 ;;; Public License as published by the Free Software Foundation.
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
14
 ;;;
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
15
 ;;; This library is distributed in the hope that it will be useful,
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
16
 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
17
 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
18
 ;;; Lesser General Public License for more details.
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
19
 ;;;
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
20
 ;;; You should have received a copy of the GNU Lesser General Public
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
21
 ;;; License along with this library; if not, write to the
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
22
 ;;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
23
 ;;; Boston, MA  02111-1307  USA.
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
24
 ;;;
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
25
 ;;; This file contains library for MIDI and Midifiles. Messages are
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
26
 ;;; represented as CLOS class instances in a class hierarchy that
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
27
 ;;; reflects interesting aspects of the messages themselves.
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
28
 (in-package :dat/midi)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
29
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
30
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
31
 ;;;
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
32
 ;;; Midifile protocol
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
33
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
34
 (defgeneric midifile-format (midifile))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
35
 (defgeneric (setf midifile-format) (format midifile))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
36
 (defgeneric midifile-division (midifile))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
37
 (defgeneric midifile-tracks (midifile))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
38
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
39
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
40
 ;;;
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
41
 ;;; Message protocol
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
42
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
43
 (defgeneric message-time (message))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
44
 (defgeneric (setf message-time) (time message))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
45
 (defgeneric message-status (message))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
46
 (defgeneric message-channel (message))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
47
 (defgeneric message-key (message))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
48
 (defgeneric message-velocity (message))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
49
 (defgeneric message-tempo (message))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
50
 (defgeneric message-numerator (message))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
51
 (defgeneric message-denominator (message))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
52
 (defgeneric message-sf (message))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
53
 (defgeneric message-mi (message))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
54
 ;; added 03-05-07
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
55
 (defgeneric message-program (message))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
56
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
57
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
58
 ;;;
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
59
 ;;; File support
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
60
 (eval-when (:compile-toplevel :load-toplevel)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
61
   (defun string-code (s)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
62
     "compute the ASCII-based numerical value of the string [warning:
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
63
 works only if the chars are coded in ASCII]"
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
64
     (let ((v 0))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
65
       (loop for i from 0 to (1- (length s))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
66
 	    do (setf v (+ (* v 256) (char-code (aref s i)))))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
67
       v)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
68
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
69
 (defconstant +header-mthd+ #.(string-code "MThd"))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
70
 (defconstant +header-mtrk+ #.(string-code "MTrk"))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
71
 (defconstant +header-mthd-length+ 6 "value of the header MThd data's length")
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
72
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
73
 (defparameter *midi-input* nil "stream for reading a Midifile")
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
74
 (defparameter *input-buffer* '() "used for unreading bytes from *midi-input")
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
75
 (defparameter *midi-output* nil "stream for writing a Midifile")
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
76
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
77
 (define-condition unknown-event ()
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
78
   ((status :initarg :status :reader status)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
79
    (data-byte :initform "" :initarg :data-byte :reader data-byte))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
80
   (:documentation "condition when the event does not exist in the library"))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
81
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
82
 (define-condition header ()
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
83
   ((header-type :initarg :header :reader header-type))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
84
   (:documentation "condition when the header is not correct"))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
85
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
86
 (defun read-next-byte ()
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
87
   "read an unsigned 8-bit byte from *midi-input* checking for unread bytes"
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
88
   (if *input-buffer*
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
89
       (pop *input-buffer*)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
90
       (read-byte *midi-input*)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
91
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
92
 (defun unread-byte (byte)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
93
   "unread a byte from *midi-input*"
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
94
   (push byte *input-buffer*))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
95
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
96
 (defun write-bytes (&rest bytes)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
97
   "write an arbitrary number of bytes to *midi-output*"
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
98
   (mapc #'(lambda (byte) (write-byte byte *midi-output*)) bytes))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
99
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
100
 (defun read-fixed-length-quantity (nb-bytes)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
101
   "read an unsigned integer of nb-bytes bytes from *midi-input*"
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
102
   (loop with result = 0
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
103
 	for i from 1 to nb-bytes
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
104
 	do (setf result (logior (ash result 8) (read-next-byte)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
105
 	finally (return result)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
106
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
107
 (defun write-fixed-length-quantity (quantity nb-bytes)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
108
   "write an unsigned integer of nb-bytes bytes to *midi-output*"
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
109
   (unless (zerop nb-bytes)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
110
     (write-fixed-length-quantity (ash quantity -8) (1- nb-bytes))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
111
     (write-bytes (logand quantity #xff))))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
112
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
113
 (defmacro with-midi-input ((pathname &rest open-args &key &allow-other-keys) &body body)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
114
   "execute body with *midi-input* assigned to a stream from pathname"
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
115
   `(with-open-file (*midi-input* ,pathname
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
116
 		                 :direction :input :element-type '(unsigned-byte 8)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
117
 		                 ,@open-args)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
118
      ,@body))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
119
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
120
 (defmacro with-midi-output ((pathname &rest open-args &key &allow-other-keys) &body body)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
121
   "execute body with *midi-output* assigned to a stream from pathname"
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
122
   `(with-open-file (*midi-output* ,pathname
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
123
 		                  :direction :output :element-type '(unsigned-byte 8)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
124
 		                  ,@open-args)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
125
      ,@body))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
126
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
127
 (defun read-variable-length-quantity ()
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
128
   "read a MIDI variable length quantity from *midi-input*"
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
129
   (loop with result = 0
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
130
 	with byte
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
131
 	do (setf byte (read-next-byte)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
132
 		 result (logior (ash result 7) (logand byte #x7f)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
133
 	until (< byte #x80)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
134
 	finally (return result)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
135
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
136
 (defun write-variable-length-quantity (quantity &optional (termination 0))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
137
   (when (> quantity 127)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
138
     (write-variable-length-quantity (ash quantity -7) #x80))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
139
   (write-bytes (logior (logand quantity #x7f) termination)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
140
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
141
 (defun length-of-variables-length-quantity (quantity)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
142
   (1+ (if (< quantity 128)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
143
 	  0
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
144
 	  (length-of-variables-length-quantity (ash quantity -7)))))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
145
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
146
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
147
 ;;;
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
148
 ;;; MIDI file representation
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
149
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
150
 (defclass midifile ()
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
151
   ((format :initarg :format :reader midifile-format)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
152
    (division :initarg :division :reader midifile-division)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
153
    (tracks :initarg :tracks :reader midifile-tracks))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
154
   (:documentation "the class that represents a Midifile in core"))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
155
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
156
 (defparameter *status* nil "the status while reading an event")
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
157
 (defparameter *running-status* nil "the running status while reading an event")
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
158
 (defparameter *dispatch-table* (make-array 256 :initial-element nil)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
159
   "given values of status (and perhaps data1), find a class to create")
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
160
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
161
 (defun read-message ()
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
162
   "read a message without time indication from *midi-input*"
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
163
   (let ((classname-or-subtype (aref *dispatch-table* *status*)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
164
     (unless classname-or-subtype
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
165
       (error (make-condition 'unknown-event
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
166
 			     :status *status*)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
167
     (if (symbolp classname-or-subtype)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
168
 	(make-instance classname-or-subtype)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
169
 	(let* ((data-byte (read-next-byte))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
170
 	       (classname (aref classname-or-subtype data-byte)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
171
 	  (unless classname
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
172
 	    (error (make-condition 'unknown-event
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
173
 				   :status *status*
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
174
 				   :data-byte data-byte)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
175
 	  (unread-byte data-byte)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
176
 	  (make-instance classname)))))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
177
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
178
 (defparameter *time* 0 "accumulated time from the start of the track")
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
179
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
180
 (defun read-timed-message ()
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
181
   "read a message preceded with a delta-time indication"
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
182
   (let ((delta-time (read-variable-length-quantity))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
183
 	(status-or-data (read-next-byte)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
184
     (if (>= status-or-data #x80)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
185
 	(progn (setf *status* status-or-data)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
186
 	       (when (<= *status* #xef)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
187
 		 (setf *running-status* *status*)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
188
 	(progn (unread-byte status-or-data)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
189
 	       (setf *status* *running-status*)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
190
     (let ((message (read-message)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
191
       (fill-message message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
192
       (setf (message-time message) (incf *time* delta-time))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
193
       message)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
194
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
195
 (defun write-timed-message (message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
196
   "write a message preceded with a delta-time indication"
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
197
   (write-variable-length-quantity (- (message-time message) *time*))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
198
   (setf *time* (message-time message))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
199
   (write-message message))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
200
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
201
 (defun read-track ()
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
202
   "read a track as a list of timed messages, excluding the end-of-track message"
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
203
   (let ((type (read-fixed-length-quantity 4))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
204
 	(length (read-fixed-length-quantity 4)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
205
     (declare (ignore length))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
206
     (unless (= type +header-mtrk+)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
207
       (error (make-condition 'header :header "MTrk")))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
208
     (loop with message = nil
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
209
 	  do (setf message (read-timed-message))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
210
 	  until (typep message 'end-of-track-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
211
 	  collect message)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
212
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
213
 (defun write-track (track)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
214
   "write a track (which does not contain the end-of-track message"
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
215
   (write-fixed-length-quantity  +header-mtrk+ 4)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
216
   (let ((end-of-track-message (make-instance 'end-of-track-message)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
217
     ;; write the length of the track
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
218
     (write-fixed-length-quantity
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
219
      (+ (reduce #'+ track :key #'length-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
220
 	(length-message end-of-track-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
221
 	(loop with time = *time*
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
222
 	      for message in track
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
223
 	      sum (prog1 (length-of-variables-length-quantity
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
224
 			  (- (message-time message) time))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
225
 		    (setf time (message-time message))))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
226
 	1) ; the delta time of the end-of-track message
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
227
      4)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
228
     (dolist (message track)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
229
       (write-timed-message message))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
230
     (setf (message-time end-of-track-message) *time*)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
231
     (write-timed-message end-of-track-message)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
232
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
233
 (defun read-midi-file (filename)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
234
   "read an entire Midifile from the file with name given as argument"
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
235
   (setf *time* 0)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
236
   (with-midi-input (filename)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
237
     (let ((type (read-fixed-length-quantity 4))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
238
 	  (length (read-fixed-length-quantity 4))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
239
 	  (format (read-fixed-length-quantity 2))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
240
 	  (nb-tracks (read-fixed-length-quantity 2))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
241
 	  (division (read-fixed-length-quantity 2)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
242
       (unless (and (= length +header-mthd-length+) (= type +header-mthd+))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
243
 	(error (make-condition 'header :header "MThd")))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
244
       (make-instance 'midifile
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
245
 	:format format
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
246
 	:division division
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
247
 	:tracks (loop repeat nb-tracks
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
248
 		      do (when (= format 1) (setf *time* 0))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
249
 		      collect (read-track))))))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
250
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
251
 (defun write-midi-file (midifile filename)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
252
   (with-midi-output (filename :if-exists :supersede)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
253
     (write-fixed-length-quantity +header-mthd+ 4)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
254
     (write-fixed-length-quantity +header-mthd-length+ 4)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
255
     (with-slots (format division tracks) midifile
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
256
       (write-fixed-length-quantity format 2)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
257
       (write-fixed-length-quantity (length tracks) 2)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
258
       (write-fixed-length-quantity division 2)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
259
       (setf *time* 0)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
260
       (loop for track in tracks do
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
261
 	(write-track track)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
262
 	(when (= (slot-value midifile 'format) 1)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
263
 	  (setf *time* 0))))))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
264
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
265
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
266
 ;;;
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
267
 ;;; Conversion routines
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
268
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
269
 (defun format1-tracks-to-format0-tracks (tracks)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
270
   (list (reduce (lambda (t1 t2) (merge 'list t1 t2 #'< :key #'message-time))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
271
 		(copy-tree tracks))))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
272
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
273
 (defun format0-tracks-to-format1-tracks (tracks)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
274
   (assert (null (cdr tracks)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
275
   (let (tempo-map track)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
276
     (dolist (message (car tracks) (list (nreverse tempo-map) (nreverse track)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
277
       (if (typep message 'tempo-map-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
278
 	  (push message tempo-map)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
279
 	  (push message track)))))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
280
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
281
 (defun change-to-format-0 (midifile)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
282
   (assert (= (midifile-format midifile) 1))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
283
   (setf (slot-value midifile 'format) 0
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
284
 	(slot-value midifile 'tracks) (format1-tracks-to-format0-tracks (midifile-tracks midifile))))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
285
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
286
 (defun change-to-format-1 (midifile)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
287
   (assert (= (midifile-format midifile) 0))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
288
   (setf (slot-value midifile 'format) 1
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
289
 	(slot-value midifile 'tracks) (format0-tracks-to-format1-tracks (midifile-tracks midifile))))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
290
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
291
 (defmethod (setf midifile-format) (new-value midifile)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
292
   (cond
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
293
     ((= (midifile-format midifile) new-value) new-value)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
294
     ((and (= new-value 0) (= (midifile-format midifile) 1))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
295
      (change-to-format-0 midifile)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
296
      new-value)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
297
     ((and (= new-value 1) (= (midifile-format midifile) 0))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
298
      (change-to-format-1 midifile)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
299
      new-value)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
300
     (t (error "Unsupported conversion from format ~S to format ~S"
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
301
 	      (midifile-format midifile) new-value))))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
302
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
303
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
304
 ;;;
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
305
 ;;; Macro for defining midi messages
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
306
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
307
 (defparameter *status-min* (make-hash-table :test #'eq)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
308
   "given a class name, find the minimum status value for the type of message")
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
309
 (defparameter *status-max* (make-hash-table :test #'eq)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
310
   "given a class name, find the maximum status value for the type of message")
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
311
 (defparameter *data-min* (make-hash-table :test #'eq)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
312
   "given a class name, find the minimum data1 value for the type of message")
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
313
 (defparameter *data-max* (make-hash-table :test #'eq)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
314
   "given a class name, find the maximum data1 value for the type of message")
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
315
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
316
 (defun register-class (class superclass status-min status-max data-min data-max)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
317
   (unless status-min
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
318
     (setf status-min (gethash superclass *status-min*)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
319
   (unless status-max
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
320
     (setf status-max (gethash superclass *status-max*)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
321
   (unless data-min
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
322
     (setf data-min (gethash superclass *data-min*)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
323
   (unless data-max
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
324
     (setf data-max (gethash superclass *data-max*)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
325
   ;; set status values for this class
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
326
   (setf (gethash class *status-min*) status-min)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
327
   (setf (gethash class *status-max*) status-max)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
328
   (setf (gethash class *data-min*) data-min)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
329
   (setf (gethash class *data-max*) data-max)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
330
   ;; update the dispatch table
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
331
   (when status-min
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
332
     (if data-min
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
333
 	(progn (unless (arrayp (aref *dispatch-table* status-min))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
334
 		 (let ((secondary-dispatch (make-array 256
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
335
 						       :initial-element nil)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
336
 		   (loop for i from status-min to status-max do
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
337
 		     (setf (aref *dispatch-table* i) secondary-dispatch))))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
338
 	       (loop for i from data-min to data-max do
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
339
 		 (setf (aref (aref *dispatch-table* status-min) i)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
340
 		       class)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
341
 	(loop for i from status-min to status-max do
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
342
 	  (setf (aref *dispatch-table* i)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
343
 		class)))))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
344
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
345
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
346
 ;;;
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
347
 ;;; main filler, length, and writer methods
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
348
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
349
 (defgeneric fill-message (message))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
350
 (defgeneric write-message (message))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
351
 (defgeneric length-message (message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
352
   (:method-combination +))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
353
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
354
 (defmethod fill-message (message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
355
   (declare (ignore message))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
356
   nil)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
357
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
358
 (defmethod length-message + (message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
359
   (declare (ignore message))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
360
   0)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
361
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
362
 (defmethod write-message (message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
363
   (declare (ignore message))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
364
   nil)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
365
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
366
 (defparameter *midi-channel* 0
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
367
   "Default MIDI channel for midi-messages for which status-min and status-max
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
368
 have a difference of 15.  When bound to an \(<= 0 integer 15\), the :status
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
369
 default value will automatically combine the message's status-min and
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
370
 *midi-channel*.")
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
371
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
372
 (defmacro define-midi-message (name superclasses
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
373
 			       &key slots filler (length 0) writer
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
374
 			         status-min status-max data-min data-max)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
375
   `(progn
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
376
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
377
      (register-class ',name ',(car superclasses)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
378
                      ,status-min ,status-max ,data-min ,data-max)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
379
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
380
      (defclass ,name ,superclasses
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
381
        ((status-min :initform ,status-min :allocation :class)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
382
         (status-max :initform ,status-max :allocation :class)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
383
         (data-min :initform ,data-min :allocation :class)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
384
         (data-max :initform ,data-max :allocation :class)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
385
         ,@slots)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
386
        ,@(when (and (numberp status-min) (numberp status-max))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
387
            (cond ((= status-min status-max)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
388
                   `((:default-initargs :status ,status-min)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
389
                  ((= 15 (- status-max status-min))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
390
                   `((:default-initargs :status (if (and (integerp *midi-channel*)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
391
                                                         (<= 0 *midi-channel* 15))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
392
                                                    (logior ,(logand status-min status-max)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
393
                                                            *midi-channel*)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
394
                                                    (error "*midi-channel*=~A not supported"
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
395
                                                           *midi-channel*))))))))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
396
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
397
      (defmethod fill-message :after ((message ,name))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
398
        (with-slots ,(mapcar #'car slots) message
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
399
 	 (symbol-macrolet ((next-byte (read-next-byte)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
400
 	   ,filler)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
401
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
402
      (defmethod length-message + ((message ,name))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
403
        (with-slots (status-min status-max data-min data-max ,@(mapcar #'car slots))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
404
 	   message
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
405
 	 ,length))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
406
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
407
      (defmethod write-message :after ((message ,name))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
408
        (with-slots (status-min status-max data-min data-max ,@(mapcar #'car slots))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
409
 	   message
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
410
 	 ,writer))))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
411
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
412
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
413
 ;;;
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
414
 ;;; midi messages
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
415
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
416
 (define-midi-message message ()
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
417
   :slots ((time :initarg :time :accessor message-time)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
418
 	  (status :initarg :status :reader message-status :initform 0))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
419
   :length 1
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
420
   :filler (setf status *status*)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
421
   :writer (write-bytes status))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
422
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
423
 (defgeneric print-midi-message (object stream)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
424
   (:method ((object message) stream)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
425
     (when (slot-boundp object 'time)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
426
       (format stream " T=~A" (slot-value object 'time)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
427
     (when (slot-boundp object 'status)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
428
       (format stream " S=~X" (slot-value object 'status))))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
429
   (:documentation
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
430
    "One PRINT-OBJECT method is defined for the MIDI message class
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
431
 \(common ancestor\): that method prints the wrapping, then calls
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
432
 the PRINT-MIDI-MESSAGE method to print the slots."))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
433
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
434
 (defmethod print-object ((obj message) stream)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
435
   (print-unreadable-object (obj stream :type t :identity t)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
436
     (print-midi-message obj stream))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
437
   obj)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
438
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
439
 (define-midi-message channel-message (message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
440
   :slots ((channel :reader message-channel))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
441
   :filler (setf channel (logand *status* #x0f)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
442
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
443
 (defmethod print-midi-message ((object channel-message) stream)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
444
   (call-next-method)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
445
   (when (slot-boundp object 'channel)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
446
     (format stream " C=~X" (slot-value object 'channel))))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
447
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
448
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
449
 ;;;
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
450
 ;;; voice messages
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
451
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
452
 (define-midi-message voice-message (channel-message))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
453
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
454
 (define-midi-message note-off-message (voice-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
455
   :status-min #x80 :status-max #x8f
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
456
   :slots ((key :initarg :key :reader message-key)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
457
 	  (velocity :initarg :velocity :reader message-velocity))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
458
   :filler (setf key next-byte
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
459
 		velocity next-byte)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
460
   :length 2
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
461
   :writer (write-bytes key velocity))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
462
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
463
 (defmethod print-midi-message ((object note-off-message) stream)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
464
   (call-next-method)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
465
   (when (slot-boundp object 'key)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
466
     (format stream " k=~A" (slot-value object 'key)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
467
   (when (slot-boundp object 'velocity)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
468
     (format stream " v=~A" (slot-value object 'velocity))))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
469
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
470
 (define-midi-message note-on-message (voice-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
471
   :status-min #x90 :status-max #x9f
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
472
   :slots ((key :initarg :key :reader message-key)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
473
 	  (velocity :initarg :velocity :reader message-velocity))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
474
   :filler (setf key next-byte
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
475
 		velocity next-byte)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
476
   :length 2
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
477
   :writer (write-bytes key velocity))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
478
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
479
 (defmethod print-midi-message ((object note-on-message) stream)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
480
   (call-next-method)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
481
   (when (slot-boundp object 'key)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
482
     (format stream " K=~A" (slot-value object 'key)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
483
   (when (slot-boundp object 'velocity)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
484
     (format stream " V=~A" (slot-value object 'velocity))))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
485
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
486
 (define-midi-message polyphonic-key-pressure-message (voice-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
487
   :status-min #xa0 :status-max #xaf
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
488
   :slots ((key)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
489
 	  (pressure))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
490
   :filler (setf key next-byte
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
491
 		pressure next-byte)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
492
   :length 2
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
493
   :writer (write-bytes key pressure))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
494
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
495
 (define-midi-message control-change-message (voice-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
496
   :status-min #xb0 :status-max #xbf
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
497
   :data-min #x00 :data-max #x78
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
498
   :slots ((controller :initarg :controller)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
499
 	  (value :initarg value))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
500
   :filler (setf controller next-byte
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
501
 		value next-byte)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
502
   :length 2
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
503
   :writer (write-bytes controller value))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
504
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
505
 (define-midi-message program-change-message (voice-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
506
   :status-min #xc0 :status-max #xcf
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
507
   :slots ((program :initarg :program :reader message-program))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
508
   :filler (setf program next-byte)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
509
   :length 1
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
510
   :writer (write-bytes program))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
511
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
512
 (defmethod print-midi-message ((object program-change-message) stream)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
513
   (call-next-method)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
514
   (when (slot-boundp object 'program)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
515
     (format stream " P=~A" (slot-value object 'program))))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
516
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
517
 (define-midi-message channel-pressure-message (voice-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
518
   :status-min #xd0 :status-max #xdf
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
519
   :slots ((pressure))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
520
   :filler (setf pressure next-byte)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
521
   :length 1
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
522
   :writer (write-bytes pressure))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
523
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
524
 (define-midi-message pitch-bend-message (voice-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
525
   :status-min #xe0 :status-max #xef
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
526
   :slots ((value :initarg :value :reader message-value))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
527
   :filler (setf value (logior next-byte (ash next-byte 7)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
528
   :length 2
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
529
   :writer (write-bytes (logand value #x7f) (logand (ash value -7) #x7f)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
530
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
531
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
532
 ;;;
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
533
 ;;; mode messages
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
534
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
535
 (define-midi-message mode-message (channel-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
536
   :filler next-byte) ; consume data byte
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
537
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
538
 (define-midi-message reset-all-controllers-message (mode-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
539
   :status-min #xb0 :status-max #xbf
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
540
   :data-min #x79 :data-max #x79
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
541
   :filler next-byte ; consume unused byte
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
542
   :length 2
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
543
   :writer (write-bytes #x79 0))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
544
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
545
 (define-midi-message local-control-message (mode-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
546
   :status-min #xb0 :status-max #xbf
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
547
   :data-min #x7a :data-max #x7a
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
548
   :slots ((mode))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
549
   :filler (setf mode (if (= next-byte 0) :off :on))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
550
   :length 2
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
551
   :writer (write-bytes #x7a (if (eq mode :off) 0 127)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
552
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
553
 (define-midi-message all-notes-off-message (mode-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
554
   :status-min #xb0 :status-max #xbf
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
555
   :data-min #x7b :data-max #x7b
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
556
   :filler next-byte ; consume unused byte
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
557
   :length 2
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
558
   :writer (write-bytes #x7b 0))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
559
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
560
 (define-midi-message omni-mode-off-message (mode-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
561
   :status-min #xb0 :status-max #xbf
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
562
   :data-min #x7c :data-max #x7c
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
563
   :filler next-byte ; consume unused byte
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
564
   :length 2
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
565
   :writer (write-bytes #x7c 0))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
566
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
567
 (define-midi-message omni-mode-on-message (mode-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
568
   :status-min #xb0 :status-max #xbf
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
569
   :data-min #x7d :data-max #x7d
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
570
   :filler next-byte ; consume unused byte
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
571
   :length 2
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
572
   :writer (write-bytes #x7d 0))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
573
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
574
 (define-midi-message mono-mode-on-message (mode-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
575
   :status-min #xb0 :status-max #xbf
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
576
   :data-min #x7e :data-max #x7e
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
577
   :slots ((nb-channels))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
578
   :filler (setf nb-channels next-byte)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
579
   :length 2
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
580
   :writer (write-bytes #x7e nb-channels))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
581
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
582
 (define-midi-message poly-mode-on-message (mode-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
583
   :status-min #xb0 :status-max #xbf
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
584
   :data-min #x7f :data-max #x7f
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
585
   :filler next-byte ; consume unused byte
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
586
   :length 2
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
587
   :writer (write-bytes #x7f 0))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
588
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
589
 (define-midi-message system-message (message))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
590
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
591
 (define-midi-message tempo-map-message (message))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
592
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
593
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
594
 ;;;
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
595
 ;;; system common messages
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
596
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
597
 (define-midi-message common-message (system-message))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
598
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
599
 (define-midi-message timing-code-message (common-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
600
   :status-min #xf1 :status-max #xf1
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
601
   :slots ((code))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
602
   :filler (setf code next-byte)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
603
   :length 1
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
604
   :writer (write-bytes code))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
605
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
606
 (defmethod print-midi-message ((object timing-code-message) stream)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
607
   (call-next-method)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
608
   (when (slot-boundp object 'code)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
609
     (format stream " code=~A" (slot-value object 'code))))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
610
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
611
 (define-midi-message song-position-pointer-message (common-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
612
   :status-min #xf2 :status-max #xf2
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
613
   :slots ((pointer))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
614
   :filler (setf pointer (logior next-byte (ash next-byte 7)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
615
   :length 2
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
616
   :writer (write-bytes (logand pointer #x7f) (logand (ash pointer -7) #x7f)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
617
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
618
 (define-midi-message song-select-message (common-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
619
   :status-min #xf3 :status-max #xf3
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
620
   :slots ((song))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
621
   :filler (setf song next-byte)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
622
   :length 1
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
623
   :writer (write-bytes song))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
624
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
625
 (define-midi-message tune-request-message (common-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
626
   :status-min #xf6 :status-max #xf6)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
627
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
628
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
629
 ;;;
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
630
 ;;; system real-time messages
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
631
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
632
 (define-midi-message real-time-message (system-message))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
633
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
634
 (define-midi-message timing-clock-message (real-time-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
635
   :status-min #xf8 :status-max #xf8)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
636
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
637
 (define-midi-message start-sequence-message (real-time-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
638
   :status-min #xfa :status-max #xfa)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
639
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
640
 (define-midi-message continue-sequence-message (real-time-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
641
   :status-min #xfb :status-max #xfb)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
642
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
643
 (define-midi-message stop-sequence-message (real-time-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
644
   :status-min #xfc :status-max #xfc)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
645
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
646
 (define-midi-message active-sensing-message (real-time-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
647
   :status-min #xfe :status-max #xfe)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
648
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
649
 ;; (define-midi-message tune-request-message (real-time-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
650
 ;;  :status-min #xf6 :status-max #xf6)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
651
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
652
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
653
 ;;;
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
654
 ;;; system exclusive messages
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
655
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
656
 (define-midi-message system-exclusive-message (system-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
657
   :status-min #xf0 :status-max #xf0
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
658
   :slots ((data))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
659
   :filler (loop with len = (read-variable-length-quantity)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
660
 	          initially (setf data (make-array
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
661
 				        len :element-type '(unsigned-byte 8)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
662
 	        for i from 0 below len
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
663
 	        do (setf (aref data i) next-byte))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
664
   :length (+ (length-of-variables-length-quantity (length data))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
665
 	     (length data))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
666
   :writer (progn (write-variable-length-quantity (length data))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
667
 		 (loop for elem across data do (write-bytes elem))))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
668
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
669
 (define-midi-message authorization-system-exclusive-message (system-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
670
   :status-min #xf7 :status-max #xf7
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
671
   :slots ((data))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
672
   :filler (loop with len = (read-variable-length-quantity)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
673
 	          initially (setf data (make-array
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
674
 				        len :element-type '(unsigned-byte 8)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
675
 	        for i from 0 below len
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
676
 	        do (setf (aref data i) next-byte))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
677
   :length (+ (length-of-variables-length-quantity (length data))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
678
 	     (length data))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
679
   :writer (progn (write-variable-length-quantity (length data))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
680
 		 (loop for elem across data do (write-bytes elem))))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
681
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
682
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
683
 ;;;
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
684
 ;;; meta messages
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
685
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
686
 (define-midi-message meta-message (message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
687
   :status-min #xff :status-max #xff
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
688
   :length 2 ; the first data byte and the length byte
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
689
   :filler next-byte ; the first data byte which gives the type of meta message
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
690
   :writer (write-bytes data-min))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
691
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
692
 (define-midi-message sequence-number-message (meta-message tempo-map-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
693
   :data-min #x00 :data-max #x00
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
694
   :slots ((sequence))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
695
   :filler (let ((data2 next-byte))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
696
 	    (setf sequence (if (zerop data2)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
697
 			       0
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
698
 			       (logior (ash next-byte 8) next-byte))))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
699
   :length (if (zerop sequence) 0 2)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
700
   :writer (unless (zerop sequence)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
701
 	    (write-bytes (ash sequence -8) (logand sequence #xf))))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
702
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
703
 (define-midi-message text-message (meta-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
704
   :slots ((text))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
705
   :filler (setf text (loop with len = next-byte
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
706
 			   with str = (make-string len)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
707
 			   for i from 0 below len
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
708
 			   do (setf (aref str i)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
709
 				    (code-char next-byte))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
710
 			   finally (return str)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
711
   :length (length text)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
712
   :writer (progn (write-bytes (length text))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
713
 		 (loop for char across text do
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
714
 		   (write-bytes (char-code char)))))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
715
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
716
 (defmethod print-midi-message ((object text-message) stream)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
717
   (call-next-method)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
718
   (when (slot-boundp object 'text)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
719
     (format stream " [~A]" (slot-value object 'text))))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
720
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
721
 (define-midi-message general-text-message (text-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
722
   :data-min #x01 :data-max #x01)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
723
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
724
 (define-midi-message copyright-message (text-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
725
   :data-min #x02 :data-max #x02)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
726
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
727
 (define-midi-message sequence/track-name-message (text-message tempo-map-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
728
   :data-min #x03 :data-max #x03)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
729
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
730
 (define-midi-message instrument-message (text-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
731
   :data-min #x04 :data-max #x04)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
732
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
733
 (define-midi-message lyric-message (text-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
734
   :data-min #x05 :data-max #x05)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
735
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
736
 (define-midi-message marker-message (text-message tempo-map-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
737
   :data-min #x06 :data-max #x06)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
738
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
739
 (define-midi-message cue-point-message (text-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
740
   :data-min #x07 :data-max #x07)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
741
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
742
 (define-midi-message program-name-message (text-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
743
   :data-min #x08 :data-max #x08)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
744
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
745
 (define-midi-message device-name-message (text-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
746
   :data-min #x09 :data-max #x09)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
747
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
748
 (define-midi-message channel-prefix-message (meta-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
749
   :data-min #x20 :data-max #x20
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
750
   :slots ((channel))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
751
   :length 1
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
752
   :filler (progn next-byte (setf channel next-byte))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
753
   :writer (write-bytes 1 channel))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
754
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
755
 (define-midi-message midi-port-message (meta-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
756
   :data-min #x21 :data-max #x21
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
757
   :slots ((port))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
758
   :length 1
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
759
   :filler (progn next-byte (setf port next-byte))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
760
   :writer (write-bytes 1 port))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
761
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
762
 (define-midi-message end-of-track-message (meta-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
763
   :data-min #x2f :data-max #x2f
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
764
   :slots ((status :initform #xff))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
765
   :filler next-byte
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
766
   :length 0
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
767
   :writer (write-bytes 0))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
768
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
769
 (define-midi-message tempo-message (meta-message tempo-map-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
770
   :data-min #x51 :data-max #x51
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
771
   :slots ((tempo :initarg :tempo :reader message-tempo))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
772
   :filler (progn next-byte (setf tempo (read-fixed-length-quantity 3)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
773
   :length 3
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
774
   :writer (progn (write-bytes 3) (write-fixed-length-quantity tempo 3)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
775
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
776
 (defmethod print-midi-message ((object tempo-message) stream)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
777
   (call-next-method)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
778
   (when (slot-boundp object 'tempo)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
779
     (format stream " tempo=~A" (slot-value object 'tempo))))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
780
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
781
 (define-midi-message smpte-offset-message (meta-message tempo-map-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
782
   :data-min #x54 :data-max #x54
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
783
   :slots ((hr) (mn) (se) (fr) (ff))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
784
   :filler (progn next-byte (setf hr next-byte mn next-byte se next-byte
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
785
 				 fr next-byte ff next-byte))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
786
   :length 5
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
787
   :writer (write-bytes 5 hr mn se fr ff))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
788
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
789
 (defmethod print-midi-message ((object smpte-offset-message) stream)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
790
   (call-next-method)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
791
   (when (or (slot-boundp object 'hr)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
792
             (slot-boundp object 'mn)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
793
             (slot-boundp object 'se)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
794
             (slot-boundp object 'fr)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
795
             (slot-boundp object 'ff))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
796
     (format stream
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
797
             " hmsff=~A/~A/~A/~A/~A"
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
798
             (ignore-errors (slot-value object 'hr))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
799
             (ignore-errors (slot-value object 'mn))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
800
             (ignore-errors (slot-value object 'se))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
801
             (ignore-errors (slot-value object 'fr))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
802
             (ignore-errors (slot-value object 'ff)))))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
803
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
804
 (define-midi-message time-signature-message (meta-message tempo-map-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
805
   :data-min #x58 :data-max #x58
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
806
   :slots ((nn :reader message-numerator)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
807
 	  (dd :reader message-denominator)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
808
 	  (cc) (bb))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
809
   :filler (progn next-byte (setf nn next-byte dd next-byte
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
810
 				 cc next-byte bb next-byte))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
811
   :length 4
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
812
   :writer (write-bytes 4 nn dd cc bb))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
813
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
814
 (defmethod print-midi-message ((object time-signature-message) stream)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
815
   (call-next-method)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
816
   (when (or (slot-boundp object 'nn)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
817
             (slot-boundp object 'dd)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
818
             (slot-boundp object 'cc)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
819
             (slot-boundp object 'bb))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
820
     (format stream
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
821
             " n/dcb=~A/~A/~A/~A"
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
822
             (ignore-errors (slot-value object 'nn))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
823
             (ignore-errors (slot-value object 'dd))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
824
             (ignore-errors (slot-value object 'cc))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
825
             (ignore-errors (slot-value object 'bb)))))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
826
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
827
 (define-midi-message key-signature-message (meta-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
828
   :data-min #x59 :data-max #x59
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
829
   :slots ((sf :reader message-sf)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
830
 	  (mi :reader message-mi))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
831
   :filler (progn next-byte (setf sf (let ((temp-sf next-byte))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
832
 				      (if (> temp-sf 127)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
833
 					  (- temp-sf 256)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
834
 					  temp-sf))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
835
 				 mi next-byte))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
836
   :length 2
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
837
   :writer (write-bytes 2 (if (< sf 0) (+ sf 256) sf) mi))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
838
 
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
839
 (define-midi-message proprietary-event (meta-message)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
840
   :data-min #x7f :data-max #x7f
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
841
   :slots ((data))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
842
   :filler (setf data (loop with len = (read-variable-length-quantity)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
843
 			   with vec = (make-array
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
844
 				       len
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
845
 				       :element-type '(unsigned-byte 8))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
846
 			   for i from 0 below len
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
847
 			   do (setf (aref vec i) next-byte)
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
848
 			   finally (return vec)))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
849
   :writer (map nil (lambda (byte) (write-bytes byte))
4e6838e03f61 add midi
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
850
 	       data)) ; FIXME