maxdemian
Joined: Jan 29, 2011 Posts: 7 Location: berlin
|
Posted: Sat Jan 29, 2011 6:42 am Post subject:
Controlling shreds via MIDI Subject description: please help me |
 |
|
Hi all of you,
i have a performance in a few hours, i use a little bit of chuck, but i've nearly no experience in programming.
I just thought about this right now:
I have four different shreds, and i am using miniaudicle:
i always just want one shred to be active.
but i dont want to change them with my mouse, as chuck is running on the same computer as visuals are running to a big screen.
so i want to use 4 buttons on my midicontroller, each stands for one shred, and kills the shred wich is active.
btw: there is no computerkeyboard connected to the computer, so keyboard shortcuts or something wont work.
is that possible in a easy way?
can you give me the code for it where i just have to input the file names and the midi data of the buttons?
it would be so nice of you, because i have really no time left now.
lg
maxdemian
ps. sorry for my weird english  |
|
jordan
Joined: May 16, 2011 Posts: 5 Location: Brooklyn, New York
|
Posted: Wed May 18, 2011 12:34 pm Post subject:
|
 |
|
I'm guessing that I found this too late to help you out, but I'm going to tackle your problem for posterity (and to have that trick up my own sleeves ^_^)
First, take a look at the section "using Machine.add" on this page:
http://chuck.cs.princeton.edu/doc/language/spork.html
You can use Machine.add to spork new shreds through code and save the id of the shred. This is undocumented, but Machine.replace will also return the id of the newly created shred.
For reasons of flexibility and sanity, I highly recommend you put the source code for each of the shreds in a separate file instead of in the file that launches it. For this example, we'll call them "shred_1.ck", "shred_2.ck", etc. I personally use a Novation Launchpad, so the Midi message parsing is designed for the four squares in the upper-left of the Launchpad's button grid. You'll have to change this portion of the code to get things working properly for your controller.
The meat of this example is in the reShred function. I temporarily store the id of the current shred so that I can restore this id if Machine.add or Machine.replace fail; in that case, each of those functions returns 0 (false). With this implementation, you can edit the contents of the child shred files (shred_1.ck, shred_2.ck, etc) and dynamically reload them, but you're protected from having a syntax error stop your sound. If you hit an error, it simply keeps going with the previously-working shred.
The full example can be seen in the following gist: https://gist.github.com/979344
Alternatively, here's the raw source. You'll have to split it up until files as indicated by the comments.
Code: |
/*------------------------------------------------------------------------------
main.ck
------------------------------------------------------------------------------*/
MidiIn min;
MidiMsg msg;
false => int activeShred; // store the id of the currently active shred.
// always be mindful of your starting conditions;
// in this case, the starting condition is that we
// have not yet launched any child shreds.
if(!min.open(0)) me.exit();
fun int reShred(string shredFileName, int currentShred) {
// temporarily save the id of the last working shred.
currentShred => int previousShred;
if(currentShred) {
Machine.replace(currentShred, shredFileName) => currentShred;
} else {
// starting condition; this will be executed only the first time.
Machine.add(shredFileName) => currentShred;
}
// helps protect us if the file indicatd in "shredFileName" has an error
// in it.
if(!currentShred) previousShred => currentShred;
return currentShred;
}
fun void midiHandler() {
while(true) {
min => now;
while(min.recv(msg)) {
// you'll have to update this to suit your controller.
if(msg.data1 == 144 && msg.data2 == 0 && msg.data3 == 127) {
reShred("shred_1.ck", activeShred) => activeShred;
} else if (msg.data1 == 144 && msg.data2 == 1 && msg.data3 == 127) {
reShred("shred_2.ck", activeShred) => activeShred;
} else if (msg.data1 == 144 && msg.data2 == 2 && msg.data3 == 127) {
reShred("shred_3.ck", activeShred) => activeShred;
} else if (msg.data1 == 144 && msg.data2 == 3 && msg.data3 == 127) {
reShred("shred_4.ck", activeShred) => activeShred;
}
}
}
}
spork ~ midiHandler();
while(true) {
100::ms => now;
}
/*------------------------------------------------------------------------------
shred_1.ck
------------------------------------------------------------------------------*/
while(true) {
50::ms => now;
chout <= "hello from shred 1." <= IO.newline();
}
/*------------------------------------------------------------------------------
shred_2.ck
------------------------------------------------------------------------------*/
while(true) {
50::ms => now;
chout <= "hello from shred 2." <= IO.newline();
}
/*------------------------------------------------------------------------------
shred_3.ck
------------------------------------------------------------------------------*/
while(true) {
50::ms => now;
chout <= "hello from shred 3." <= IO.newline();
}
/*------------------------------------------------------------------------------
shred_4.ck
------------------------------------------------------------------------------*/
while(true) {
50::ms => now;
chout <= "hello from shred 4." <= IO.newline();
}
|
|
|