Implement Chuck in Max for Live in Ableton 10
Hi all
I have written a script in Chuck which is meant to play back segments of a sample in random order and at different speed and direction. The script has some variables build into it, e.g. the amount of segments the imported sample is split into, as well as the different playback speeds that might occur. Here's my Chuck script:
/* Chuck Computer Music - Chop, reorder and play at different speeds */
/* load sample*/
SndBuf buffer => dac;
me.dir() + "/Users/Matthias/Music/Chuck/Samples/" + "sample3.wav" => buffer.read;
1 => buffer.loop;
/* get the number of samples in the file, divide by 16*/
buffer.samples() / 16 => int s;
/* define a duration 'tick' */
s::samp => dur tick;
while(true) {
if (Std.rand2(1,10) < 4) {
s * Std.rand2(0,15) => buffer.pos;
}
/* randomly set the rate of the buffer from half to double speed, with
weighted probability */
if (Std.rand2(1,10) < 2) {-2 => buffer.rate;}
else if (Std.rand2(1,10) < 1) {1.5 => buffer.rate;}
else if (Std.rand2(1,10) < 1) {0.75 => buffer.rate;}
else if (Std.rand2(1,10) < 3) {0.5 => buffer.rate;}
else {1 => buffer.rate;}
tick => now;
}
Now, I would like to create a M4L instrument out of this Chuck script, in order to use it more easily when producing music in Ableton 10. Can anyone recommend me tutorials/guidelines on how to implement Chuck in Max for Live? I have read about the Chuck~ object but it's not available in my Max environment. Should I download it or is it outdated? I do have encountered the ability to "import" plug-ins into the Max environment, but I would like some extra info on that as well.
So, in the end. I just want Max for Live to communicate with Chuck. Any tips please?
Thanks in advance!
Matthias
It would be pretty simple to just write this patch in Max. You'll probably spend more time trying to find something with Chuck compatibility than you would just coding it directly....
\M
Any tips on how to write this patch in Max?
I'm no Chuck programmer, but something like:
-- load a sound into a buffer with the "replace" message
-- use [info~] to get your sample length
-- divide by 16 to get playback unit length
-- [random 15] * unit length to generate random start point
-- startpoint + unit length to set endpoint
-- send to loop points on groove~ object
-- use a weighted random (via table, zl lookup, lots of ways to skin that cat) to generate your pitch value
-- send pitch to sig~ to set groove~ rate
-- trigger the groove~
-- repeat
Like that!
Alright, thanks for this guideline. Will be very helpfull!
Though a first irregularity has popped up already; the Buffersize (in samples) retrieved from the samps attribute, and the one calculated from the Sample Rate and Total Time (retrieved from info~ object) aren't equal. It is correct to say that the size of a sample (in samples) is equal to Sampling Rate (Hz) multiplied with Total Time (s), right?
See screenshot in attachment.
thanks!

You are doing an integer multiplication and division. You need a floating-point argument to the [*] and the [/] to have it do FP math.
Try attaching the total time output of info~ to [translate ms samples] and see what you get. See attached patch.
\M
Thanks Mattyo, this worked.
I'm currently struggling with retriggering groove~ after a segment has played. I know groove~ outputs a signal ramping up from 0 to 1 during a loop playback, so in fact I want certain things retriggered (e.g. random startpoint generator, groove object) whenever this output signal reaches 1.
Any tips on this step?
Attach this to groove~s sync outlet:
Super nice solution Mattyo! Couldn't have come up with that myself.
Though a main problem now left is that I can't stop the sample. This is because stopping the sample is a change in negative direction and therefore delta~ sends out a negative impuls which is captured by edge~ which sends out a bang to start playing the sample again..
Right. groove~ can be kind of annoying when playing backwards. Two options I can think of:
1. have a second delta~ connected to the sync, with [>=~ 0.] instead, and switch between them depending on direction;
2. use play~ instead, with "start <startpoint> <endpoint> " messages. a bit more annoying, but it will always send a bang out the right outlet when done.
I'd do it in gen~, myself.
not sure that's helpful but I've heard there is a plugin for Chuck that let's you use Chuck code as a VST plugin