Superparticular samchillian: Difference between revisions
Jump to navigation
Jump to search
Wikispaces>xenjacob **Imported revision 343572870 - Original comment: ** |
Wikispaces>xenjacob **Imported revision 343680102 - Original comment: ** |
||
Line 1: | Line 1: | ||
<h2>IMPORTED REVISION FROM WIKISPACES</h2> | <h2>IMPORTED REVISION FROM WIKISPACES</h2> | ||
This is an imported revision from Wikispaces. The revision metadata is included below for reference:<br> | This is an imported revision from Wikispaces. The revision metadata is included below for reference:<br> | ||
: This revision was by author [[User:xenjacob|xenjacob]] and made on <tt>2012-06-07 | : This revision was by author [[User:xenjacob|xenjacob]] and made on <tt>2012-06-07 19:38:40 UTC</tt>.<br> | ||
: The original revision id was <tt> | : The original revision id was <tt>343680102</tt>.<br> | ||
: The revision comment was: <tt></tt><br> | : The revision comment was: <tt></tt><br> | ||
The revision contents are below, presented both in the original Wikispaces Wikitext format, and in HTML exactly as Wikispaces rendered it.<br> | The revision contents are below, presented both in the original Wikispaces Wikitext format, and in HTML exactly as Wikispaces rendered it.<br> | ||
<h4>Original Wikitext content:</h4> | <h4>Original Wikitext content:</h4> | ||
<div style="width:100%; max-height:400pt; overflow:auto; background-color:#f8f9fa; border: 1px solid #eaecf0; padding:0em"><pre style="margin:0px;border:none;background:none;word-wrap:break-word;white-space: pre-wrap ! important" class="old-revision-html"> | <div style="width:100%; max-height:400pt; overflow:auto; background-color:#f8f9fa; border: 1px solid #eaecf0; padding:0em"><pre style="margin:0px;border:none;background:none;word-wrap:break-word;white-space: pre-wrap ! important" class="old-revision-html">[[code format="java"]] | ||
// | //ChucK code for Superparticular Samchillian | ||
//Samchillian idea by Leon Gruenbaum | |||
//superparticular-ratio implementation by Jacob Barton | |||
//paste these lines into a new document in miniAudicle, or save text as a .ck to run in command-line | |||
//change these to match your input/output device | |||
0 => int inDeviceNum; | |||
1 => int outDeviceNum; | |||
class MicroRobinMidiIO | |||
{ | { | ||
MidiIn min; | |||
MidiOut mouse; | |||
MidiMsg inmsg, outmsg; | |||
0 => int 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 | |||
& | int chans[14]; // list of channels used | ||
float holds[16]; // pitches of on notes, zero if off. | |||
// | [0,1,2,3,4,5,6,7,8,10,11,12,13,14] @=> chans; //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 | |||
mouse. | // (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 | |||
fun int PitchBend(float pitch, int velocity) | |||
{ | |||
//send pitchbend | |||
224 + chans[ctr] => outmsg.data1; | |||
0 => outmsg.data2; | |||
// | Math.round((pitch % 1.0) * 32.0 + 64.0) $ int => outmsg.data3; | ||
mouse.send(outmsg); | |||
< | return Math.floor(pitch) $ int; | ||
{ | } | ||
// StartRelay | |||
// input: number of MIDI device, MidiTransform to be used | |||
// | // creates a loop ~ should be sporked | ||
fun void StartRelay(int deviceNum, MidiTransform mt) | |||
{ | |||
if( !min.open(inDeviceNum)) me.exit(); | |||
if( !mouse.open(outDeviceNum)) me.exit(); | |||
// print out device that was opened | |||
<<< min.num(), " -> ", min.name() >>>; | |||
{ | <<< mouse.num(), " -> ", mouse.name() >>>; | ||
& | while ( true) | ||
{ | |||
min => now; | |||
while( min.recv(inmsg)) | |||
{ | |||
if( inmsg.data1 % 16 == 0) // only receive on channel 1 | |||
} | { | ||
<<< "r ", inmsg.data1 / 16, inmsg.data1 % 16, inmsg.data2, inmsg.data3>>>; | |||
// | |||
// | if( inmsg.data1 / 16 == 9) | ||
{ | |||
{ | mt.NoteOn(inmsg.data2, inmsg.data3); | ||
} | |||
if( inmsg.data1 / 16 == 8) | |||
{ | { | ||
mt.NoteOff(inmsg.data2, inmsg.data3); | |||
{ | } | ||
if( inmsg.data1 / 16 == 12) | |||
Math.floor(nn) $ & | { | ||
velocity => outmsg.data3; | //prog change apply to channels 1-16 | ||
mouse.send(outmsg); | //works! | ||
//<<< "s ", outmsg.data1 / 16, outmsg.data1 % 16, outmsg.data2, outmsg.data3>>>; | inmsg.data1 - (inmsg.data1 % 16) => int base; | ||
for(0=>int i; i<15; i++) | |||
{ | |||
} | base + chans[i] => outmsg.data1; | ||
inmsg.data2 => outmsg.data2; | |||
i++; | |||
if( i == 15) | |||
{ | |||
0 => outmsg.data3; | |||
mouse.send(outmsg); | |||
break; | |||
} | |||
prognum => outmsg.data2; | |||
val => outmsg.data3; | base + chans[i] => outmsg.data3; | ||
} | mouse.send(outmsg); | ||
inmsg.data2 => outmsg.data1; | |||
i++; | |||
if( i == 15) | |||
{ | |||
0 => outmsg.data2 => outmsg.data3; | |||
mouse.send(outmsg); | |||
break; | |||
} | |||
base + chans[i] => outmsg.data2; | |||
inmsg.data2 => outmsg.data3; | |||
mouse.send(outmsg); | |||
} | |||
} | |||
if( inmsg.data1 / 16 == 11) | |||
{ | |||
//apply any controller data to channels 1-16 | |||
inmsg.data1 - (inmsg.data1 % 16) => int base; | |||
inmsg.data2 => outmsg.data2; | |||
inmsg.data3 => outmsg.data3; | |||
for(0=>int i; i<16; 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 | |||
fun void NoteOn(float nn, int velocity) | |||
{ | |||
IncrementCtr(); | |||
nn => holds[chans[ctr%14]]; | |||
PitchBend(nn, velocity) => outmsg.data2; | |||
// note on, right channel | |||
144 + chans[ctr%14] => 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. | |||
fun void IncrementCtr() | |||
{ | |||
ctr; | |||
0 => int i; | |||
for( i; i<14; i++) | |||
{ | |||
if ( holds[chans[(ctr+i) % 14]] == 0.0) | |||
{ (ctr + i) % 14 => ctr; return; } | |||
} | |||
(ctr + 1) % 14 => ctr; | |||
} | |||
// NoteOff | |||
// input: pitch & note-off velocity | |||
// action: finds the pitch & offs it. | |||
fun void NoteOff(float nn, int velocity) | |||
{ | |||
0 => int c; | |||
for(c; c<16; c++) | |||
{ | |||
if(holds[c] == nn) // we found the pitch! | |||
{ | |||
128 + c => outmsg.data1; | |||
Math.floor(nn) $ int => outmsg.data2; | |||
velocity => outmsg.data3; | |||
mouse.send(outmsg); | |||
//<<< "s ", outmsg.data1 / 16, outmsg.data1 % 16, outmsg.data2, outmsg.data3>>>; | |||
0.0 => holds[c]; | |||
return; | |||
} | |||
} | |||
<<<"MISS", nn>>>; | |||
// we couldn't find the pitch! | |||
// don't do anything. | |||
} | |||
fun void ControlChange(int channel, int prognum, int val) | |||
{ | |||
128 + channel => outmsg.data1; | |||
prognum => outmsg.data2; | |||
val => outmsg.data3; | |||
} | |||
} | } | ||
class MidiTransform | |||
{ | { | ||
// superclass for MIDI transformers to be used by MicroRobinMidiIO | // superclass for MIDI transformers to be used by MicroRobinMidiIO | ||
MicroRobinMidiIO myIO; | MicroRobinMidiIO myIO; | ||
fun void LinkToIO(MicroRobinMidiIO io) | |||
{ | { | ||
io @=> myIO; | io @=> myIO; | ||
} | } | ||
fun void NoteOn( int nn, int vel) | |||
{ | { | ||
return; | |||
} | } | ||
fun void NoteOff( int nn, int vel) | |||
{ | { | ||
return; | |||
} | } | ||
} | } | ||
class SuperparticularSamchillian extends MidiTransform | |||
{ | { | ||
& | 57. => float resentFreq; | ||
myIO.NoteOn( Std.ftom(prevFreq), vel); | 57. => float prevFreq; | ||
} | |||
} | 62 => int keyboardCenterNN; | ||
} | |||
Std.ftom(prevFreq) => prevFreqsByKey[nn]; | float prevFreqsByKey[128]; | ||
} | |||
//set pans funky | |||
{ | //for(0=>int f; f<16; f++) | ||
myIO.NoteOff( prevFreqsByKey[nn], vel); | //{ | ||
} | // myIO.ControlChange(f, 9, f*8); | ||
//} | |||
fun void NoteOn( int nn, int vel) | |||
{ | |||
if(nn == keyboardCenterNN) | |||
{ | |||
myIO.NoteOn( Std.ftom(prevFreq), vel); | |||
} | |||
else | |||
{ | |||
if(nn < keyboardCenterNN) | |||
{ | |||
// superparticular! | |||
1. + 1./(keyboardCenterNN - nn) /=> prevFreq; | |||
myIO.NoteOn( Std.ftom(prevFreq), vel); | |||
} | |||
else | |||
{ | |||
if(nn > keyboardCenterNN) | |||
{ | |||
1. + 1./(nn - keyboardCenterNN) *=> prevFreq; | |||
myIO.NoteOn( Std.ftom(prevFreq), vel); | |||
} | |||
} | |||
} | |||
Std.ftom(prevFreq) => prevFreqsByKey[nn]; | |||
} | |||
fun void NoteOff( int nn, int vel) | |||
{ | |||
myIO.NoteOff( prevFreqsByKey[nn], vel); | |||
} | |||
} | } | ||
Line 241: | Line 266: | ||
SuperparticularSamchillian easy; | SuperparticularSamchillian easy; | ||
easy.LinkToIO(mrmio); | easy.LinkToIO(mrmio); | ||
spork ~ mrmio.StartRelay( 1, easy); | |||
1::second => now; | |||
KBHit kb; | KBHit kb; | ||
while | while(true) | ||
{ | { | ||
kb = | kb => now; | ||
{ | while( kb.more() ) | ||
kb.getchar() = | { | ||
<<< | kb.getchar() => int c; | ||
easy.NoteOn(c, | <<< "ascii:", c>>>; | ||
easy.NoteOn(c, 88); | |||
} | |||
} | } | ||
[[code]]</pre></div> | |||
<h4>Original HTML content:</h4> | <h4>Original HTML content:</h4> | ||
<div style="width:100%; max-height:400pt; overflow:auto; background-color:#f8f9fa; border: 1px solid #eaecf0; padding:0em"><pre style="margin:0px;border:none;background:none;word-wrap:break-word;width:200%;white-space: pre-wrap ! important" class="old-revision-html"><html><head><title>superparticular samchillian</title></head><body><!-- ws:start:WikiTextCodeRule:0: | |||
&lt;pre class=&quot;java&quot;&gt;//ChucK code for Superparticular Samchillian&lt;br/&gt;//Samchillian idea by Leon Gruenbaum&lt;br/&gt;//superparticular-ratio implementation by Jacob Barton&lt;br/&gt;&lt;br/&gt;//paste these lines into a new document in miniAudicle, or save text as a .ck to run in command-line&lt;br/&gt;&lt;br/&gt;//change these to match your input/output device& | |||
Revision as of 19:38, 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 19:38:40 UTC.
- The original revision id was 343680102.
- 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:
[[code format="java"]] //ChucK code for Superparticular Samchillian //Samchillian idea by Leon Gruenbaum //superparticular-ratio implementation by Jacob Barton //paste these lines into a new document in miniAudicle, or save text as a .ck to run in command-line //change these to match your input/output device 0 => int inDeviceNum; 1 => int outDeviceNum; class MicroRobinMidiIO { MidiIn min; MidiOut mouse; MidiMsg inmsg, outmsg; 0 => int 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 int chans[14]; // list of channels used float holds[16]; // pitches of on notes, zero if off. [0,1,2,3,4,5,6,7,8,10,11,12,13,14] @=> chans; //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 fun int PitchBend(float pitch, int velocity) { //send pitchbend 224 + chans[ctr] => outmsg.data1; 0 => outmsg.data2; Math.round((pitch % 1.0) * 32.0 + 64.0) $ int => outmsg.data3; mouse.send(outmsg); return Math.floor(pitch) $ int; } // StartRelay // input: number of MIDI device, MidiTransform to be used // creates a loop ~ should be sporked fun void StartRelay(int deviceNum, MidiTransform mt) { if( !min.open(inDeviceNum)) me.exit(); if( !mouse.open(outDeviceNum)) me.exit(); // print out device that was opened <<< min.num(), " -> ", min.name() >>>; <<< mouse.num(), " -> ", mouse.name() >>>; while ( true) { min => now; while( min.recv(inmsg)) { if( inmsg.data1 % 16 == 0) // only receive on channel 1 { <<< "r ", inmsg.data1 / 16, inmsg.data1 % 16, inmsg.data2, inmsg.data3>>>; if( inmsg.data1 / 16 == 9) { mt.NoteOn(inmsg.data2, inmsg.data3); } if( inmsg.data1 / 16 == 8) { mt.NoteOff(inmsg.data2, inmsg.data3); } if( inmsg.data1 / 16 == 12) { //prog change apply to channels 1-16 //works! inmsg.data1 - (inmsg.data1 % 16) => int base; for(0=>int i; i<15; i++) { base + chans[i] => outmsg.data1; inmsg.data2 => outmsg.data2; i++; if( i == 15) { 0 => outmsg.data3; mouse.send(outmsg); break; } base + chans[i] => outmsg.data3; mouse.send(outmsg); inmsg.data2 => outmsg.data1; i++; if( i == 15) { 0 => outmsg.data2 => outmsg.data3; mouse.send(outmsg); break; } base + chans[i] => outmsg.data2; inmsg.data2 => outmsg.data3; mouse.send(outmsg); } } if( inmsg.data1 / 16 == 11) { //apply any controller data to channels 1-16 inmsg.data1 - (inmsg.data1 % 16) => int base; inmsg.data2 => outmsg.data2; inmsg.data3 => outmsg.data3; for(0=>int i; i<16; 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 fun void NoteOn(float nn, int velocity) { IncrementCtr(); nn => holds[chans[ctr%14]]; PitchBend(nn, velocity) => outmsg.data2; // note on, right channel 144 + chans[ctr%14] => 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. fun void IncrementCtr() { ctr; 0 => int i; for( i; i<14; i++) { if ( holds[chans[(ctr+i) % 14]] == 0.0) { (ctr + i) % 14 => ctr; return; } } (ctr + 1) % 14 => ctr; } // NoteOff // input: pitch & note-off velocity // action: finds the pitch & offs it. fun void NoteOff(float nn, int velocity) { 0 => int c; for(c; c<16; c++) { if(holds[c] == nn) // we found the pitch! { 128 + c => outmsg.data1; Math.floor(nn) $ int => outmsg.data2; velocity => outmsg.data3; mouse.send(outmsg); //<<< "s ", outmsg.data1 / 16, outmsg.data1 % 16, outmsg.data2, outmsg.data3>>>; 0.0 => holds[c]; return; } } <<<"MISS", nn>>>; // we couldn't find the pitch! // don't do anything. } fun void ControlChange(int channel, int prognum, int val) { 128 + channel => outmsg.data1; prognum => outmsg.data2; val => outmsg.data3; } } class MidiTransform { // superclass for MIDI transformers to be used by MicroRobinMidiIO MicroRobinMidiIO myIO; fun void LinkToIO(MicroRobinMidiIO io) { io @=> myIO; } fun void NoteOn( int nn, int vel) { return; } fun void NoteOff( int nn, int vel) { return; } } class SuperparticularSamchillian extends MidiTransform { 57. => float resentFreq; 57. => float prevFreq; 62 => int keyboardCenterNN; float prevFreqsByKey[128]; //set pans funky //for(0=>int f; f<16; f++) //{ // myIO.ControlChange(f, 9, f*8); //} fun void NoteOn( int nn, int vel) { if(nn == keyboardCenterNN) { myIO.NoteOn( Std.ftom(prevFreq), vel); } else { if(nn < keyboardCenterNN) { // superparticular! 1. + 1./(keyboardCenterNN - nn) /=> prevFreq; myIO.NoteOn( Std.ftom(prevFreq), vel); } else { if(nn > keyboardCenterNN) { 1. + 1./(nn - keyboardCenterNN) *=> prevFreq; myIO.NoteOn( Std.ftom(prevFreq), vel); } } } Std.ftom(prevFreq) => prevFreqsByKey[nn]; } fun void NoteOff( int nn, int vel) { myIO.NoteOff( prevFreqsByKey[nn], vel); } } MicroRobinMidiIO mrmio; SuperparticularSamchillian easy; easy.LinkToIO(mrmio); spork ~ mrmio.StartRelay( 1, easy); 1::second => now; KBHit kb; while(true) { kb => now; while( kb.more() ) { kb.getchar() => int c; <<< "ascii:", c>>>; easy.NoteOn(c, 88); } } [[code]]
Original HTML content:
<html><head><title>superparticular samchillian</title></head><body><!-- ws:start:WikiTextCodeRule:0: <pre class="java">//ChucK code for Superparticular Samchillian<br/>//Samchillian idea by Leon Gruenbaum<br/>//superparticular-ratio implementation by Jacob Barton<br/><br/>//paste these lines into a new document in miniAudicle, or save text as a .ck to run in command-line<br/><br/>//change these to match your input/output device<br/>0 =&gt; int inDeviceNum;<br/>1 =&gt; int outDeviceNum;<br/><br/>class MicroRobinMidiIO<br/>{<br/> MidiIn min;<br/> MidiOut mouse;<br/> MidiMsg inmsg, outmsg;<br/> 0 =&gt; int ctr;<br/> <br/> //int rr[128][3]; don't think we need this now.<br/> // index = note number?<br/> // column 0 = channel sent to<br/> // column 1 = note number sent<br/> int chans[14]; // list of channels used<br/> float holds[16]; // pitches of on notes, zero if off.<br/> [0,1,2,3,4,5,6,7,8,10,11,12,13,14] @=&gt; chans; //exclude channel 10 (drums) &amp; 16 (send channel)<br/> <br/> //microtuning stuff<br/> <br/> // PitchBend<br/> // input: pitch (midi note number float) &amp; velocity of desired note<br/> // action: sends appropriate pitchbend message<br/> // (assuming pitchbend range = +/- 2 semitones)<br/> // output: note number required for correct frequency to be realized<br/> // sends pitchbend, assuming +/- wholestep pitchbend range<br/> // returns note number required for correct frequency<br/> fun int PitchBend(float pitch, int velocity)<br/> {<br/> //send pitchbend<br/> 224 + chans[ctr] =&gt; outmsg.data1;<br/> 0 =&gt; outmsg.data2;<br/> Math.round((pitch % 1.0) * 32.0 + 64.0) $ int =&gt; outmsg.data3;<br/> mouse.send(outmsg);<br/> return Math.floor(pitch) $ int;<br/> }<br/> <br/> // StartRelay<br/> // input: number of MIDI device, MidiTransform to be used<br/> // creates a loop ~ should be sporked<br/> fun void StartRelay(int deviceNum, MidiTransform mt)<br/> {<br/> <br/> if( !min.open(inDeviceNum)) me.exit();<br/> if( !mouse.open(outDeviceNum)) me.exit();<br/> <br/> // print out device that was opened<br/> &lt;&lt;&lt; min.num(), &quot; -&gt; &quot;, min.name() &gt;&gt;&gt;;<br/> &lt;&lt;&lt; mouse.num(), &quot; -&gt; &quot;, mouse.name() &gt;&gt;&gt;;<br/> <br/> while ( true)<br/> {<br/> min =&gt; now;<br/> <br/> while( min.recv(inmsg))<br/> { <br/> if( inmsg.data1 % 16 == 0) // only receive on channel 1<br/> {<br/> &lt;&lt;&lt; &quot;r &quot;, inmsg.data1 / 16, inmsg.data1 % 16, inmsg.data2, inmsg.data3&gt;&gt;&gt;;<br/> <br/> if( inmsg.data1 / 16 == 9)<br/> { <br/> mt.NoteOn(inmsg.data2, inmsg.data3);<br/> }<br/> if( inmsg.data1 / 16 == 8)<br/> {<br/> mt.NoteOff(inmsg.data2, inmsg.data3);<br/> }<br/> if( inmsg.data1 / 16 == 12)<br/> {<br/> //prog change apply to channels 1-16<br/> //works!<br/> inmsg.data1 - (inmsg.data1 % 16) =&gt; int base;<br/> for(0=&gt;int i; i&lt;15; i++)<br/> {<br/> base + chans[i] =&gt; outmsg.data1;<br/> inmsg.data2 =&gt; outmsg.data2;<br/> i++;<br/> if( i == 15) <br/> { <br/> 0 =&gt; outmsg.data3;<br/> mouse.send(outmsg);<br/> break; <br/> }<br/> <br/> base + chans[i] =&gt; outmsg.data3;<br/> mouse.send(outmsg);<br/> inmsg.data2 =&gt; outmsg.data1;<br/> i++;<br/> if( i == 15)<br/> {<br/> 0 =&gt; outmsg.data2 =&gt; outmsg.data3;<br/> mouse.send(outmsg);<br/> break;<br/> }<br/> base + chans[i] =&gt; outmsg.data2;<br/> inmsg.data2 =&gt; outmsg.data3;<br/> mouse.send(outmsg);<br/> }<br/> }<br/> <br/> if( inmsg.data1 / 16 == 11)<br/> {<br/> //apply any controller data to channels 1-16<br/> inmsg.data1 - (inmsg.data1 % 16) =&gt; int base;<br/> inmsg.data2 =&gt; outmsg.data2;<br/> inmsg.data3 =&gt; outmsg.data3;<br/> for(0=&gt;int i; i&lt;16; i++)<br/> {<br/> base + i =&gt; outmsg.data1;<br/> mouse.send(outmsg);<br/> }<br/> }<br/> }<br/> }<br/> }<br/> }<br/> // NoteOn<br/> // input: pitch in midi note-number extended, velocity<br/> // action: sends a MIDI pitchbend + note-on message to mouse on the current channel<br/> // keeping track of holds<br/> fun void NoteOn(float nn, int velocity)<br/> {<br/> IncrementCtr();<br/> nn =&gt; holds[chans[ctr%14]];<br/> PitchBend(nn, velocity) =&gt; outmsg.data2;<br/> // note on, right channel<br/> 144 + chans[ctr%14] =&gt; outmsg.data1; <br/> <br/> velocity =&gt; outmsg.data3;<br/> mouse.send(outmsg);<br/> //&lt;&lt;&lt; &quot;s &quot;, outmsg.data1 / 16, outmsg.data1 % 16, outmsg.data2, outmsg.data3&gt;&gt;&gt;;<br/> }<br/> <br/> // increments mod-14 counter, skipping over channels with<br/> // notes already on them, if possible.<br/> fun void IncrementCtr()<br/> {<br/> ctr;<br/> 0 =&gt; int i;<br/> for( i; i&lt;14; i++)<br/> {<br/> if ( holds[chans[(ctr+i) % 14]] == 0.0)<br/> { (ctr + i) % 14 =&gt; ctr; return; }<br/> }<br/> (ctr + 1) % 14 =&gt; ctr;<br/> }<br/> <br/> // NoteOff<br/> // input: pitch &amp; note-off velocity<br/> // action: finds the pitch &amp; offs it.<br/> fun void NoteOff(float nn, int velocity)<br/> {<br/> 0 =&gt; int c;<br/> for(c; c&lt;16; c++)<br/> {<br/> if(holds[c] == nn) // we found the pitch!<br/> {<br/> 128 + c =&gt; outmsg.data1;<br/> Math.floor(nn) $ int =&gt; outmsg.data2;<br/> velocity =&gt; outmsg.data3;<br/> mouse.send(outmsg);<br/> //&lt;&lt;&lt; &quot;s &quot;, outmsg.data1 / 16, outmsg.data1 % 16, outmsg.data2, outmsg.data3&gt;&gt;&gt;;<br/> 0.0 =&gt; holds[c];<br/> return;<br/> }<br/> }<br/> &lt;&lt;&lt;&quot;MISS&quot;, nn&gt;&gt;&gt;;<br/> // we couldn't find the pitch!<br/> // don't do anything. <br/> }<br/> <br/> fun void ControlChange(int channel, int prognum, int val)<br/> {<br/> 128 + channel =&gt; outmsg.data1;<br/> prognum =&gt; outmsg.data2;<br/> val =&gt; outmsg.data3;<br/> }<br/> <br/>}<br/><br/>class MidiTransform<br/>{<br/> // superclass for MIDI transformers to be used by MicroRobinMidiIO<br/> MicroRobinMidiIO myIO;<br/> fun void LinkToIO(MicroRobinMidiIO io)<br/> {<br/> io @=&gt; myIO;<br/> }<br/> fun void NoteOn( int nn, int vel)<br/> {<br/> return;<br/> }<br/> fun void NoteOff( int nn, int vel)<br/> {<br/> return;<br/> }<br/>}<br/><br/>class SuperparticularSamchillian extends MidiTransform<br/>{<br/> 57. =&gt; float resentFreq;<br/> 57. =&gt; float prevFreq; <br/> <br/> 62 =&gt; int keyboardCenterNN;<br/> <br/> float prevFreqsByKey[128];<br/> <br/> //set pans funky<br/> //for(0=&gt;int f; f&lt;16; f++)<br/> //{<br/> // myIO.ControlChange(f, 9, f*8);<br/> //}<br/> <br/> fun void NoteOn( int nn, int vel)<br/> {<br/> if(nn == keyboardCenterNN)<br/> {<br/> myIO.NoteOn( Std.ftom(prevFreq), vel);<br/> }<br/> else <br/> {<br/> if(nn &lt; keyboardCenterNN)<br/> {<br/> // superparticular!<br/> 1. + 1./(keyboardCenterNN - nn) /=&gt; prevFreq;<br/> myIO.NoteOn( Std.ftom(prevFreq), vel);<br/> }<br/> else<br/> { <br/> if(nn &gt; keyboardCenterNN)<br/> {<br/> 1. + 1./(nn - keyboardCenterNN) *=&gt; prevFreq;<br/> myIO.NoteOn( Std.ftom(prevFreq), vel);<br/> }<br/> }<br/> }<br/> Std.ftom(prevFreq) =&gt; prevFreqsByKey[nn];<br/> }<br/> <br/> <br/> fun void NoteOff( int nn, int vel)<br/> {<br/> myIO.NoteOff( prevFreqsByKey[nn], vel);<br/> }<br/> <br/>}<br/><br/>MicroRobinMidiIO mrmio;<br/>SuperparticularSamchillian easy;<br/>easy.LinkToIO(mrmio);<br/>spork ~ mrmio.StartRelay( 1, easy);<br/><br/>1::second =&gt; now;<br/><br/>KBHit kb; <br/><br/>while(true)<br/>{<br/> kb =&gt; now;<br/> <br/> while( kb.more() )<br/> {<br/> kb.getchar() =&gt; int c;<br/> &lt;&lt;&lt; &quot;ascii:&quot;, c&gt;&gt;&gt;;<br/> easy.NoteOn(c, 88);<br/> }<br/>}<br/></pre> --> <style type="text/css"><!-- /** * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann * (http://qbnz.com/highlighter/ and http://geshi.org/) */ .java {font-family:monospace;} .java .imp {font-weight: bold; color: red;} .java .kw1 {color: #000000; font-weight: bold;} .java .kw2 {color: #000066; font-weight: bold;} .java .kw3 {color: #003399;} .java .kw4 {color: #000066; font-weight: bold;} .java .co1 {color: #666666; font-style: italic;} .java .co2 {color: #006699;} .java .co3 {color: #008000; font-style: italic; font-weight: bold;} .java .coMULTI {color: #666666; font-style: italic;} .java .es0 {color: #000099; font-weight: bold;} .java .br0 {color: #009900;} .java .sy0 {color: #339933;} .java .st0 {color: #0000ff;} .java .nu0 {color: #cc66cc;} .java .me1 {color: #006633;} .java .me2 {color: #006633;} .java span.xtra { display:block; } --> </style><pre class="java"> <span class="co1">//ChucK code for Superparticular Samchillian</span> <span class="co1">//Samchillian idea by Leon Gruenbaum</span> <span class="co1">//superparticular-ratio implementation by Jacob Barton</span> <span class="co1">//paste these lines into a new document in miniAudicle, or save text as a .ck to run in command-line</span> <span class="co1">//change these to match your input/output device</span> <span class="nu0">0</span> <span class="sy0">=></span> <span class="kw4">int</span> inDeviceNum<span class="sy0">;</span> <span class="nu0">1</span> <span class="sy0">=></span> <span class="kw4">int</span> outDeviceNum<span class="sy0">;</span> <span class="kw1">class</span> MicroRobinMidiIO <span class="br0">{</span> MidiIn min<span class="sy0">;</span> MidiOut mouse<span class="sy0">;</span> MidiMsg inmsg, outmsg<span class="sy0">;</span> <span class="nu0">0</span> <span class="sy0">=></span> <span class="kw4">int</span> ctr<span class="sy0">;</span> <span class="co1">//int rr[128][3]; don't think we need this now.</span> <span class="co1">// index = note number?</span> <span class="co1">// column 0 = channel sent to</span> <span class="co1">// column 1 = note number sent</span> <span class="kw4">int</span> chans<span class="br0">[</span><span class="nu0">14</span><span class="br0">]</span><span class="sy0">;</span> <span class="co1">// list of channels used</span> <span class="kw4">float</span> holds<span class="br0">[</span><span class="nu0">16</span><span class="br0">]</span><span class="sy0">;</span> <span class="co1">// pitches of on notes, zero if off.</span> <span class="br0">[</span><span class="nu0">0</span>,<span class="nu0">1</span>,<span class="nu0">2</span>,<span class="nu0">3</span>,<span class="nu0">4</span>,<span class="nu0">5</span>,<span class="nu0">6</span>,<span class="nu0">7</span>,<span class="nu0">8</span>,<span class="nu0">10</span>,<span class="nu0">11</span>,<span class="nu0">12</span>,<span class="nu0">13</span>,<span class="nu0">14</span><span class="br0">]</span> @<span class="sy0">=></span> chans<span class="sy0">;</span> <span class="co1">//exclude channel 10 (drums) & 16 (send channel)</span> <span class="co1">//microtuning stuff</span> <span class="co1">// PitchBend</span> <span class="co1">// input: pitch (midi note number float) & velocity of desired note</span> <span class="co1">// action: sends appropriate pitchbend message</span> <span class="co1">// (assuming pitchbend range = +/- 2 semitones)</span> <span class="co1">// output: note number required for correct frequency to be realized</span> <span class="co1">// sends pitchbend, assuming +/- wholestep pitchbend range</span> <span class="co1">// returns note number required for correct frequency</span> fun <span class="kw4">int</span> PitchBend<span class="br0">(</span><span class="kw4">float</span> pitch, <span class="kw4">int</span> velocity<span class="br0">)</span> <span class="br0">{</span> <span class="co1">//send pitchbend</span> <span class="nu0">224</span> <span class="sy0">+</span> chans<span class="br0">[</span>ctr<span class="br0">]</span> <span class="sy0">=></span> outmsg.<span class="me1">data1</span><span class="sy0">;</span> <span class="nu0">0</span> <span class="sy0">=></span> outmsg.<span class="me1">data2</span><span class="sy0">;</span> <span class="kw3">Math</span>.<span class="me1">round</span><span class="br0">(</span><span class="br0">(</span>pitch <span class="sy0">%</span> <span class="nu0">1.0</span><span class="br0">)</span> <span class="sy0">*</span> <span class="nu0">32.0</span> <span class="sy0">+</span> <span class="nu0">64.0</span><span class="br0">)</span> $ <span class="kw4">int</span> <span class="sy0">=></span> outmsg.<span class="me1">data3</span><span class="sy0">;</span> mouse.<span class="me1">send</span><span class="br0">(</span>outmsg<span class="br0">)</span><span class="sy0">;</span> <span class="kw1">return</span> <span class="kw3">Math</span>.<span class="me1">floor</span><span class="br0">(</span>pitch<span class="br0">)</span> $ <span class="kw4">int</span><span class="sy0">;</span> <span class="br0">}</span> <span class="co1">// StartRelay</span> <span class="co1">// input: number of MIDI device, MidiTransform to be used</span> <span class="co1">// creates a loop ~ should be sporked</span> fun <span class="kw4">void</span> StartRelay<span class="br0">(</span><span class="kw4">int</span> deviceNum, MidiTransform mt<span class="br0">)</span> <span class="br0">{</span> <span class="kw1">if</span><span class="br0">(</span> <span class="sy0">!</span>min.<span class="me1">open</span><span class="br0">(</span>inDeviceNum<span class="br0">)</span><span class="br0">)</span> me.<span class="me1">exit</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span> <span class="kw1">if</span><span class="br0">(</span> <span class="sy0">!</span>mouse.<span class="me1">open</span><span class="br0">(</span>outDeviceNum<span class="br0">)</span><span class="br0">)</span> me.<span class="me1">exit</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span> <span class="co1">// print out device that was opened</span> <span class="sy0"><<<</span> min.<span class="me1">num</span><span class="br0">(</span><span class="br0">)</span>, <span class="st0">" -> "</span>, min.<span class="me1">name</span><span class="br0">(</span><span class="br0">)</span> <span class="sy0">>>>;</span> <span class="sy0"><<<</span> mouse.<span class="me1">num</span><span class="br0">(</span><span class="br0">)</span>, <span class="st0">" -> "</span>, mouse.<span class="me1">name</span><span class="br0">(</span><span class="br0">)</span> <span class="sy0">>>>;</span> <span class="kw1">while</span> <span class="br0">(</span> <span class="kw2">true</span><span class="br0">)</span> <span class="br0">{</span> min <span class="sy0">=></span> now<span class="sy0">;</span> <span class="kw1">while</span><span class="br0">(</span> min.<span class="me1">recv</span><span class="br0">(</span>inmsg<span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span> <span class="kw1">if</span><span class="br0">(</span> inmsg.<span class="me1">data1</span> <span class="sy0">%</span> <span class="nu0">16</span> <span class="sy0">==</span> <span class="nu0">0</span><span class="br0">)</span> <span class="co1">// only receive on channel 1</span> <span class="br0">{</span> <span class="sy0"><<<</span> <span class="st0">"r "</span>, inmsg.<span class="me1">data1</span> <span class="sy0">/</span> <span class="nu0">16</span>, inmsg.<span class="me1">data1</span> <span class="sy0">%</span> <span class="nu0">16</span>, inmsg.<span class="me1">data2</span>, inmsg.<span class="me1">data3</span><span class="sy0">>>>;</span> <span class="kw1">if</span><span class="br0">(</span> inmsg.<span class="me1">data1</span> <span class="sy0">/</span> <span class="nu0">16</span> <span class="sy0">==</span> <span class="nu0">9</span><span class="br0">)</span> <span class="br0">{</span> mt.<span class="me1">NoteOn</span><span class="br0">(</span>inmsg.<span class="me1">data2</span>, inmsg.<span class="me1">data3</span><span class="br0">)</span><span class="sy0">;</span> <span class="br0">}</span> <span class="kw1">if</span><span class="br0">(</span> inmsg.<span class="me1">data1</span> <span class="sy0">/</span> <span class="nu0">16</span> <span class="sy0">==</span> <span class="nu0">8</span><span class="br0">)</span> <span class="br0">{</span> mt.<span class="me1">NoteOff</span><span class="br0">(</span>inmsg.<span class="me1">data2</span>, inmsg.<span class="me1">data3</span><span class="br0">)</span><span class="sy0">;</span> <span class="br0">}</span> <span class="kw1">if</span><span class="br0">(</span> inmsg.<span class="me1">data1</span> <span class="sy0">/</span> <span class="nu0">16</span> <span class="sy0">==</span> <span class="nu0">12</span><span class="br0">)</span> <span class="br0">{</span> <span class="co1">//prog change apply to channels 1-16</span> <span class="co1">//works!</span> inmsg.<span class="me1">data1</span> <span class="sy0">-</span> <span class="br0">(</span>inmsg.<span class="me1">data1</span> <span class="sy0">%</span> <span class="nu0">16</span><span class="br0">)</span> <span class="sy0">=></span> <span class="kw4">int</span> base<span class="sy0">;</span> <span class="kw1">for</span><span class="br0">(</span><span class="nu0">0</span><span class="sy0">=></span><span class="kw4">int</span> i<span class="sy0">;</span> i<span class="sy0"><</span><span class="nu0">15</span><span class="sy0">;</span> i<span class="sy0">++</span><span class="br0">)</span> <span class="br0">{</span> base <span class="sy0">+</span> chans<span class="br0">[</span>i<span class="br0">]</span> <span class="sy0">=></span> outmsg.<span class="me1">data1</span><span class="sy0">;</span> inmsg.<span class="me1">data2</span> <span class="sy0">=></span> outmsg.<span class="me1">data2</span><span class="sy0">;</span> i<span class="sy0">++;</span> <span class="kw1">if</span><span class="br0">(</span> i <span class="sy0">==</span> <span class="nu0">15</span><span class="br0">)</span> <span class="br0">{</span> <span class="nu0">0</span> <span class="sy0">=></span> outmsg.<span class="me1">data3</span><span class="sy0">;</span> mouse.<span class="me1">send</span><span class="br0">(</span>outmsg<span class="br0">)</span><span class="sy0">;</span> <span class="kw1">break</span><span class="sy0">;</span> <span class="br0">}</span> base <span class="sy0">+</span> chans<span class="br0">[</span>i<span class="br0">]</span> <span class="sy0">=></span> outmsg.<span class="me1">data3</span><span class="sy0">;</span> mouse.<span class="me1">send</span><span class="br0">(</span>outmsg<span class="br0">)</span><span class="sy0">;</span> inmsg.<span class="me1">data2</span> <span class="sy0">=></span> outmsg.<span class="me1">data1</span><span class="sy0">;</span> i<span class="sy0">++;</span> <span class="kw1">if</span><span class="br0">(</span> i <span class="sy0">==</span> <span class="nu0">15</span><span class="br0">)</span> <span class="br0">{</span> <span class="nu0">0</span> <span class="sy0">=></span> outmsg.<span class="me1">data2</span> <span class="sy0">=></span> outmsg.<span class="me1">data3</span><span class="sy0">;</span> mouse.<span class="me1">send</span><span class="br0">(</span>outmsg<span class="br0">)</span><span class="sy0">;</span> <span class="kw1">break</span><span class="sy0">;</span> <span class="br0">}</span> base <span class="sy0">+</span> chans<span class="br0">[</span>i<span class="br0">]</span> <span class="sy0">=></span> outmsg.<span class="me1">data2</span><span class="sy0">;</span> inmsg.<span class="me1">data2</span> <span class="sy0">=></span> outmsg.<span class="me1">data3</span><span class="sy0">;</span> mouse.<span class="me1">send</span><span class="br0">(</span>outmsg<span class="br0">)</span><span class="sy0">;</span> <span class="br0">}</span> <span class="br0">}</span> <span class="kw1">if</span><span class="br0">(</span> inmsg.<span class="me1">data1</span> <span class="sy0">/</span> <span class="nu0">16</span> <span class="sy0">==</span> <span class="nu0">11</span><span class="br0">)</span> <span class="br0">{</span> <span class="co1">//apply any controller data to channels 1-16</span> inmsg.<span class="me1">data1</span> <span class="sy0">-</span> <span class="br0">(</span>inmsg.<span class="me1">data1</span> <span class="sy0">%</span> <span class="nu0">16</span><span class="br0">)</span> <span class="sy0">=></span> <span class="kw4">int</span> base<span class="sy0">;</span> inmsg.<span class="me1">data2</span> <span class="sy0">=></span> outmsg.<span class="me1">data2</span><span class="sy0">;</span> inmsg.<span class="me1">data3</span> <span class="sy0">=></span> outmsg.<span class="me1">data3</span><span class="sy0">;</span> <span class="kw1">for</span><span class="br0">(</span><span class="nu0">0</span><span class="sy0">=></span><span class="kw4">int</span> i<span class="sy0">;</span> i<span class="sy0"><</span><span class="nu0">16</span><span class="sy0">;</span> i<span class="sy0">++</span><span class="br0">)</span> <span class="br0">{</span> base <span class="sy0">+</span> i <span class="sy0">=></span> outmsg.<span class="me1">data1</span><span class="sy0">;</span> mouse.<span class="me1">send</span><span class="br0">(</span>outmsg<span class="br0">)</span><span class="sy0">;</span> <span class="br0">}</span> <span class="br0">}</span> <span class="br0">}</span> <span class="br0">}</span> <span class="br0">}</span> <span class="br0">}</span> <span class="co1">// NoteOn</span> <span class="co1">// input: pitch in midi note-number extended, velocity</span> <span class="co1">// action: sends a MIDI pitchbend + note-on message to mouse on the current channel</span> <span class="co1">// keeping track of holds</span> fun <span class="kw4">void</span> NoteOn<span class="br0">(</span><span class="kw4">float</span> nn, <span class="kw4">int</span> velocity<span class="br0">)</span> <span class="br0">{</span> IncrementCtr<span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span> nn <span class="sy0">=></span> holds<span class="br0">[</span>chans<span class="br0">[</span>ctr<span class="sy0">%</span>14<span class="br0">]</span><span class="br0">]</span><span class="sy0">;</span> PitchBend<span class="br0">(</span>nn, velocity<span class="br0">)</span> <span class="sy0">=></span> outmsg.<span class="me1">data2</span><span class="sy0">;</span> <span class="co1">// note on, right channel</span> <span class="nu0">144</span> <span class="sy0">+</span> chans<span class="br0">[</span>ctr<span class="sy0">%</span>14<span class="br0">]</span> <span class="sy0">=></span> outmsg.<span class="me1">data1</span><span class="sy0">;</span> velocity <span class="sy0">=></span> outmsg.<span class="me1">data3</span><span class="sy0">;</span> mouse.<span class="me1">send</span><span class="br0">(</span>outmsg<span class="br0">)</span><span class="sy0">;</span> <span class="co1">//<<< "s ", outmsg.data1 / 16, outmsg.data1 % 16, outmsg.data2, outmsg.data3>>>;</span> <span class="br0">}</span> <span class="co1">// increments mod-14 counter, skipping over channels with</span> <span class="co1">// notes already on them, if possible.</span> fun <span class="kw4">void</span> IncrementCtr<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> ctr<span class="sy0">;</span> <span class="nu0">0</span> <span class="sy0">=></span> <span class="kw4">int</span> i<span class="sy0">;</span> <span class="kw1">for</span><span class="br0">(</span> i<span class="sy0">;</span> i<span class="sy0"><</span><span class="nu0">14</span><span class="sy0">;</span> i<span class="sy0">++</span><span class="br0">)</span> <span class="br0">{</span> <span class="kw1">if</span> <span class="br0">(</span> holds<span class="br0">[</span>chans<span class="br0">[</span><span class="br0">(</span>ctr<span class="sy0">+</span>i<span class="br0">)</span> <span class="sy0">%</span> <span class="nu0">14</span><span class="br0">]</span><span class="br0">]</span> <span class="sy0">==</span> <span class="nu0">0.0</span><span class="br0">)</span> <span class="br0">{</span> <span class="br0">(</span>ctr <span class="sy0">+</span> i<span class="br0">)</span> <span class="sy0">%</span> <span class="nu0">14</span> <span class="sy0">=></span> ctr<span class="sy0">;</span> <span class="kw1">return</span><span class="sy0">;</span> <span class="br0">}</span> <span class="br0">}</span> <span class="br0">(</span>ctr <span class="sy0">+</span> <span class="nu0">1</span><span class="br0">)</span> <span class="sy0">%</span> <span class="nu0">14</span> <span class="sy0">=></span> ctr<span class="sy0">;</span> <span class="br0">}</span> <span class="co1">// NoteOff</span> <span class="co1">// input: pitch & note-off velocity</span> <span class="co1">// action: finds the pitch & offs it.</span> fun <span class="kw4">void</span> NoteOff<span class="br0">(</span><span class="kw4">float</span> nn, <span class="kw4">int</span> velocity<span class="br0">)</span> <span class="br0">{</span> <span class="nu0">0</span> <span class="sy0">=></span> <span class="kw4">int</span> c<span class="sy0">;</span> <span class="kw1">for</span><span class="br0">(</span>c<span class="sy0">;</span> c<span class="sy0"><</span><span class="nu0">16</span><span class="sy0">;</span> c<span class="sy0">++</span><span class="br0">)</span> <span class="br0">{</span> <span class="kw1">if</span><span class="br0">(</span>holds<span class="br0">[</span>c<span class="br0">]</span> <span class="sy0">==</span> nn<span class="br0">)</span> <span class="co1">// we found the pitch!</span> <span class="br0">{</span> <span class="nu0">128</span> <span class="sy0">+</span> c <span class="sy0">=></span> outmsg.<span class="me1">data1</span><span class="sy0">;</span> <span class="kw3">Math</span>.<span class="me1">floor</span><span class="br0">(</span>nn<span class="br0">)</span> $ <span class="kw4">int</span> <span class="sy0">=></span> outmsg.<span class="me1">data2</span><span class="sy0">;</span> velocity <span class="sy0">=></span> outmsg.<span class="me1">data3</span><span class="sy0">;</span> mouse.<span class="me1">send</span><span class="br0">(</span>outmsg<span class="br0">)</span><span class="sy0">;</span> <span class="co1">//<<< "s ", outmsg.data1 / 16, outmsg.data1 % 16, outmsg.data2, outmsg.data3>>>;</span> <span class="nu0">0.0</span> <span class="sy0">=></span> holds<span class="br0">[</span>c<span class="br0">]</span><span class="sy0">;</span> <span class="kw1">return</span><span class="sy0">;</span> <span class="br0">}</span> <span class="br0">}</span> <span class="sy0"><<<</span><span class="st0">"MISS"</span>, nn<span class="sy0">>>>;</span> <span class="co1">// we couldn't find the pitch!</span> <span class="co1">// don't do anything. </span> <span class="br0">}</span> fun <span class="kw4">void</span> ControlChange<span class="br0">(</span><span class="kw4">int</span> channel, <span class="kw4">int</span> prognum, <span class="kw4">int</span> val<span class="br0">)</span> <span class="br0">{</span> <span class="nu0">128</span> <span class="sy0">+</span> channel <span class="sy0">=></span> outmsg.<span class="me1">data1</span><span class="sy0">;</span> prognum <span class="sy0">=></span> outmsg.<span class="me1">data2</span><span class="sy0">;</span> val <span class="sy0">=></span> outmsg.<span class="me1">data3</span><span class="sy0">;</span> <span class="br0">}</span> <span class="br0">}</span> <span class="kw1">class</span> MidiTransform <span class="br0">{</span> <span class="co1">// superclass for MIDI transformers to be used by MicroRobinMidiIO</span> MicroRobinMidiIO myIO<span class="sy0">;</span> fun <span class="kw4">void</span> LinkToIO<span class="br0">(</span>MicroRobinMidiIO io<span class="br0">)</span> <span class="br0">{</span> io @<span class="sy0">=></span> myIO<span class="sy0">;</span> <span class="br0">}</span> fun <span class="kw4">void</span> NoteOn<span class="br0">(</span> <span class="kw4">int</span> nn, <span class="kw4">int</span> vel<span class="br0">)</span> <span class="br0">{</span> <span class="kw1">return</span><span class="sy0">;</span> <span class="br0">}</span> fun <span class="kw4">void</span> NoteOff<span class="br0">(</span> <span class="kw4">int</span> nn, <span class="kw4">int</span> vel<span class="br0">)</span> <span class="br0">{</span> <span class="kw1">return</span><span class="sy0">;</span> <span class="br0">}</span> <span class="br0">}</span> <span class="kw1">class</span> SuperparticularSamchillian <span class="kw1">extends</span> MidiTransform <span class="br0">{</span> <span class="nu0">57</span>. <span class="sy0">=></span> <span class="kw4">float</span> resentFreq<span class="sy0">;</span> <span class="nu0">57</span>. <span class="sy0">=></span> <span class="kw4">float</span> prevFreq<span class="sy0">;</span> <span class="nu0">62</span> <span class="sy0">=></span> <span class="kw4">int</span> keyboardCenterNN<span class="sy0">;</span> <span class="kw4">float</span> prevFreqsByKey<span class="br0">[</span><span class="nu0">128</span><span class="br0">]</span><span class="sy0">;</span> <span class="co1">//set pans funky</span> <span class="co1">//for(0=>int f; f<16; f++)</span> <span class="co1">//{</span> <span class="co1">// myIO.ControlChange(f, 9, f*8);</span> <span class="co1">//}</span> fun <span class="kw4">void</span> NoteOn<span class="br0">(</span> <span class="kw4">int</span> nn, <span class="kw4">int</span> vel<span class="br0">)</span> <span class="br0">{</span> <span class="kw1">if</span><span class="br0">(</span>nn <span class="sy0">==</span> keyboardCenterNN<span class="br0">)</span> <span class="br0">{</span> myIO.<span class="me1">NoteOn</span><span class="br0">(</span> Std.<span class="me1">ftom</span><span class="br0">(</span>prevFreq<span class="br0">)</span>, vel<span class="br0">)</span><span class="sy0">;</span> <span class="br0">}</span> <span class="kw1">else</span> <span class="br0">{</span> <span class="kw1">if</span><span class="br0">(</span>nn <span class="sy0"><</span> keyboardCenterNN<span class="br0">)</span> <span class="br0">{</span> <span class="co1">// superparticular!</span> <span class="nu0">1</span>. <span class="sy0">+</span> <span class="nu0">1</span>.<span class="sy0">/</span><span class="br0">(</span>keyboardCenterNN <span class="sy0">-</span> nn<span class="br0">)</span> <span class="sy0">/=></span> prevFreq<span class="sy0">;</span> myIO.<span class="me1">NoteOn</span><span class="br0">(</span> Std.<span class="me1">ftom</span><span class="br0">(</span>prevFreq<span class="br0">)</span>, vel<span class="br0">)</span><span class="sy0">;</span> <span class="br0">}</span> <span class="kw1">else</span> <span class="br0">{</span> <span class="kw1">if</span><span class="br0">(</span>nn <span class="sy0">></span> keyboardCenterNN<span class="br0">)</span> <span class="br0">{</span> <span class="nu0">1</span>. <span class="sy0">+</span> <span class="nu0">1</span>.<span class="sy0">/</span><span class="br0">(</span>nn <span class="sy0">-</span> keyboardCenterNN<span class="br0">)</span> <span class="sy0">*=></span> prevFreq<span class="sy0">;</span> myIO.<span class="me1">NoteOn</span><span class="br0">(</span> Std.<span class="me1">ftom</span><span class="br0">(</span>prevFreq<span class="br0">)</span>, vel<span class="br0">)</span><span class="sy0">;</span> <span class="br0">}</span> <span class="br0">}</span> <span class="br0">}</span> Std.<span class="me1">ftom</span><span class="br0">(</span>prevFreq<span class="br0">)</span> <span class="sy0">=></span> prevFreqsByKey<span class="br0">[</span>nn<span class="br0">]</span><span class="sy0">;</span> <span class="br0">}</span> fun <span class="kw4">void</span> NoteOff<span class="br0">(</span> <span class="kw4">int</span> nn, <span class="kw4">int</span> vel<span class="br0">)</span> <span class="br0">{</span> myIO.<span class="me1">NoteOff</span><span class="br0">(</span> prevFreqsByKey<span class="br0">[</span>nn<span class="br0">]</span>, vel<span class="br0">)</span><span class="sy0">;</span> <span class="br0">}</span> <span class="br0">}</span> MicroRobinMidiIO mrmio<span class="sy0">;</span> SuperparticularSamchillian easy<span class="sy0">;</span> easy.<span class="me1">LinkToIO</span><span class="br0">(</span>mrmio<span class="br0">)</span><span class="sy0">;</span> spork ~ mrmio.<span class="me1">StartRelay</span><span class="br0">(</span> <span class="nu0">1</span>, easy<span class="br0">)</span><span class="sy0">;</span> <span class="nu0">1</span><span class="sy0">::</span>second <span class="sy0">=></span> now<span class="sy0">;</span> KBHit kb<span class="sy0">;</span> <span class="kw1">while</span><span class="br0">(</span><span class="kw2">true</span><span class="br0">)</span> <span class="br0">{</span> kb <span class="sy0">=></span> now<span class="sy0">;</span> <span class="kw1">while</span><span class="br0">(</span> kb.<span class="me1">more</span><span class="br0">(</span><span class="br0">)</span> <span class="br0">)</span> <span class="br0">{</span> kb.<span class="me1">getchar</span><span class="br0">(</span><span class="br0">)</span> <span class="sy0">=></span> <span class="kw4">int</span> c<span class="sy0">;</span> <span class="sy0"><<<</span> <span class="st0">"ascii:"</span>, c<span class="sy0">>>>;</span> easy.<span class="me1">NoteOn</span><span class="br0">(</span>c, <span class="nu0">88</span><span class="br0">)</span><span class="sy0">;</span> <span class="br0">}</span> <span class="br0">}</span> </pre> <!-- ws:end:WikiTextCodeRule:0 --></body></html>