Non Repeating Round Robin Help
-
@d-healey
i would like each sampler to change to a different group -
@Casmat In that case you should use one RR script per sampler. Of course you don't want to re-write the same code 3 times, so this is where a reusable module is perfect.
This is what we did in the Hackspace course (I think it was in part 3).
-
got it! thanks for clarifying!
-
@d-healey
Just tried testing it and it seems to not work still. the RR groups in the sampler view don't seem to change number. this is what I have so far:oninit:
const var sampler0 = Synth.getSampler("sampler0"); sampler0.enableRoundRobin(false); reg counter = 0; reg lastCount = 0;
onnoteon:
function onNoteOn() { counter = (lastCount - 1 + Math.randInt(2, 5)) % 5 ; sampler0.setActiveGroup(counter + 1); lastCount = counter; }
Here's the hise snippet as well:
HiseSnippet 2257.3oc6b0sbabaEdWIgXQFKYmLIcZm1NyVOsyPkXqvkxVoynoiV8aBqsjnIUTSuHiCzRPRDsDXCVrxVMiq0zIOB8lbWdD5ifeDZmoO.9pNSuKuAs.6tjKVJJEJpehnDzUBXW.78c.1y4fymkqvntnf.JyvL21G3iLLuMn1ADdqUZAwDixqZX9yAa2BY8Y9LbyVbqkgAAVUvPB0X4C7EMP0MLMG+SjusYtILh94GVbYnGj3hR6xvXGJ1E8DbaLOs2JNOF64sNrNZabak29gNkcojUndzPAxFGTzvG5tGrIZSn70FCXX9VqUGyorZbHGEXXNwxz5GTqE84j32eGb.dWOjrgsQMwDE285Tu5RDK60XkVXu5U5XABLLLAURsGiGaOdOvF353t8mZWtazCrRGgp8vbrrva7LvyVEdEUfWefjoBjlHFRuCnlKC6ySehDOuMnLgiXMfBytJTheWCyWCVgJdABe11v8PqyDM5NfByWr38slqXwYVnQHwkioDKJYSJGsEovL4+l74x+x7V89nFM56yjKCi54gX88wxcZ1IMvBjv16hX22ZenWHp6KJneVaJ33sopa4twrV4EojxDLeKeD43NHXjXpD1+oSPk3U4QV+oSr907v0QLCrvHmGrGYW4m.EMhvr5wdiSy3sOiiuzvM9Ikie8WT7LM5gD62MZzXOwIwkpGvJdtLKmOXoz4xrL2vMKua1YYo17gadlRNOK01+LXbUmB6y9TT5rOE8yl9YkWExgROlIe7J9f1Gw3XouByUQ6KB+D6+LGXUTvdbpuHRxJz19Th7ScyIiW5oRV5xsEwahV46.vsatrH.TSFMjT23Epq6ApMdNtNuU2Nd8eyoERF0LsGlCG8BYavtMiWfFXujnZkAeSkpa8GWakse15a8jUWq5K2fx7aIbj07.qGX0+nvVE1o11V+InmmOTv1Yl0mzTZN6xpamkUUfDjWDqlF3S7jlJgeCgI9LQpcapFqFyQs6e6RwcHsApuvtTlXWtJrNNLPcki6uF9ujYmV5RtK8d6AwobJ2bPNob6vFNY4lQ4d4lnGeHSrRJKYOFt3MTQJIhcx1AbAJh2XM+kGY+7wD5t1Q6P3fcjGMcgdwV.QHuZxglR+CK6Xb53osJO+5qu7rjBOeyyu1wytAiSY4gOVgkNe40HVpdl8tu5ZGKORxMJdYWWgsu4q5ksEOBacFd19aNBa2DEjfyXNeTNZrnSaZX.pFhDf438wbkfBuYwgh+p61Vacyi+pdtr19lG+mSg+u9yu1v+bmlj3Ur.egp+tds.G5zqE3vebKvf4lqzwPYm+7.5VK6cJRYzW9WuAblN6sgRI+29paXjW0a11GdCi7ptx9Oi3j+nUX7tfMn0C8f7rE7Tl8cxCvTRlpLJKknb1OPsJvmaUAcPg36.pf4ts5OFGqOXTbaxKBLlT63o.q0nAxkmBvI.q+4WLEJVc4m7XJk+sAtcNgU77n789Cb46MG+hnb825hpb8SLX6BmL7t79t5REtmCeicti2g+6sycn7qigx6BDNgQv1XRyZv19dnXQZxCBhacI+8WEFxiBqmsTZu1Y4Pg8pmBr8ObhVpkDgLHYVqDdTE4ifbw1uxXlzoZ0OgQC86cTumSzgksYP28DlBUNtEAIr6bUNtBiFDzPPmn4JSo.qDxZJsUo8TEsOhEjsuMCaK16IDjmTeHSSYYgEw8D60X2MfhnhYpxYzpTbaXz9sHVaTa6dZWpm1y0S6G1S6G0S646o8Gm1N1ftAzumSF8Jz0sFLgtDSTT0cUdykwM6tHw8ndPtq4NBRJdi6iq125Jsq1AWkzo.Q0vmQ2UVX39nS5XeqoLJY.2ZeHypydh0evJJV5rMQ7juCJbuNO7dyrP9N+9rHhzXVUtHUkKRgFPu.j3MxyPMsbkedfXhoq3BQc3ACDoAJ5LpqiQ70zQUH88efks0GZINU2ZVFjTW33sPo6a8nYlw52Y8HqExmqKjBP7kDS69weVUnyr8gV1BXkSEAIOZg7uL+MQwdGJMjFARe1bLELdmXLdKvRe5p0plDRO52sViruHLgOxNC11fRn9snDraV2uB2oMahXpHtuzXINW38ekP19JQL9mKtJxEdvQ5M9kUCkE2ySDd68TW+OU3PHs8u0IZ5T0jpVX.OSXUIl8PvfLAJWyklMT1oxraexlcv.dzXJPLIshBie0N8uo6f03cjq1f81fniEiB106.RNvNRXXmFj7szUES6shAadvNBOXtxUWBy2uaSqtjv9DQ62+ce2+cQQNiIYok56nrv2HimMcSwgK7tHurNPNUkTv9hurGiOpckrym+sxkqy8vpP8NHN7Ubg3i.QNPbC6S3ZXFFqyPecHh3pTl9W47T0y0Y25umySCgdJV54Gu7RKi8odP1Ys3S+HgZlX.Op7y.cIk0OM4hXd5xEojNWDctH5bQz4hL5jKxIGpVFjwZjoZu+BPR7KKYbiQGbOM3oiRfMtlRVhUmwux6GKpLRVxxN+SETqRC4XRyNkzErYX6ZzPlKRs5uiIKsSb6hx1R.UCQpG03+I9I4g1cJUr7g1cdngamoRvsjeOp3PliGWhuH4N75MUffvFMjPZLvvnJPlzQGSqJfVUfzSF2nTE3R3uWJUk.r6qR.+89nDf8IoDfshR.1WUTB3i9fHdZEQzfO3ijRCj.bsx.ZkAz2FWeab8sw02FWqL.qjVY.sx.cTFnzEpx.e++9G9WZkANaJC7PctH5bQz4hnyEQqLfVY.sx.ZkAtNqLPIsx.ZkA5qx.kzJCbApLPoAVYfRmjx.kTTFnjVY.sx.W6TFXN8sw02FWeab8swuNpLvbZkAzJCzQYf4tX+aFv3W89ZkANaJCLuNWDctH5bQz4hnUFPqLfVY.sx.iNJCbYfxKi0nMzkQelabA6j1iIi5QXIHQ+mcdNvFx1Vc++Sd.n3rEMZiqielqqLi+GH1E6+XJMDiYtgXLObHFyiFhwL+PLlOdHFyu+DGirF7KExosi89I5nxZwGdMWq6g2wM9+.zZN4GA
-
@Casmat Your snippet works here, the groups change with each key press.
I noticed you are hardcoding the sampler reference which means you need three separate scripts. Try to avoid this. Instead, reuse the same script as I demonstrate in the Hackspace course.
The problem with writing 3 scripts that all do the same thing is it doesn't scale well and you give yourself additional code maintenance. Imagine you have a project with 10 samplers, now you have 10 separate RR scripts that all do the same thing except one line is different. Then you find a bug in the script, now you have to go through 10 scripts to fix the bug 10 times. It makes no sense to do that when you can write and maintain one script instead.
-
Hmm, that’s weird, it doesn’t seem to change on my end, I’ll try fiddling with it in the meantime and yes, I had the scripts all connected, I had just disconnected them to see if that would’ve fixed the problem. Thanks again for your help!
-
Hey, sorry for the necro bump. But if you've got say 7 RR groups... and for a particular velocity range there are only 6 samples..... is it possible to avoid the sampler triggering silence when it cycles around to the 7th group.
So for example:
RR1 - vel-range 60-70 - sample mapped
RR2 - vel-range 60-70 - sample mapped
RR3 - vel-range 60-70 - sample mapped
RR4 - vel-range 60-70 - sample mapped
RR5 - vel-range 60-70 - sample mapped
RR6 - vel-range 60-70 - sample mapped
RR7 - vel-range 60-70 - NO SAMPLE MAPPEDCurrently you hit a note to trigger the sample 6 times in a row... you'll trigger RR1, 2, 3, 4, 5, 6... and then on the 7th it will attempt to trigger RR7.... and produce silence, because there isn't a sample there.
Any way around this?
-
@Orvillain said in Non Repeating Round Robin Help:
Any way around this?
Put some samples there - copy them from another group
-
@d-healey said in Non Repeating Round Robin Help:
@Orvillain said in Non Repeating Round Robin Help:
Any way around this?
Put some samples there - copy them from another group
Ahhh, I think I figured it out.
In the init script:
Content.makeFrontInterface(600, 600); const var Sampler1 = Synth.getSampler("Sampler1"); Sampler1.enableRoundRobin(false); Sampler1.refreshRRMap(); var last_group = 0;
In the onNoteOn function:
function onNoteOn() { var note = Message.getNoteNumber(); var vel = Message.getVelocity(); var rrGroups = Sampler1.getRRGroupsForMessage(note, vel); Console.print('For this note and vel we have a max of - ' + rrGroups + ' rrGroups'); if (last_group >= rrGroups) { last_group = 0; } Console.print(last_group); Sampler1.setActiveGroup(last_group+1); last_group += 1; }
This will ensure that for a given note and velocity, the active group can never be one that is empty - assuming that it is always the later groups that are empty, and not the ealier ones.
IE: For all samples group 0, 1, 2, 3 should be populated. If you have groups 0, 1, 3 populated, then group 2 will still fire off silence. Not too bad. There is at least a way.
The will cycle around the groups in a forwards RR style. If you wanted it to be random, you'd have to adjust the logic.
-
@Orvillain yes, just don't ever declare variables in realtime callbacks and use reg whenever possible for realtime callbacks. You get 32 slots by default, but if you ever need more, create a namespace (each namespace gets its own 32 regs).
var in your case creates a scoped variable that will be killed once the function is executed. Memory allocation and deallocation is a bad idea for realtime. That's also why for any arrays you use in realtime callbacks, even reg, need to have reserved slots by calling array.reserve().
Objects cannot have dynamic access in realtime callbacks. Any object properties you want to use, you need to assign/initialize beforehand in on init.
So in your case, you need to declare these variables as reg in on init and then store whatever in on note on.
I suggest you build HISE with the audio thread guard (find it in the JUCE_CORE module in Projucer) and enable it in project settings. It should then scream at you whenever you try something like this.
-
@aaronventure All good points!