supernova: fixes for boost-1.49 and gcc-4.7
[supercollider.git] / Help / Control / UsingMIDI.html
blob4d0baae88630ada1dceb80895ce3abbf66aba70a
1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2 <html>
3 <head>
4 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
5 <meta http-equiv="Content-Style-Type" content="text/css">
6 <title></title>
7 <meta name="Generator" content="Cocoa HTML Writer">
8 <meta name="CocoaVersion" content="824.48">
9 <style type="text/css">
10 p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 20.0px Helvetica}
11 p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px}
12 p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Helvetica}
13 p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica}
14 p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco}
15 p.p6 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #bf0000}
16 p.p7 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; min-height: 12.0px}
17 p.p8 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #000000}
18 p.p9 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #000000; min-height: 12.0px}
19 p.p10 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #bf0000}
20 p.p11 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #0000bf}
21 span.s1 {color: #0000bf}
22 span.s2 {color: #0000bf}
23 span.s3 {color: #000000}
24 span.s4 {color: #007300}
25 span.s5 {color: #bf0000}
26 span.s6 {color: #0000bf}
27 span.s7 {color: #007300}
28 span.Apple-tab-span {white-space:pre}
29 </style>
30 </head>
31 <body>
32 <p class="p1"><b>Notes on MIDI support in SuperCollider</b></p>
33 <p class="p2"><br></p>
34 <p class="p3"><b>Contents</b></p>
35 <p class="p2"><br></p>
36 <p class="p4">Introduction</p>
37 <p class="p4">Receiving MIDI input: MIDIResponder classes</p>
38 <p class="p4">Receiving MIDI input: MIDIIn</p>
39 <p class="p4">Playing notes on your MIDI keyboard<span class="Apple-converted-space"> </span></p>
40 <p class="p4">Sending MIDI out</p>
41 <p class="p4">MIDI synchronization</p>
42 <p class="p4">Third party libraries</p>
43 <p class="p2"><br></p>
44 <p class="p3"><b>Introduction</b></p>
45 <p class="p2"><br></p>
46 <p class="p4">SuperCollider's out of the box MIDI support is fairly thorough (although not as complete as you'll find in commercial sequencers). All MIDI devices accessible to your operating system (CoreMIDI on OSX, ALSA on Linux, PortMIDI on Windows) are accessible to SuperCollider.<span class="Apple-converted-space"> </span></p>
47 <p class="p2"><br></p>
48 <p class="p4"><b>Note:</b> This document is written from an OSX perspective. The essential behavior of the MIDI interface classes should be the same on other platforms, despite my continual reference to CoreMIDI here.</p>
49 <p class="p2"><br></p>
50 <p class="p4">SuperCollider does not impose much higher-level structure on MIDI functionality. The core classes are little more than hardware abstractions (see also the <a href="MIDI.html"><span class="s1">MIDI</span></a> helpfile):</p>
51 <p class="p2"><br></p>
52 <p class="p4"><b>MIDIClient:</b> represents SuperCollider's communications with CoreMIDI</p>
53 <p class="p4"><b>MIDIIn:</b> receives MIDI messages and executes functions in response to those messages</p>
54 <p class="p4"><b>MIDIOut:</b> sends MIDI messages out to a specific port and channel</p>
55 <p class="p4"><b>MIDIEndPoint:</b> a client-side representation of a CoreMIDI device, containing three variables (name, device and uid, which is a unique identifier assigned by the system)<span class="Apple-converted-space"> </span></p>
56 <p class="p2"><br></p>
57 <p class="p4">In most cases, each physical MIDI connection (pair of in/out jacks on the MIDI interface) has one MIDIEndPoint object to represent it in the client.<span class="Apple-converted-space"> </span></p>
58 <p class="p2"><br></p>
59 <p class="p3"><b>Receiving MIDI input: MIDIResponder classes</b></p>
60 <p class="p2"><br></p>
61 <p class="p4">For most uses, the preferred way to receive MIDI input is using the <b>MIDIResponder</b> classes. The advantage of this approach is that any number of responders can be registered. (By contrast, using MIDIIn responder functions directly means that only one function can exist per incoming message type. That is not an ideal programming practice.)</p>
62 <p class="p2"><br></p>
63 <p class="p4">Six types of MIDI responder exist, corresponding to the most common MIDI messages.They all have similar interfaces, described in the <a href="MIDIResponder.html"><span class="s1">MIDIResponder</span></a> help file. They can also filter incoming MIDI messages, to respond to a particular device, channel number, or specific parameter values.</p>
64 <p class="p2"><br></p>
65 <p class="p4">NoteOnResponder</p>
66 <p class="p4">NoteOffResponder</p>
67 <p class="p4">CCResponder</p>
68 <p class="p4">BendResponder</p>
69 <p class="p4">TouchResponder</p>
70 <p class="p4">ProgramChangeResponder</p>
71 <p class="p2"><br></p>
72 <p class="p4">See "Playing notes on your MIDI keyboard" below for a simple example using the note-on and note-off responders.</p>
73 <p class="p2"><br></p>
74 <p class="p3"><b>Receiving MIDI input: MIDIIn</b></p>
75 <p class="p2"><br></p>
76 <p class="p4">MIDIIn has a number of class variables holding functions to be evaluated when a MIDI event comes in. Technical details on each function can be found in the MIDIIn help file.</p>
77 <p class="p2"><br></p>
78 <p class="p4">noteOn</p>
79 <p class="p4">noteOff</p>
80 <p class="p4">control</p>
81 <p class="p4">bend</p>
82 <p class="p4">touch</p>
83 <p class="p4">polyTouch</p>
84 <p class="p4">program</p>
85 <p class="p4">sysex</p>
86 <p class="p4">sysrt</p>
87 <p class="p4">smpte<span class="Apple-converted-space"> </span></p>
88 <p class="p2"><br></p>
89 <p class="p4">To assign a response to a particular kind of MIDI message, assign a function to the class variable:<span class="Apple-converted-space"> </span></p>
90 <p class="p2"><br></p>
91 <p class="p5"><span class="s2">MIDIIn</span>.connect;</p>
92 <p class="p5"><span class="s2">MIDIIn</span>.noteOn = { <span class="s2">|port, chan, note, vel|</span> [port, chan, note, vel].postln };<span class="Apple-converted-space"> </span></p>
93 <p class="p6"><span class="s2">MIDIIn</span><span class="s3">.noteOn = </span><span class="s2">nil</span><span class="s3">;<span class="Apple-converted-space">  </span></span>// stop responding</p>
94 <p class="p2"><br></p>
95 <p class="p4">MIDIIn provides the responding functions with all the information coming in from CoreMIDI:</p>
96 <p class="p2"><br></p>
97 <p class="p4"><b>source (src):</b> corresponds to the uid of the MIDIEndPont from which the message is coming.</p>
98 <p class="p4"><b>channel (chan):</b> integer 0-15 representing the channel bits of the MIDI status byte</p>
99 <p class="p2"><br></p>
100 <p class="p4">... with subsequent arguments representing the data bytes. The MIDIIn help file details all the supported messages along with the arguments of the responding function for the message.<span class="Apple-converted-space"> </span></p>
101 <p class="p2"><br></p>
102 <p class="p4">Because these are class variables, you can have only one function assigned at one time. A common usage is to assign a function that looks up responses in a collection. For example, you could have a separate set of response functions for each channel.</p>
103 <p class="p2"><br></p>
104 <p class="p5">~noteOn = <span class="s2">Array</span>.fill(16, <span class="s2">IdentityDictionary</span>.new);</p>
105 <p class="p5"><span class="s2">MIDIIn</span>.noteOn = { <span class="s2">|port, chan, num, vel|</span> ~noteOn[chan].do(<span class="s2">_</span>.value(port, chan, num, vel)) };</p>
106 <p class="p7"><br></p>
107 <p class="p6"><span class="s3"><span class="Apple-converted-space">   </span></span>// this function will respond only on channel 0</p>
108 <p class="p5">~noteOn[0].put(<span class="s4">\postNoteOn</span>, { <span class="s2">|port, chan, num, vel|</span> [port, chan, note, vel].postln });</p>
109 <p class="p5">~noteOn[0].removeAt(<span class="s4">\postNoteOn</span>);<span class="Apple-converted-space">  </span><span class="s5">// stop responding</span></p>
110 <p class="p2"><br></p>
111 <p class="p4">The advantage of this approach over using "if" or "case" statements in the response function is that you can add and remove responses without having to change the MIDIIn function. The MIDIIn function can serve as a "hook" into another structure that distributes the MIDI events to the real responders.</p>
112 <p class="p2"><br></p>
113 <p class="p3"><b>Playing notes on your MIDI keyboard<span class="Apple-converted-space"> </span></b></p>
114 <p class="p2"><br></p>
115 <p class="p4">The technical problem is that every note on needs to save its synth object so that the note off message can end the right server-side node.<span class="Apple-converted-space"> </span></p>
116 <p class="p2"><br></p>
117 <p class="p5">s.boot;</p>
118 <p class="p7"><br></p>
119 <p class="p5">(</p>
120 <p class="p8"><span class="s6">var</span> notes, on, off;</p>
121 <p class="p9"><br></p>
122 <p class="p8"><span class="s6">//MIDIIn</span>.connect;</p>
123 <p class="p9"><br></p>
124 <p class="p10"><span class="s3">notes = </span><span class="s6">Array</span><span class="s3">.newClear(128);<span class="Apple-converted-space">  </span></span>// array has one slot per possible MIDI note</p>
125 <p class="p9"><br></p>
126 <p class="p11"><span class="s3">on = </span>NoteOnResponder<span class="s3">({ </span>|src, chan, num, veloc|</p>
127 <p class="p8"><span class="Apple-tab-span"> </span>notes[num] = <span class="s6">Synth</span>(<span class="s7">\default</span>, [<span class="s7">\freq</span>, num.midicps,</p>
128 <p class="p8"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s7">\amp</span>, veloc * 0.00315]);</p>
129 <p class="p8">});</p>
130 <p class="p9"><br></p>
131 <p class="p11"><span class="s3">off = </span>NoteOffResponder<span class="s3">({ </span>|src, chan, num, veloc|</p>
132 <p class="p8"><span class="Apple-tab-span"> </span>notes[num].release;</p>
133 <p class="p8">});</p>
134 <p class="p9"><br></p>
135 <p class="p8">q = { on.remove; off.remove; };</p>
136 <p class="p5">)</p>
137 <p class="p7"><br></p>
138 <p class="p6">// when done:</p>
139 <p class="p5">q.value;</p>
140 <p class="p2"><br></p>
141 <p class="p4">The MIDIIn help file contains a more elaborate example.</p>
142 <p class="p2"><br></p>
143 <p class="p4">SuperCollider does not have a built-in class to handle this automatically. However, <i>dewdrop_lib</i>, a third party libraries mentioned below, includes Voicer (to simplify note on-off bookkeeping) and VoicerMIDISocket (to trigger Voicer notes by MIDI). Users interested in this functionality may wish to examine that library.</p>
144 <p class="p2"><br></p>
145 <p class="p3"><b>Sending MIDI out</b></p>
146 <p class="p2"><br></p>
147 <p class="p4">See the <a href="MIDIOut.html"><span class="s1">MIDIOut</span></a> helpfile. Unlike MIDIIn, with MIDIOut you create an instance of the MIDIOut class with a port and uid. You can have multiple MIDIOut objects to send MIDI to different physical devices.</p>
148 <p class="p2"><br></p>
149 <p class="p4">Many users have reported timing issues with MIDIOut. When the CPU is busy, especially during graphics updates, outgoing MIDI messages may be delayed. Use with caution in a performance situation.</p>
150 <p class="p2"><br></p>
151 <p class="p3"><b>MIDI synchronization</b></p>
152 <p class="p2"><br></p>
153 <p class="p4">MIDI synchronization may be performed using MIDIIn's sysrt or smpte response functions. It's up to the user to implement the desired kind of synchronization.</p>
154 <p class="p2"><br></p>
155 <p class="p4">For sysrt, external MIDI clocks output 24 pulses per quarter note. The responder should count the incoming pulses and multiply the rhythmic value into 24 to determine how many pulses to wait:</p>
156 <p class="p2"><br></p>
157 <p class="p4">0.25<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>wait 6 pulses (16th note)</p>
158 <p class="p4">0.5<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>wait 12 pulses (8th note)</p>
159 <p class="p4">2<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>wait 48 pulses (half note)</p>
160 <p class="p2"><br></p>
161 <p class="p4">dewdrop_lib (third party library) includes a class, MIDISyncClock, that receives MIDI clock messages and allows events to be scheduled to keep time with an external MIDI device. See the <b>[MIDISyncClock]</b> helpfile for details.</p>
162 <p class="p2"><br></p>
163 <p class="p4">There are significant limitations, discussed in the helpfile. This is not really a fully supported class, but it's there for users who need rudimentary MIDI sync functionality.</p>
164 <p class="p2"><br></p>
165 <p class="p3"><b>Third party libraries</b></p>
166 <p class="p2"><br></p>
167 <p class="p4"><i>dewdrop_lib</i> is a third party library providing a number of useful performance features, available through the <a href="../Extending and Customizing SC/Quarks/Quarks.html"><span class="s1">Quarks</span></a> interface. The library provides a user-extensible framework of MIDI responder classes designed for multiport, multichannel applications.<span class="Apple-converted-space"> </span></p>
168 <p class="p2"><br></p>
169 <p class="p4">Among its features:</p>
170 <p class="p2"><br></p>
171 <p class="p4">- user-extensible: simple functions may be used, and frequently-needed responses can be written into classes that inherit from the framework (see <b>[BasicMIDISocket]</b> and <b>[BasicMIDIControl]</b>)</p>
172 <p class="p2"><br></p>
173 <p class="p4">- easy to use classes for playing MIDI notes and assigning MIDI controllers to synthesis parameters</p>
174 <p class="p2"><br></p>
175 <p class="p4">- a user-configurable array of MIDI controller numbers, to simplify assignment of events to hardware controllers</p>
176 </body>
177 </html>