Superparticular samchillian: Difference between revisions
Jump to navigation
Jump to search
Wikispaces>xenjacob **Imported revision 343572870 - Original comment: ** |
(No difference)
|
Revision as of 12:40, 7 June 2012
IMPORTED REVISION FROM WIKISPACES
This is an imported revision from Wikispaces. The revision metadata is included below for reference:
- This revision was by author xenjacob and made on 2012-06-07 12:40:57 UTC.
- The original revision id was 343572870.
- The revision comment was:
The revision contents are below, presented both in the original Wikispaces Wikitext format, and in HTML exactly as Wikispaces rendered it.
Original Wikitext content:
<span class="s1">// ChucK code for Superparticular Samchillian</span> <span class="s1">// Samchillian idea by Leon Gruenbaum</span> <span class="s1">// superparticular-ratio implementation by Jacob Barton</span> // paste these into a new document in miniAudicle, or save text as a .ck to run in command-line <span class="s1">// change these to match your input/output device</span> <span class="s1">0 => int inDeviceNum;</span> <span class="s1">1 => int outDeviceNum;</span> <span class="s1">class</span> MicroRobinMidiIO { MidiIn min; MidiOut mouse; MidiMsg inmsg, outmsg; <span class="s2">0</span> => <span class="s1">int</span> ctr; //int rr[128][3]; don't think we need this now. // index = note number? // column 0 = channel sent to // column 1 = note number sent <span class="s1">int</span><span class="s3"> chans[</span><span class="s2">14</span><span class="s3">]; </span>// list of channels used <span class="s1">float</span><span class="s3"> holds[</span><span class="s2">16</span><span class="s3">]; </span>// pitches of on notes, zero if off. <span class="s3"> [</span><span class="s2">0</span><span class="s3">,</span><span class="s2">1</span><span class="s3">,</span><span class="s2">2</span><span class="s3">,</span><span class="s2">3</span><span class="s3">,</span><span class="s2">4</span><span class="s3">,</span><span class="s2">5</span><span class="s3">,</span><span class="s2">6</span><span class="s3">,</span><span class="s2">7</span><span class="s3">,</span><span class="s2">8</span><span class="s3">,</span><span class="s2">10</span><span class="s3">,</span><span class="s2">11</span><span class="s3">,</span><span class="s2">12</span><span class="s3">,</span><span class="s2">13</span><span class="s3">,</span><span class="s2">14</span><span class="s3">] @=> chans; </span>//exclude channel 10 (drums) & 16 (send channel) //microtuning stuff // PitchBend // input: pitch (midi note number float) & velocity of desired note // action: sends appropriate pitchbend message // (assuming pitchbend range = +/- 2 semitones) // output: note number required for correct frequency to be realized // sends pitchbend, assuming +/- wholestep pitchbend range // returns note number required for correct frequency <span class="s1">fun int</span> PitchBend(<span class="s1">float</span> pitch, <span class="s1">int</span> velocity) { //send pitchbend <span class="s2">224</span> + chans[ctr] => outmsg.data1; <span class="s2">0</span> => outmsg.data2; Math.round((pitch % <span class="s2">1</span>.<span class="s2">0</span>) * <span class="s2">32</span>.<span class="s2">0</span> + <span class="s2">64</span>.<span class="s2">0</span>) $ <span class="s1">int</span> => outmsg.data3; mouse.send(outmsg); <span class="s1">return</span> Math.floor(pitch) $ <span class="s1">int</span>; } // StartRelay // input: number of MIDI device, MidiTransform to be used // creates a loop ~ should be sporked <span class="s1">fun void</span> StartRelay(<span class="s1">int</span> deviceNum, MidiTransform mt) { <span class="s1">if</span>( !min.open(<span class="s2">inDeviceNum</span>)) <span class="s1">me</span>.exit(); <span class="s1">if</span>( !mouse.open(outDeviceNum)) <span class="s1">me</span>.exit(); // print out device that was opened <<< min.num(), <span class="s4">" -> "</span>, min.name() >>>; <<< mouse.num(), <span class="s4">" -> "</span>, mouse.name() >>>; <span class="s1">while</span> ( <span class="s1">true</span>) { min => <span class="s1">now</span>; <span class="s1">while</span>( min.recv(inmsg)) { <span class="s1">if</span>( inmsg.data1 % <span class="s2">16</span> == <span class="s2">0</span>) <span class="s5">// only receive on channel 1</span> { <<< <span class="s4">"r "</span>, inmsg.data1 / <span class="s2">16</span>, inmsg.data1 % <span class="s2">16</span>, inmsg.data2, inmsg.data3>>>; <span class="s1">if</span>( inmsg.data1 / <span class="s2">16</span> == <span class="s2">9</span>) { mt.NoteOn(inmsg.data2, inmsg.data3); } <span class="s1">if</span>( inmsg.data1 / <span class="s2">16</span> == <span class="s2">8</span>) { mt.NoteOff(inmsg.data2, inmsg.data3); } <span class="s1">if</span>( inmsg.data1 / <span class="s2">16</span> == <span class="s2">12</span>) { //prog change apply to channels 1-16 <span class="s5">//works!</span> inmsg.data1 - (inmsg.data1 % <span class="s2">16</span>) => <span class="s1">int</span> base; <span class="s1">for</span>(<span class="s2">0</span>=><span class="s1">int</span> i; i<<span class="s2">15</span>; i++) { base + chans[i] => outmsg.data1; inmsg.data2 => outmsg.data2; i++; <span class="s1">if</span>( i == <span class="s2">15</span>) { <span class="s2">0</span> => outmsg.data3; mouse.send(outmsg); <span class="s1">break</span>; } base + chans[i] => outmsg.data3; mouse.send(outmsg); inmsg.data2 => outmsg.data1; i++; <span class="s1">if</span>( i == <span class="s2">15</span>) { <span class="s2">0</span> => outmsg.data2 => outmsg.data3; mouse.send(outmsg); <span class="s1">break</span>; } base + chans[i] => outmsg.data2; inmsg.data2 => outmsg.data3; mouse.send(outmsg); } } <span class="s1">if</span>( inmsg.data1 / <span class="s2">16</span> == <span class="s2">11</span>) { //apply any controller data to channels 1-16 inmsg.data1 - (inmsg.data1 % <span class="s2">16</span>) => <span class="s1">int</span> base; inmsg.data2 => outmsg.data2; inmsg.data3 => outmsg.data3; <span class="s1">for</span>(<span class="s2">0</span>=><span class="s1">int</span> i; i<<span class="s2">16</span>; i++) { base + i => outmsg.data1; mouse.send(outmsg); } } } } } } // NoteOn // input: pitch in midi note-number extended, velocity // action: sends a MIDI pitchbend + note-on message to mouse on the current channel // keeping track of holds <span class="s1">fun void</span> NoteOn(<span class="s1">float</span> nn, <span class="s1">int</span> velocity) { IncrementCtr(); nn => holds[chans[ctr%<span class="s2">14</span>]]; PitchBend(nn, velocity) => outmsg.data2; // note on, right channel <span class="s2">144</span> + chans[ctr%<span class="s2">14</span>] => outmsg.data1; velocity => outmsg.data3; mouse.send(outmsg); //<<< "s ", outmsg.data1 / 16, outmsg.data1 % 16, outmsg.data2, outmsg.data3>>>; } // increments mod-14 counter, skipping over channels with // notes already on them, if possible. <span class="s1">fun void</span> IncrementCtr() { ctr; <span class="s2">0</span> => <span class="s1">int</span> i; <span class="s1">for</span>( i; i<<span class="s2">14</span>; i++) { <span class="s1">if</span> ( holds[chans[(ctr+i) % <span class="s2">14</span>]] == <span class="s2">0</span>.<span class="s2">0</span>) { (ctr + i) % <span class="s2">14</span> => ctr; <span class="s1">return</span>; } } (ctr + <span class="s2">1</span>) % <span class="s2">14</span> => ctr; } // NoteOff // input: pitch & note-off velocity // action: finds the pitch & offs it. <span class="s1">fun void</span> NoteOff(<span class="s1">float</span> nn, <span class="s1">int</span> velocity) { <span class="s2">0</span> => <span class="s1">int</span> c; <span class="s1">for</span>(c; c<<span class="s2">16</span>; c++) { <span class="s1">if</span>(holds[c] == nn) <span class="s5">// we found the pitch!</span> { <span class="s2">128</span> + c => outmsg.data1; Math.floor(nn) $ <span class="s1">int</span> => outmsg.data2; velocity => outmsg.data3; mouse.send(outmsg); //<<< "s ", outmsg.data1 / 16, outmsg.data1 % 16, outmsg.data2, outmsg.data3>>>; <span class="s2">0</span>.<span class="s2">0</span> => holds[c]; <span class="s1">return</span>; } } <<<<span class="s4">"MISS"</span>, nn>>>; // we couldn't find the pitch! // don't do anything. } <span class="s1">fun void</span> ControlChange(<span class="s1">int</span> channel, <span class="s1">int</span> prognum, <span class="s1">int</span> val) { <span class="s2">128</span> + channel => outmsg.data1; prognum => outmsg.data2; val => outmsg.data3; } } <span class="s1">class</span> MidiTransform { // superclass for MIDI transformers to be used by MicroRobinMidiIO MicroRobinMidiIO myIO; <span class="s1">fun void</span> LinkToIO(MicroRobinMidiIO io) { io @=> myIO; } <span class="s1">fun void</span> NoteOn( <span class="s1">int</span> nn, <span class="s1">int</span> vel) { <span class="s1">return</span>; } <span class="s1">fun void</span> NoteOff( <span class="s1">int</span> nn, <span class="s1">int</span> vel) { <span class="s1">return</span>; } } <span class="s1">class</span> SuperparticularSamchillian <span class="s1">extends</span> MidiTransform { <span class="s2">57</span>. => <span class="s1">float</span> resentFreq; <span class="s2">57</span>. => <span class="s1">float</span> prevFreq; <span class="s2">62</span> => <span class="s1">int</span> keyboardCenterNN; <span class="s1">float</span> prevFreqsByKey[<span class="s2">128</span>]; //set pans funky //for(0=>int f; f<16; f++) <span class="s5">//{</span> // myIO.ControlChange(f, 9, f*8); <span class="s5">//}</span> <span class="s1">fun void</span> NoteOn( <span class="s1">int</span> nn, <span class="s1">int</span> vel) { <span class="s1">if</span>(nn == keyboardCenterNN) { myIO.NoteOn( Std.ftom(prevFreq), vel); } <span class="s1">else</span> { <span class="s1">if</span>(nn < keyboardCenterNN) { // superparticular! <span class="s2">1</span>. + <span class="s2">1</span>./(keyboardCenterNN - nn) /=> prevFreq; myIO.NoteOn( Std.ftom(prevFreq), vel); } <span class="s1">else</span> { <span class="s1">if</span>(nn > keyboardCenterNN) { <span class="s2">1</span>. + <span class="s2">1</span>./(nn - keyboardCenterNN) *=> prevFreq; myIO.NoteOn( Std.ftom(prevFreq), vel); } } } Std.ftom(prevFreq) => prevFreqsByKey[nn]; } <span class="s1">fun void</span> NoteOff( <span class="s1">int</span> nn, <span class="s1">int</span> vel) { myIO.NoteOff( prevFreqsByKey[nn], vel); } } MicroRobinMidiIO mrmio; SuperparticularSamchillian easy; easy.LinkToIO(mrmio); <span class="s1">spork</span> ~ mrmio.StartRelay( <span class="s2">1</span>, easy); <span class="s2">1</span><span class="s3">::</span>second<span class="s3"> => </span>now<span class="s3">;</span> KBHit kb; while<span class="s3">(</span>true<span class="s3">)</span> { kb => <span class="s1">now</span>; <span class="s1">while</span>( kb.more() ) { kb.getchar() => <span class="s1">int</span> c; <<< <span class="s4">"ascii:"</span>, c>>>; easy.NoteOn(c, <span class="s2">88</span>); } }
Original HTML content:
<html><head><title>superparticular samchillian</title></head><body><span class="s1"><em> ChucK code for Superparticular Samchillian</span><br /> <span class="s1"></em> Samchillian idea by Leon Gruenbaum</span><br /> <span class="s1"><em> superparticular-ratio implementation by Jacob Barton</span><br /> <br /> </em> paste these into a new document in miniAudicle, or save text as a .ck to run in command-line<br /> <br /> <span class="s1"><em> change these to match your input/output device</span><br /> <span class="s1">0 => int inDeviceNum;</span><br /> <span class="s1">1 => int outDeviceNum;</span><br /> <br /> <span class="s1">class</span> MicroRobinMidiIO<br /> {<br /> MidiIn min;<br /> MidiOut mouse;<br /> MidiMsg inmsg, outmsg;<br /> <span class="s2">0</span> => <span class="s1">int</span> ctr;<br /> </em>int rr[128][3]; don't think we need this now.<br /> <em> index = note number?<br /> </em> column 0 = channel sent to<br /> <em> column 1 = note number sent<br /> <span class="s1">int</span><span class="s3"> chans[</span><span class="s2">14</span><span class="s3">]; </span></em> list of channels used<br /> <span class="s1">float</span><span class="s3"> holds[</span><span class="s2">16</span><span class="s3">]; </span><em> pitches of on notes, zero if off.<br /> <span class="s3"> [</span><span class="s2">0</span><span class="s3">,</span><span class="s2">1</span><span class="s3">,</span><span class="s2">2</span><span class="s3">,</span><span class="s2">3</span><span class="s3">,</span><span class="s2">4</span><span class="s3">,</span><span class="s2">5</span><span class="s3">,</span><span class="s2">6</span><span class="s3">,</span><span class="s2">7</span><span class="s3">,</span><span class="s2">8</span><span class="s3">,</span><span class="s2">10</span><span class="s3">,</span><span class="s2">11</span><span class="s3">,</span><span class="s2">12</span><span class="s3">,</span><span class="s2">13</span><span class="s3">,</span><span class="s2">14</span><span class="s3">] @=> chans; </span></em>exclude channel 10 (drums) & 16 (send channel)<br /> <em>microtuning stuff<br /> </em> PitchBend<br /> <em> input: pitch (midi note number float) & velocity of desired note<br /> </em> action: sends appropriate pitchbend message<br /> <em> (assuming pitchbend range = +/- 2 semitones)<br /> </em> output: note number required for correct frequency to be realized<br /> <em> sends pitchbend, assuming +/- wholestep pitchbend range<br /> </em> returns note number required for correct frequency<br /> <span class="s1">fun int</span> PitchBend(<span class="s1">float</span> pitch, <span class="s1">int</span> velocity)<br /> {<br /> <em>send pitchbend<br /> <span class="s2">224</span> + chans[ctr] => outmsg.data1;<br /> <span class="s2">0</span> => outmsg.data2;<br /> Math.round((pitch % <span class="s2">1</span>.<span class="s2">0</span>) * <span class="s2">32</span>.<span class="s2">0</span> + <span class="s2">64</span>.<span class="s2">0</span>) $ <span class="s1">int</span> => outmsg.data3;<br /> mouse.send(outmsg);<br /> <span class="s1">return</span> Math.floor(pitch) $ <span class="s1">int</span>;<br /> }<br /> </em> StartRelay<br /> <em> input: number of MIDI device, MidiTransform to be used<br /> </em> creates a loop ~ should be sporked<br /> <span class="s1">fun void</span> StartRelay(<span class="s1">int</span> deviceNum, MidiTransform mt)<br /> {<br /> <span class="s1">if</span>( !min.open(<span class="s2">inDeviceNum</span>)) <span class="s1">me</span>.exit();<br /> <span class="s1">if</span>( !mouse.open(outDeviceNum)) <span class="s1">me</span>.exit();<br /> <em> print out device that was opened<br /> <<< min.num(), <span class="s4">" -> "</span>, min.name() >>>;<br /> <<< mouse.num(), <span class="s4">" -> "</span>, mouse.name() >>>;<br /> <span class="s1">while</span> ( <span class="s1">true</span>)<br /> {<br /> min => <span class="s1">now</span>;<br /> <span class="s1">while</span>( min.recv(inmsg))<br /> { <br /> <span class="s1">if</span>( inmsg.data1 % <span class="s2">16</span> == <span class="s2">0</span>) <span class="s5"></em> only receive on channel 1</span><br /> {<br /> <<< <span class="s4">"r "</span>, inmsg.data1 / <span class="s2">16</span>, inmsg.data1 % <span class="s2">16</span>, inmsg.data2, inmsg.data3>>>;<br /> <span class="s1">if</span>( inmsg.data1 / <span class="s2">16</span> == <span class="s2">9</span>)<br /> { <br /> mt.NoteOn(inmsg.data2, inmsg.data3);<br /> }<br /> <span class="s1">if</span>( inmsg.data1 / <span class="s2">16</span> == <span class="s2">8</span>)<br /> {<br /> mt.NoteOff(inmsg.data2, inmsg.data3);<br /> }<br /> <span class="s1">if</span>( inmsg.data1 / <span class="s2">16</span> == <span class="s2">12</span>)<br /> {<br /> <em>prog change apply to channels 1-16<br /> <span class="s5"></em>works!</span><br /> inmsg.data1 - (inmsg.data1 % <span class="s2">16</span>) => <span class="s1">int</span> base;<br /> <span class="s1">for</span>(<span class="s2">0</span>=><span class="s1">int</span> i; i<<span class="s2">15</span>; i++)<br /> {<br /> base + chans[i] => outmsg.data1;<br /> inmsg.data2 => outmsg.data2;<br /> i++;<br /> <span class="s1">if</span>( i == <span class="s2">15</span>) <br /> { <br /> <span class="s2">0</span> => outmsg.data3;<br /> mouse.send(outmsg);<br /> <span class="s1">break</span>; <br /> }<br /> base + chans[i] => outmsg.data3;<br /> mouse.send(outmsg);<br /> inmsg.data2 => outmsg.data1;<br /> i++;<br /> <span class="s1">if</span>( i == <span class="s2">15</span>)<br /> {<br /> <span class="s2">0</span> => outmsg.data2 => outmsg.data3;<br /> mouse.send(outmsg);<br /> <span class="s1">break</span>;<br /> }<br /> base + chans[i] => outmsg.data2;<br /> inmsg.data2 => outmsg.data3;<br /> mouse.send(outmsg);<br /> }<br /> }<br /> <span class="s1">if</span>( inmsg.data1 / <span class="s2">16</span> == <span class="s2">11</span>)<br /> {<br /> <em>apply any controller data to channels 1-16<br /> inmsg.data1 - (inmsg.data1 % <span class="s2">16</span>) => <span class="s1">int</span> base;<br /> inmsg.data2 => outmsg.data2;<br /> inmsg.data3 => outmsg.data3;<br /> <span class="s1">for</span>(<span class="s2">0</span>=><span class="s1">int</span> i; i<<span class="s2">16</span>; i++)<br /> {<br /> base + i => outmsg.data1;<br /> mouse.send(outmsg);<br /> }<br /> }<br /> }<br /> }<br /> }<br /> }<br /> </em> NoteOn<br /> <em> input: pitch in midi note-number extended, velocity<br /> </em> action: sends a MIDI pitchbend + note-on message to mouse on the current channel<br /> <em> keeping track of holds<br /> <span class="s1">fun void</span> NoteOn(<span class="s1">float</span> nn, <span class="s1">int</span> velocity)<br /> {<br /> IncrementCtr();<br /> nn => holds[chans[ctr%<span class="s2">14</span>]];<br /> PitchBend(nn, velocity) => outmsg.data2;<br /> </em> note on, right channel<br /> <span class="s2">144</span> + chans[ctr%<span class="s2">14</span>] => outmsg.data1; <br /> velocity => outmsg.data3;<br /> mouse.send(outmsg);<br /> <em><<< "s ", outmsg.data1 / 16, outmsg.data1 % 16, outmsg.data2, outmsg.data3>>>;<br /> }<br /> </em> increments mod-14 counter, skipping over channels with<br /> <em> notes already on them, if possible.<br /> <span class="s1">fun void</span> IncrementCtr()<br /> {<br /> ctr;<br /> <span class="s2">0</span> => <span class="s1">int</span> i;<br /> <span class="s1">for</span>( i; i<<span class="s2">14</span>; i++)<br /> {<br /> <span class="s1">if</span> ( holds[chans[(ctr+i) % <span class="s2">14</span>]] == <span class="s2">0</span>.<span class="s2">0</span>)<br /> { (ctr + i) % <span class="s2">14</span> => ctr; <span class="s1">return</span>; }<br /> }<br /> (ctr + <span class="s2">1</span>) % <span class="s2">14</span> => ctr;<br /> }<br /> </em> NoteOff<br /> <em> input: pitch & note-off velocity<br /> </em> action: finds the pitch & offs it.<br /> <span class="s1">fun void</span> NoteOff(<span class="s1">float</span> nn, <span class="s1">int</span> velocity)<br /> {<br /> <span class="s2">0</span> => <span class="s1">int</span> c;<br /> <span class="s1">for</span>(c; c<<span class="s2">16</span>; c++)<br /> {<br /> <span class="s1">if</span>(holds[c] == nn) <span class="s5"><em> we found the pitch!</span><br /> {<br /> <span class="s2">128</span> + c => outmsg.data1;<br /> Math.floor(nn) $ <span class="s1">int</span> => outmsg.data2;<br /> velocity => outmsg.data3;<br /> mouse.send(outmsg);<br /> </em><<< "s ", outmsg.data1 / 16, outmsg.data1 % 16, outmsg.data2, outmsg.data3>>>;<br /> <span class="s2">0</span>.<span class="s2">0</span> => holds[c];<br /> <span class="s1">return</span>;<br /> }<br /> }<br /> <<<<span class="s4">"MISS"</span>, nn>>>;<br /> <em> we couldn't find the pitch!<br /> </em> don't do anything. <br /> }<br /> <span class="s1">fun void</span> ControlChange(<span class="s1">int</span> channel, <span class="s1">int</span> prognum, <span class="s1">int</span> val)<br /> {<br /> <span class="s2">128</span> + channel => outmsg.data1;<br /> prognum => outmsg.data2;<br /> val => outmsg.data3;<br /> }<br /> }<br /> <br /> <span class="s1">class</span> MidiTransform<br /> {<br /> <em> superclass for MIDI transformers to be used by MicroRobinMidiIO<br /> MicroRobinMidiIO myIO;<br /> <span class="s1">fun void</span> LinkToIO(MicroRobinMidiIO io)<br /> {<br /> io @=> myIO;<br /> }<br /> <span class="s1">fun void</span> NoteOn( <span class="s1">int</span> nn, <span class="s1">int</span> vel)<br /> {<br /> <span class="s1">return</span>;<br /> }<br /> <span class="s1">fun void</span> NoteOff( <span class="s1">int</span> nn, <span class="s1">int</span> vel)<br /> {<br /> <span class="s1">return</span>;<br /> }<br /> }<br /> <br /> <span class="s1">class</span> SuperparticularSamchillian <span class="s1">extends</span> MidiTransform<br /> {<br /> <span class="s2">57</span>. => <span class="s1">float</span> resentFreq;<br /> <span class="s2">57</span>. => <span class="s1">float</span> prevFreq; <br /> <span class="s2">62</span> => <span class="s1">int</span> keyboardCenterNN;<br /> <span class="s1">float</span> prevFreqsByKey[<span class="s2">128</span>];<br /> </em>set pans funky<br /> <em>for(0=>int f; f<16; f++)<br /> <span class="s5"></em>{</span><br /> <em> myIO.ControlChange(f, 9, f*8);<br /> <span class="s5"></em>}</span><br /> <span class="s1">fun void</span> NoteOn( <span class="s1">int</span> nn, <span class="s1">int</span> vel)<br /> {<br /> <span class="s1">if</span>(nn == keyboardCenterNN)<br /> {<br /> myIO.NoteOn( Std.ftom(prevFreq), vel);<br /> }<br /> <span class="s1">else</span><br /> {<br /> <span class="s1">if</span>(nn < keyboardCenterNN)<br /> {<br /> // superparticular!<br /> <span class="s2">1</span>. + <span class="s2">1</span>./(keyboardCenterNN - nn) /=> prevFreq;<br /> myIO.NoteOn( Std.ftom(prevFreq), vel);<br /> }<br /> <span class="s1">else</span><br /> { <br /> <span class="s1">if</span>(nn > keyboardCenterNN)<br /> {<br /> <span class="s2">1</span>. + <span class="s2">1</span>./(nn - keyboardCenterNN) *=> prevFreq;<br /> myIO.NoteOn( Std.ftom(prevFreq), vel);<br /> }<br /> }<br /> }<br /> Std.ftom(prevFreq) => prevFreqsByKey[nn];<br /> }<br /> <span class="s1">fun void</span> NoteOff( <span class="s1">int</span> nn, <span class="s1">int</span> vel)<br /> {<br /> myIO.NoteOff( prevFreqsByKey[nn], vel);<br /> }<br /> }<br /> <br /> MicroRobinMidiIO mrmio;<br /> SuperparticularSamchillian easy;<br /> easy.LinkToIO(mrmio);<br /> <span class="s1">spork</span> ~ mrmio.StartRelay( <span class="s2">1</span>, easy);<br /> <br /> <span class="s2">1</span><span class="s3">::</span>second<span class="s3"> => </span>now<span class="s3">;</span><br /> <br /> KBHit kb; <br /> <br /> while<span class="s3">(</span>true<span class="s3">)</span><br /> {<br /> kb => <span class="s1">now</span>;<br /> <span class="s1">while</span>( kb.more() )<br /> {<br /> kb.getchar() => <span class="s1">int</span> c;<br /> <<< <span class="s4">"ascii:"</span>, c>>>;<br /> easy.NoteOn(c, <span class="s2">88</span>);<br /> }<br /> }</body></html>