how do I get a codebox to count?

Hannes d'Hoine's icon

Hello everyone, I'm doing my first efforts on writing codebox.

I want the slot number go up one step every time the index number is reached by the counter number (c). But the code below doesn't seem to work. What am I doing wrong? I can see that it's counting, but the slot number doesn't change.

👽'tW∆s ∆lienz👽's icon

with just the code you've given, there's no way to tell how your line:

index = floor(peek(transientindex, slot) * dim(looper)); would fail. but that is probably the line that is failing to trigger the next conditional below that which is

index == c(we can't see the 'transientindex' and 'looper' buffer/data spaces and understand what you're trying to 'peek' from 'transientindex', in particular).

so you just need to look more closely at your patch and notice why index == c never seems to hold true(otherwise, post the full patch and it'll be easier for others to see where it's going wrong).

one suggestion: take a closer look at how 'counter'/'c' maybe acting against detection in the 'peek' which you 'floor': if 'unit' is the minimum of the count, and you've set it to '1', while 'index' is being 'floor'ed from a floating-point value, then it could be that 'index' is stuck at '0' while 'c' is always counting between '1' and 'length'(?)... therefore, 'index' will never equal 'c'. this might not be the problem, but is just one example of how detailed you need to look into knowing the exact values being sent there, so that you know you're not constraining yourself out of the range you expected.

hope this can help.

Hannes d'Hoine's icon

Here's the patch. It's not finished yet so I hope you can make something out of it. You arm the rec buffer, press play on the playlist object and then play in the patch to make a loop. Best to lower sensitivity a bit; I'm using it with live input, just put the playlist in to demonstrate. the transient phases get recorded in a 32 samps buffer (transientindex). I would like to send clicks on those values to trigger other samples as well.

The codebox is counting now, but I must've done something wrong because the counting is at really weird places and with weird values. Probably because I'm calculating something wrong somewhere; Here's what the codebox looks like now: (patch below)


Max Patch
Copy patch and select New From Clipboard in Max.

👽'tW∆s ∆lienz👽's icon

it seems to be working now, although i probably don't understand most of it(for example, what 'slot' and 'sliceamount' are actually referring to, in terms of sound captured...), but i think the code might work more reliably if you perform the 'wrap' within the conditional(the only place where 'slot' is changed without being set to a discrete number), this way you're not accidentally incrementing 'slot' more than once, but only when you need to by the 'index==c' conditional:

Param sliceamount, length;
History index;
History slot;
trig, pulse= in1, 0;
c = counter(1, 0, length);
index = floor(peek(transientindex, slot) * dim(looper));

if (trig == 1){
     c = 0;
     slot = 1;
}

if (index == c) { 
     pulse = 1;
     slot = wrap(slot+1, 0,sliceamount + 1);
}
else { pulse = 0;}

out1 = pulse;
out2 = c;
out3 = index;
out4 = slot;

you mentioned, "the counting is at really weird places and with weird values", but i'm not sure what you mean?

'slot' seems to be incrementing predictably for me, as long as i use 'arm', then start the playlist playing, then hit 'play' to playback(plus, make sure the 'amount of slices' is set to something more than '0'). this series of actions seems to set the 'length' and 'sliceamount' properly, input transients into the buffer, and then increment 'slot' according to when those transients are encountered. i'm assuming this is the desired behavior?

(and this, too, with the altered code i have just above... so that you're not telling 'slot' to increment twice within the same code)

hope i'm making sense here. let me know if the above code doesn't improve things, and if not, maybe more description on what you want all the various parts to do.

Hannes d'Hoine's icon

indeed! that's it! I was indeed telling 'slot' to increment twice, which made it jumpy and I couldn't really tell what was going on. Thanks!!

A little explanation about the patch. The patch expects live input. You arm the patch with the arm button, and when you play (preferably percussive sounds, but it works with a guitar, synth or bass as well, or any other soundsource, you just need to adapt the threshold) you trigger an onset detector and start recording from the first transient. When you push play, you end the recording, end the loop, and start playing the loop. The loop is sliced on transients, which you can play separately. The sliceamount is calculated and sent to the rest of the patch. It is necessary to know how many slices there are, otherwise you are triggering empty space in the buffer later on.

The goal with the code I was struggling with is to play different slices but at the same moment where the original transients are (the transientindex is a buffer into which I recorded where the transients in the loop happened. Every "slot" is a sample in that transientbuffer. So the first sample holds the first transient phaseindex, the second sample the second transient phaseindex etc. I found it in another thread somewhere and adapted it to my needs. Screenshot below. The original patch is from Graham Wakefield. )

After all slices are played (set by sliceamount), the index wraps back to the first slice.

Probably a bit confusing and not clearly explained, but it's the best I can do at the moment, been only using Max for a year now.

Anyway, big thanks for the help, now I can finally finish this patch!