|
PreImportHandFixes>Battaglia01 |
Line 1: |
Line 1: |
| <pre> <span style="">//ChucK code for Superparticular Samchillian</span><span style="">//Samchillian idea by Leon Gruenbaum</span><span style="">//superparticular-ratio implementation by Jacob Barton</span> <span style="">//paste these lines into a new document in miniAudicle, or save text as a .ck to run in command-line</span> <span style="">//change these to match your input/output device</span><span style="">0</span> <span style="">=></span> <span style="">int</span> inDeviceNum<span style="">;</span><span style="">1</span> <span style="">=></span> <span style="">int</span> outDeviceNum<span style="">;</span> <span style="">class</span> MicroRobinMidiIO<span style="">{</span> MidiIn min<span style="">;</span> MidiOut mouse<span style="">;</span> MidiMsg inmsg, outmsg<span style="">;</span> <span style="">0</span> <span style="">=></span> <span style="">int</span> ctr<span style="">;</span> | | <pre> |
| <span style="">//int rr[128][3]; don't think we need this now.</span> <span style="">// index = note number?</span> <span style="">// column 0 = channel sent to</span> <span style="">// column 1 = note number sent</span> <span style="">int</span> chans<span style="">[</span><span style="">14</span><span style="">]</span><span style="">;</span> <span style="">// list of channels used</span> <span style="">float</span> holds<span style="">[</span><span style="">16</span><span style="">]</span><span style="">;</span> <span style="">// pitches of on notes, zero if off.</span> <span style="">[</span><span style="">0</span>,<span style="">1</span>,<span style="">2</span>,<span style="">3</span>,<span style="">4</span>,<span style="">5</span>,<span style="">6</span>,<span style="">7</span>,<span style="">8</span>,<span style="">10</span>,<span style="">11</span>,<span style="">12</span>,<span style="">13</span>,<span style="">14</span><span style="">]</span> @<span style="">=></span> chans<span style="">;</span> <span style="">//exclude channel 10 (drums) & 16 (send channel)</span> | | //ChucK code for Superparticular Samchillian |
| <span style="">//microtuning stuff</span>
| | //Samchillian idea by Leon Gruenbaum |
| <span style="">// PitchBend</span> <span style="">// input: pitch (midi note number float) & velocity of desired note</span> <span style="">// action: sends appropriate pitchbend message</span> <span style="">// (assuming pitchbend range = +/- 2 semitones)</span> <span style="">// output: note number required for correct frequency to be realized</span> <span style="">// sends pitchbend, assuming +/- wholestep pitchbend range</span> <span style="">// returns note number required for correct frequency</span> fun <span style="">int</span> PitchBend<span style="">(</span><span style="">float</span> pitch, <span style="">int</span> velocity<span style="">)</span> <span style="">{</span> <span style="">//send pitchbend</span> <span style="">224</span> <span style="">+</span> chans<span style="">[</span>ctr<span style="">]</span> <span style="">=></span> outmsg.<span style="">data1</span><span style="">;</span> <span style="">0</span> <span style="">=></span> outmsg.<span style="">data2</span><span style="">;</span> <span style="">Math</span>.<span style="">round</span><span style="">(</span><span style="">(</span>pitch <span style="">%</span> <span style="">1.0</span><span style="">)</span> <span style="">*</span> <span style="">32.0</span> <span style="">+</span> <span style="">64.0</span><span style="">)</span> $ <span style="">int</span> <span style="">=></span> outmsg.<span style="">data3</span><span style="">;</span> mouse.<span style="">send</span><span style="">(</span>outmsg<span style="">)</span><span style="">;</span> <span style="">return</span> <span style="">Math</span>.<span style="">floor</span><span style="">(</span>pitch<span style="">)</span> $ <span style="">int</span><span style="">;</span> <span style="">}</span>
| | //superparticular-ratio implementation by Jacob Barton |
| <span style="">// StartRelay</span> <span style="">// input: number of MIDI device, MidiTransform to be used</span> <span style="">// creates a loop ~ should be sporked</span> fun <span style="">void</span> StartRelay<span style="">(</span><span style="">int</span> deviceNum, MidiTransform mt<span style="">)</span> <span style="">{</span>
| | |
| <span style="">if</span><span style="">(</span> <span style="">!</span>min.<span style="">open</span><span style="">(</span>inDeviceNum<span style="">)</span><span style="">)</span> me.<span style="">exit</span><span style="">(</span><span style="">)</span><span style="">;</span> <span style="">if</span><span style="">(</span> <span style="">!</span>mouse.<span style="">open</span><span style="">(</span>outDeviceNum<span style="">)</span><span style="">)</span> me.<span style="">exit</span><span style="">(</span><span style="">)</span><span style="">;</span>
| | //paste these lines into a new document in miniAudicle, or save text as a .ck to run in command-line |
| <span style="">// print out device that was opened</span> <span style=""><<<</span> min.<span style="">num</span><span style="">(</span><span style="">)</span>, <span style="">" -> "</span>, min.<span style="">name</span><span style="">(</span><span style="">)</span> <span style="">>>>;</span> <span style=""><<<</span> mouse.<span style="">num</span><span style="">(</span><span style="">)</span>, <span style="">" -> "</span>, mouse.<span style="">name</span><span style="">(</span><span style="">)</span> <span style="">>>>;</span>
| | |
| <span style="">while</span> <span style="">(</span> <span style="">true</span><span style="">)</span> <span style="">{</span> min <span style="">=></span> now<span style="">;</span>
| | //change these to match your input/output device |
| <span style="">while</span><span style="">(</span> min.<span style="">recv</span><span style="">(</span>inmsg<span style="">)</span><span style="">)</span> <span style="">{</span>
| | 0 => int inDeviceNum; |
| <span style="">if</span><span style="">(</span> inmsg.<span style="">data1</span> <span style="">%</span> <span style="">16</span> <span style="">==</span> <span style="">0</span><span style="">)</span> <span style="">// only receive on channel 1</span> <span style="">{</span> <span style=""><<<</span> <span style="">"r "</span>, inmsg.<span style="">data1</span> <span style="">/</span> <span style="">16</span>, inmsg.<span style="">data1</span> <span style="">%</span> <span style="">16</span>, inmsg.<span style="">data2</span>, inmsg.<span style="">data3</span><span style="">>>>;</span>
| | 1 => int outDeviceNum; |
| <span style="">if</span><span style="">(</span> inmsg.<span style="">data1</span> <span style="">/</span> <span style="">16</span> <span style="">==</span> <span style="">9</span><span style="">)</span> <span style="">{</span>
| | |
| mt.<span style="">NoteOn</span><span style="">(</span>inmsg.<span style="">data2</span>, inmsg.<span style="">data3</span><span style="">)</span><span style="">;</span> <span style="">}</span> <span style="">if</span><span style="">(</span> inmsg.<span style="">data1</span> <span style="">/</span> <span style="">16</span> <span style="">==</span> <span style="">8</span><span style="">)</span> <span style="">{</span> mt.<span style="">NoteOff</span><span style="">(</span>inmsg.<span style="">data2</span>, inmsg.<span style="">data3</span><span style="">)</span><span style="">;</span> <span style="">}</span> <span style="">if</span><span style="">(</span> inmsg.<span style="">data1</span> <span style="">/</span> <span style="">16</span> <span style="">==</span> <span style="">12</span><span style="">)</span> <span style="">{</span> <span style="">//prog change apply to channels 1-16</span> <span style="">//works!</span> inmsg.<span style="">data1</span> <span style="">-</span> <span style="">(</span>inmsg.<span style="">data1</span> <span style="">%</span> <span style="">16</span><span style="">)</span> <span style="">=></span> <span style="">int</span> base<span style="">;</span> <span style="">for</span><span style="">(</span><span style="">0</span><span style="">=></span><span style="">int</span> i<span style="">;</span> i<span style=""><</span><span style="">15</span><span style="">;</span> i<span style="">++</span><span style="">)</span> <span style="">{</span> base <span style="">+</span> chans<span style="">[</span>i<span style="">]</span> <span style="">=></span> outmsg.<span style="">data1</span><span style="">;</span> inmsg.<span style="">data2</span> <span style="">=></span> outmsg.<span style="">data2</span><span style="">;</span> i<span style="">++;</span> <span style="">if</span><span style="">(</span> i <span style="">==</span> <span style="">15</span><span style="">)</span>
| | class MicroRobinMidiIO |
| <span style="">{</span>
| | { |
| <span style="">0</span> <span style="">=></span> outmsg.<span style="">data3</span><span style="">;</span> mouse.<span style="">send</span><span style="">(</span>outmsg<span style="">)</span><span style="">;</span> <span style="">break</span><span style="">;</span>
| | MidiIn min; |
| <span style="">}</span>
| | MidiOut mouse; |
| base <span style="">+</span> chans<span style="">[</span>i<span style="">]</span> <span style="">=></span> outmsg.<span style="">data3</span><span style="">;</span> mouse.<span style="">send</span><span style="">(</span>outmsg<span style="">)</span><span style="">;</span> inmsg.<span style="">data2</span> <span style="">=></span> outmsg.<span style="">data1</span><span style="">;</span> i<span style="">++;</span> <span style="">if</span><span style="">(</span> i <span style="">==</span> <span style="">15</span><span style="">)</span> <span style="">{</span> <span style="">0</span> <span style="">=></span> outmsg.<span style="">data2</span> <span style="">=></span> outmsg.<span style="">data3</span><span style="">;</span> mouse.<span style="">send</span><span style="">(</span>outmsg<span style="">)</span><span style="">;</span> <span style="">break</span><span style="">;</span> <span style="">}</span> base <span style="">+</span> chans<span style="">[</span>i<span style="">]</span> <span style="">=></span> outmsg.<span style="">data2</span><span style="">;</span> inmsg.<span style="">data2</span> <span style="">=></span> outmsg.<span style="">data3</span><span style="">;</span> mouse.<span style="">send</span><span style="">(</span>outmsg<span style="">)</span><span style="">;</span> <span style="">}</span> <span style="">}</span>
| | MidiMsg inmsg, outmsg; |
| <span style="">if</span><span style="">(</span> inmsg.<span style="">data1</span> <span style="">/</span> <span style="">16</span> <span style="">==</span> <span style="">11</span><span style="">)</span> <span style="">{</span> <span style="">//apply any controller data to channels 1-16</span> inmsg.<span style="">data1</span> <span style="">-</span> <span style="">(</span>inmsg.<span style="">data1</span> <span style="">%</span> <span style="">16</span><span style="">)</span> <span style="">=></span> <span style="">int</span> base<span style="">;</span> inmsg.<span style="">data2</span> <span style="">=></span> outmsg.<span style="">data2</span><span style="">;</span> inmsg.<span style="">data3</span> <span style="">=></span> outmsg.<span style="">data3</span><span style="">;</span> <span style="">for</span><span style="">(</span><span style="">0</span><span style="">=></span><span style="">int</span> i<span style="">;</span> i<span style=""><</span><span style="">16</span><span style="">;</span> i<span style="">++</span><span style="">)</span> <span style="">{</span> base <span style="">+</span> i <span style="">=></span> outmsg.<span style="">data1</span><span style="">;</span> mouse.<span style="">send</span><span style="">(</span>outmsg<span style="">)</span><span style="">;</span> <span style="">}</span> <span style="">}</span> <span style="">}</span> <span style="">}</span> <span style="">}</span> <span style="">}</span> <span style="">// NoteOn</span> <span style="">// input: pitch in midi note-number extended, velocity</span> <span style="">// action: sends a MIDI pitchbend + note-on message to mouse on the current channel</span> <span style="">// keeping track of holds</span> fun <span style="">void</span> NoteOn<span style="">(</span><span style="">float</span> nn, <span style="">int</span> velocity<span style="">)</span> <span style="">{</span> IncrementCtr<span style="">(</span><span style="">)</span><span style="">;</span> nn <span style="">=></span> holds<span style="">[</span>chans<span style="">[</span>ctr<span style="">%</span>14<span style="">]</span><span style="">]</span><span style="">;</span> PitchBend<span style="">(</span>nn, velocity<span style="">)</span> <span style="">=></span> outmsg.<span style="">data2</span><span style="">;</span> <span style="">// note on, right channel</span> <span style="">144</span> <span style="">+</span> chans<span style="">[</span>ctr<span style="">%</span>14<span style="">]</span> <span style="">=></span> outmsg.<span style="">data1</span><span style="">;</span>
| | 0 => int ctr; |
|
| | |
| velocity <span style="">=></span> outmsg.<span style="">data3</span><span style="">;</span> mouse.<span style="">send</span><span style="">(</span>outmsg<span style="">)</span><span style="">;</span> <span style="">//<<< "s ", outmsg.data1 / 16, outmsg.data1 % 16, outmsg.data2, outmsg.data3>>>;</span> <span style="">}</span>
| | //int rr[128][3]; don't think we need this now. |
| <span style="">// increments mod-14 counter, skipping over channels with</span> <span style="">// notes already on them, if possible.</span> fun <span style="">void</span> IncrementCtr<span style="">(</span><span style="">)</span> <span style="">{</span> ctr<span style="">;</span> <span style="">0</span> <span style="">=></span> <span style="">int</span> i<span style="">;</span> <span style="">for</span><span style="">(</span> i<span style="">;</span> i<span style=""><</span><span style="">14</span><span style="">;</span> i<span style="">++</span><span style="">)</span> <span style="">{</span> <span style="">if</span> <span style="">(</span> holds<span style="">[</span>chans<span style="">[</span><span style="">(</span>ctr<span style="">+</span>i<span style="">)</span> <span style="">%</span> <span style="">14</span><span style="">]</span><span style="">]</span> <span style="">==</span> <span style="">0.0</span><span style="">)</span> <span style="">{</span> <span style="">(</span>ctr <span style="">+</span> i<span style="">)</span> <span style="">%</span> <span style="">14</span> <span style="">=></span> ctr<span style="">;</span> <span style="">return</span><span style="">;</span> <span style="">}</span> <span style="">}</span> <span style="">(</span>ctr <span style="">+</span> <span style="">1</span><span style="">)</span> <span style="">%</span> <span style="">14</span> <span style="">=></span> ctr<span style="">;</span> <span style="">}</span>
| | // index = note number? |
| <span style="">// NoteOff</span> <span style="">// input: pitch & note-off velocity</span> <span style="">// action: finds the pitch & offs it.</span> fun <span style="">void</span> NoteOff<span style="">(</span><span style="">float</span> nn, <span style="">int</span> velocity<span style="">)</span> <span style="">{</span> <span style="">0</span> <span style="">=></span> <span style="">int</span> c<span style="">;</span> <span style="">for</span><span style="">(</span>c<span style="">;</span> c<span style=""><</span><span style="">16</span><span style="">;</span> c<span style="">++</span><span style="">)</span> <span style="">{</span> <span style="">if</span><span style="">(</span>holds<span style="">[</span>c<span style="">]</span> <span style="">==</span> nn<span style="">)</span> <span style="">// we found the pitch!</span> <span style="">{</span> <span style="">128</span> <span style="">+</span> c <span style="">=></span> outmsg.<span style="">data1</span><span style="">;</span> <span style="">Math</span>.<span style="">floor</span><span style="">(</span>nn<span style="">)</span> $ <span style="">int</span> <span style="">=></span> outmsg.<span style="">data2</span><span style="">;</span> velocity <span style="">=></span> outmsg.<span style="">data3</span><span style="">;</span> mouse.<span style="">send</span><span style="">(</span>outmsg<span style="">)</span><span style="">;</span> <span style="">//<<< "s ", outmsg.data1 / 16, outmsg.data1 % 16, outmsg.data2, outmsg.data3>>>;</span> <span style="">0.0</span> <span style="">=></span> holds<span style="">[</span>c<span style="">]</span><span style="">;</span> <span style="">return</span><span style="">;</span> <span style="">}</span> <span style="">}</span> <span style=""><<<</span><span style="">"MISS"</span>, nn<span style="">>>>;</span> <span style="">// we couldn't find the pitch!</span> <span style="">// don't do anything. </span> <span style="">}</span>
| | // column 0 = channel sent to |
| fun <span style="">void</span> ControlChange<span style="">(</span><span style="">int</span> channel, <span style="">int</span> prognum, <span style="">int</span> val<span style="">)</span> <span style="">{</span> <span style="">128</span> <span style="">+</span> channel <span style="">=></span> outmsg.<span style="">data1</span><span style="">;</span> prognum <span style="">=></span> outmsg.<span style="">data2</span><span style="">;</span> val <span style="">=></span> outmsg.<span style="">data3</span><span style="">;</span> <span style="">}</span> <span style="">}</span> <span style="">class</span> MidiTransform<span style="">{</span> <span style="">// superclass for MIDI transformers to be used by MicroRobinMidiIO</span> MicroRobinMidiIO myIO<span style="">;</span> fun <span style="">void</span> LinkToIO<span style="">(</span>MicroRobinMidiIO io<span style="">)</span> <span style="">{</span> io @<span style="">=></span> myIO<span style="">;</span> <span style="">}</span> fun <span style="">void</span> NoteOn<span style="">(</span> <span style="">int</span> nn, <span style="">int</span> vel<span style="">)</span> <span style="">{</span> <span style="">return</span><span style="">;</span> <span style="">}</span> fun <span style="">void</span> NoteOff<span style="">(</span> <span style="">int</span> nn, <span style="">int</span> vel<span style="">)</span> <span style="">{</span> <span style="">return</span><span style="">;</span> <span style="">}</span><span style="">}</span> <span style="">class</span> SuperparticularSamchillian <span style="">extends</span> MidiTransform<span style="">{</span> <span style="">57</span>. <span style="">=></span> <span style="">float</span> resentFreq<span style="">;</span> <span style="">57</span>. <span style="">=></span> <span style="">float</span> prevFreq<span style="">;</span>
| | // column 1 = note number sent |
|
| | int chans[14]; // list of channels used |
| <span style="">62</span> <span style="">=></span> <span style="">int</span> keyboardCenterNN<span style="">;</span>
| | float holds[16]; // pitches of on notes, zero if off. |
| <span style="">float</span> prevFreqsByKey<span style="">[</span><span style="">128</span><span style="">]</span><span style="">;</span>
| | [0,1,2,3,4,5,6,7,8,10,11,12,13,14] @=> chans; //exclude channel 10 (drums) & 16 (send channel) |
| <span style="">//set pans funky</span> <span style="">//for(0=>int f; f<16; f++)</span> <span style="">//{</span> <span style="">// myIO.ControlChange(f, 9, f*8);</span> <span style="">//}</span>
| | |
| fun <span style="">void</span> NoteOn<span style="">(</span> <span style="">int</span> nn, <span style="">int</span> vel<span style="">)</span> <span style="">{</span> <span style="">if</span><span style="">(</span>nn <span style="">==</span> keyboardCenterNN<span style="">)</span> <span style="">{</span> myIO.<span style="">NoteOn</span><span style="">(</span> Std.<span style="">ftom</span><span style="">(</span>prevFreq<span style="">)</span>, vel<span style="">)</span><span style="">;</span> <span style="">}</span> <span style="">else</span>
| | //microtuning stuff |
| <span style="">{</span> <span style="">if</span><span style="">(</span>nn <span style=""><</span> keyboardCenterNN<span style="">)</span> <span style="">{</span> <span style="">// superparticular!</span> <span style="">1</span>. <span style="">+</span> <span style="">1</span>.<span style="">/</span><span style="">(</span>keyboardCenterNN <span style="">-</span> nn<span style="">)</span> <span style="">/=></span> prevFreq<span style="">;</span> myIO.<span style="">NoteOn</span><span style="">(</span> Std.<span style="">ftom</span><span style="">(</span>prevFreq<span style="">)</span>, vel<span style="">)</span><span style="">;</span> <span style="">}</span> <span style="">else</span> <span style="">{</span>
| | |
| <span style="">if</span><span style="">(</span>nn <span style="">></span> keyboardCenterNN<span style="">)</span> <span style="">{</span> <span style="">1</span>. <span style="">+</span> <span style="">1</span>.<span style="">/</span><span style="">(</span>nn <span style="">-</span> keyboardCenterNN<span style="">)</span> <span style="">*=></span> prevFreq<span style="">;</span> myIO.<span style="">NoteOn</span><span style="">(</span> Std.<span style="">ftom</span><span style="">(</span>prevFreq<span style="">)</span>, vel<span style="">)</span><span style="">;</span> <span style="">}</span> <span style="">}</span> <span style="">}</span> Std.<span style="">ftom</span><span style="">(</span>prevFreq<span style="">)</span> <span style="">=></span> prevFreqsByKey<span style="">[</span>nn<span style="">]</span><span style="">;</span> <span style="">}</span>
| | // PitchBend |
|
| | // input: pitch (midi note number float) & velocity of desired note |
| fun <span style="">void</span> NoteOff<span style="">(</span> <span style="">int</span> nn, <span style="">int</span> vel<span style="">)</span> <span style="">{</span> myIO.<span style="">NoteOff</span><span style="">(</span> prevFreqsByKey<span style="">[</span>nn<span style="">]</span>, vel<span style="">)</span><span style="">;</span> <span style="">}</span> <span style="">}</span>
| | // action: sends appropriate pitchbend message |
| MicroRobinMidiIO mrmio<span style="">;</span>SuperparticularSamchillian easy<span style="">;</span>easy.<span style="">LinkToIO</span><span style="">(</span>mrmio<span style="">)</span><span style="">;</span>spork ~ mrmio.<span style="">StartRelay</span><span style="">(</span> <span style="">1</span>, easy<span style="">)</span><span style="">;</span> <span style="">1</span><span style="">::</span>second <span style="">=></span> now<span style="">;</span>
| | // (assuming pitchbend range = +/- 2 semitones) |
| KBHit kb<span style="">;</span>
| | // output: note number required for correct frequency to be realized |
| <span style="">while</span><span style="">(</span><span style="">true</span><span style="">)</span><span style="">{</span> kb <span style="">=></span> now<span style="">;</span>
| | // sends pitchbend, assuming +/- wholestep pitchbend range |
| <span style="">while</span><span style="">(</span> kb.<span style="">more</span><span style="">(</span><span style="">)</span> <span style="">)</span> <span style="">{</span> kb.<span style="">getchar</span><span style="">(</span><span style="">)</span> <span style="">=></span> <span style="">int</span> c<span style="">;</span> <span style=""><<<</span> <span style="">"ascii:"</span>, c<span style="">>>>;</span> easy.<span style="">NoteOn</span><span style="">(</span>c, <span style="">88</span><span style="">)</span><span style="">;</span> <span style="">}</span><span style="">}</span> </pre>
| | // 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); |
| | } |
| | } |
| | </pre> |
| [[Category:chuck]] | | [[Category:chuck]] |
| [[Category:code]] | | [[Category:code]] |
| [[Category:todo:link]] | | [[Category:todo:link]] |
//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);
}
}