Browsable Snippet: [Clocksynced Arpeggiator]
-
Over the time I've got so many request of modifying the existing arpeggiator that I think it's a better approach to just rewrite the logic in a new module and then let the people customize as you wish, so here we go:
In the snippet browser you can now find a snippet with a new arpeggiator that should be a much better starting point. It includes the latest and greatest coding practices - using a FixObjectFactory and relying on their native sortability for almost C++ like performance and the grid callback of the transport handler which allows you to lock the arpeggiator timing to the DAW clock instead of relying on the note timing.
I opened this forum topic for any discussion around the snippet (as I think that might be a good channel of communication that I'll be using for the more complex snippet examples going forward) so post any feedback about the snippet in here (I'll post a link to this topic in the snippet description in the browser).
-
@Christoph-Hart Hi, I'm trying to add this to my project, I have a few questions:
Regarding the octave range, is it possible to make it go negative (down octaves)? I could do this in the old arp. I tried changing the min and max range, but it didn't work.
Another thing I noticed: when the octave range is set to 2, the arp adds one octave, and when set to 3, it adds two octaves, and so on. Shouldn't it be 0-based? If set to 1, the arp should add one octave to the held notes, so when it's set to 0, it plays only the notes being held.I'd like to show the notes being played by the arp in the UI. Is it possible to get the note numbers that the arp is outputting? If so, how?
I'd love to be able to add glide to the arp. What is the best way to have this arp work nicely with the mono/glide script from the snippet browser? Perhaps there is a way to combine the two scripts to use a single object factory?
-
@CyberGen said in Browsable Snippet: [Clocksynced Arpeggiator]:
I'd like to show the notes being played by the arp in the UI. Is it possible to get the note numbers that the arp is outputting? If so, how?
One answer:
Insert this into the snippet.//Add note Note Names const var noteNames = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]; //Add labels to display name and number const var noteNumberView = Content.addLabel("noteNumberView", 550, 0); const var noteNameView = Content.addLabel("noteNameView", 650, 0); //! LOGIC FUNCTIONS // ========================================================================== // Just a small helper function that plays a note with a defined length inline function playNote(noteNumber, velocity, timestamp, length) { local newId = Synth.addNoteOn(1, Math.range(noteNumber, 0, 126), velocity, timestamp); local noteName = noteNames[noteNumber % 12];//ADD local octave = Engine.doubleToString((Math.floor(noteNumber / 12) - 1), 0.0);//ADD // Send note number and name to display noteNumberView.set("text", noteNumber);//ADD noteNameView.set("text", (noteName + octave));//ADD Synth.noteOffDelayedByEventId(newId, timestamp + length); return newId; } }
-
@Christoph-Hart I have a project that currently uses three samplers, each with its own arp. I stumbled across this yesterday and was initially excited because of the improved sync but then spotted this:
// The only real limitation of this approach is that it doesn't allow multiple arpeggiators to run // simultaneously (because there's only one grid callback) but that is a rather exotic use case
As an experiment, I made a project with three waveform generators and added a script processor to each to run this code in and, following a bit of tweaking, observed that everything could be set individually with the exception of the Tempo value. Tempo value was global and reflected whichever of the three Tempo controls was last moved.
Is the reason you can only have one Tempo value because you can only have one transport handler? Is there any possible way to enable all parameters to be set on a per instance basis?
-
@CyberGen said in Browsable Snippet: [Clocksynced Arpeggiator]:
Found one solution to this question:
Regarding the octave range, is it possible to make it go negative?
- First, customize the min, max and middlePosition for the octave knob properties:
// The number of octaves. This will create octaved copies of the currently held notes const var numOctaves = Content.addKnob("Octaves", X_OFFSET + 0, Y_OFFSET + 60); numOctaves.set("min", -4); numOctaves.set("max", 4); numOctaves.set("middlePosition", 0); numOctaves.set("stepSize", 1);
- Then make changes to the rebuildSortedList function to:
Calculate absolute value of the octave range knob.
Add if statement to discern upwards from downwards transposition.
inline function rebuildSortedList() { // Clear the sorted list sortedList.clearQuick(); // Sort the notes before stacking them up in the octaves activeNotes.sort(); // for each octave, insert the sorted list into the note array for(i = 0 ; i < Math.abs(numOctaves.getValue()) + 1; i++) { for(s in activeNotes) { // Copy all relevant properties (currently we don't) // use the velocity property at all, but that can be // used for further customization if (numOctaves.getValue() >= 0) scratch.noteNumber = s.noteNumber + i * 12; else scratch.noteNumber = s.noteNumber + i * -12; scratch.id = s.id; scratch.velocity = s.velocity; sortedList.insert(scratch); } } };
-
@M_Holloway said in Browsable Snippet: [Clocksynced Arpeggiator]:
Is the reason you can only have one Tempo value because you can only have one transport handler? Is there any possible way to enable all parameters to be set on a per instance basis?
I think you can have several arps running in different tempos with Christophs "Clocksynced Arpeggiator" if you have them set per/voice source.
I haven't tried this but I managed to do it in this experiment where I built an arp using the Transport Handlers setEnableGrid() functionTake a look in the snippet and maybe you can find a way to do it in your project
Remember this is only a test and I know nothing about the performance or any complications that can come from it, but so far so good.HiseSnippet 5024.3oc6c07baibkmz1zyPLalJIURp4TpdTkYVRKZIBRJJY63nussrkL4XRqY7NwUJHhljvBDfF.TVzSTsmx+Q49tG2C6gs1+BxdYq83bbOs69dc2.nAIHErj+Ja.mQjn+926i985tQ+looicGpqqsSlr4aOdHMS1+tbsFa40e69ZFVY1aGLisG45YOfroyvLaMdnlqKUOS1rW89XMxl+ZYXe9w02RyTypCMLqLYNz1nCceiAFdg41biGYXZdOMcZaiAR0t1F60w1ZaaS6Q.ZtZtxYFp04XsdzGqgU6J4xj856pa3Y6zxSyi5lI601xVebq91uxhW+CMbMNxjhITyzB5Hd12y1TGQL9bls6aXp2zmpcy.cZyPdvU47feQtCLzMBxOjW7SYEPBagL+H6UhBuqFAdpxvqrD7hARYkfz03P5mkqUGGigdgkf34yxsmkG0oqFv1kgButYx9OmaaanBVdKMP6X58bfDAMnP8xkKQfuJdmtir53YXaQrsdrsGsgUghJ+fRdkyTHSVT2twVFNLN1llTmXKFkzNyqgErFM3HpSIxIZlinAUDH+n7zbylmJKx6voZoJZasmkgWigTQ5o45YDrJ3omt2NZdZnfPjGTugTGOCDBY2gdBnUyEK4ysC08XO6gfd8TxLPawVejolWTUHbdin.fGDQtgBGKWCuwxyqlTu5ZISuJTsOVpMgv8mkqogWm9wi2qDCdAt16Z7Jlk9Sxsa2tzNdgf8Z4t22M2oju0gxmygxmkqkgEkY3jAjeEKM4a0NgRtO0h5fLU04X87eKoVOGlXqmM53ACeaGMK2g1tQ53VzAFsssPNRXlO0ELPPe4SPorb9aaq4DaQ+352CHxXaSKMuQNL0kMGXOxxKh5wUm2T5YZEO5rFIY37EVYu16Jy6WKYlhNGuOxl5yMOS8eRNv+KIpNziGMnkogN0oI3oDYkYuJx74F+uRwhAV+codOfZzquWA05f8dEkkugR918MbIZPmB+.5NcM5MxgpS5Z6PF4ZX0i7.CWJgdJzC.EP7nCFZqj2nKYr8n+dGJwx1STQu9ZdXtj9nBumMwgNvFepOkz0vw0irBzPnWNk5RLrHO9v8ssO9oCa44fM+qCx.HH.QNZicUxqYoSzLcsI.3Ise.RC6ZoAb366XnWvyYDsDQcsh2A5PWOplNwtKGiDv6FHmHUppbikUVd47.PoL+JtDSXXFML+Mm5iBvA.bNAxtK46WXskUWnDYg57epw+oJ+mJ3OKnxSntbkcD+tPIE3mZ9Iay+sFO60DYWSj8Z7rUqKxeMQ9p04ET0uaUqKJopX.p6OBU8Gh507Ko8BOGjyQoJj8BjzZfa+RjZkHUKQp.LQ3gkgT.PKoTc40vmpheUCSpVGej80ZX5pXKVVk+ccLm571x9tJqKTqv5jZrughUTW9V0Q3.Bi6F4Cwko+hqzinC9bI2cxO9jvi2gULYWqdfUmk53PgogaZo+DZOCP96DNQ.qXATK2m3eyZoZXK2+MqkUJFKI1wFTJsfogtSScgjWq8aBij+DVMc8vNuvBrhAILrfMjvjlVGtxDX0cCdXqFONn13hnVnOaZ+B2lTqbIH4.CK34aBBKLg1oPB9y.4LrkwqoPFpKwppNsq1HSuCwINPtkWprxYHAx58kbncoNssYzMW1TTRca9DygADyJIgZN7bnF0PZQsxpIhXpWKfZNbJp4vInl8mO0re.0nVNIjy9mC4TVhblfX.YfZrhlUEDy9SQL66SLfdolooz7MWA8AMoEZUfIWKwEdk3TcnEjV.HbixDdjk8QEVfU.P9UTSlton9QI+UXz7qLz85yDhRbiJgbipURjrUsturU.8gTv6UDnus8fir2x9T.NXg9vOIZihFDE+UiC+SBq.UNVWf8egEL.GVH2KpamkdgsgUgE98VKTThLnubDEVf3LoDQ49DyZIgXBZyEfdPluDatAr929vJBh.usF44YCjhnPeropl.vEzl2brUlqXX3df8.XDzbFCY1EVLAUFw6aCNchEtXI.VqVKY5z7p+tBl2GmwFONYE4CzpI.ohF7NEp39RhyRQPg9.tdRALuQIwjgsNB1Edrsy.MSvHgdSpSGDu8vNHFpZkHpvrcLEqYNQQ9PWs7JIPA1uMI1X2Mkr1w8PanqaRaZCawF1zCaV2JuYdq4TFeSCwqDwKCnrZ0Sl5teCdWoE01wnWu4ZNQtF9.OIp+Qa2ac7O0R+hr5ORGv+6Qni2XVFXz0DFWGcWxQBg3LZjgkIdlCRmsFWP4eBaA.Q9P1NlN1UG1B6RcLoZNE.hfk0q5SsLAqZfepfBNCDP972dTus86t.EhhHaWLZaKn0BSfBTJOCxykuDijSdrkRLWpC2JaAWyg3dNwk4TTIedHI22KekP7ymXA+VMOxjuzkYPkxfI1sAfjHzQDWlVcBIQgt5bIRC2v4JrbmGM3q7OCpH53MK53tDSlqyjREn+w4SBcIE9RQx7P53TKyC+KVuITOMoV875iBVtz9XTVGsNrBC6xgib6W3XrKOaNLJlO8YvkjnmXXQ.c4XfmSQTkYEGZOhOHv0aCKt1OqPrJU.67RfzkEIkDyLSN7r6fpug0Zno1XXEjryPQtubEEDqDk3wOjPGu9ZVf+FGxL1kZ6GL4lga62xGvaIJpT3GVSqwVcN.bHW.R1jsmjcOE1yrklo+APUoJdzSrCqfvOVI9AHE8HmHhitgxN7Gck7EfoPNdT.O3A6vKleDTShFvjqEgSSfR.EXZD00vwzgNzg5BBZ7PdX.PAzu1KxQaAPge1VSAHARPMM7HxTxiH2B2kgmMoCLd8P7.CCjTcsRjvSxhAbKrOUxO2CA6nw7yPyGArSQSI+JDoSQyquMPPhiK6FKqLiyHqR03L5R5A0Pf0fopm2TYrW2l0lBcP8Ufzb5Ug8c0fIxb683zIlayBEI+w+HL8NX9GeFK4q+ZxWF+bYb9pC0aji0cPoB1mxp0Rcfg6Nzt.B0KDnfWTXAIHCPiMtVCbfJj04yjH2lfrJzHSjpFZ74Lef7kIbHEyPi1g3DRVAkXi2yYcL1y.8qYRrNApfjRv2y2nXHi7lpXS3UV3sjuwbo5bmv9a68ar8i3rvPjcW1PCTNqTnCXBRfCDjFMn.sxOsvpir7bcgUmaKMD3747Lk9A3gzaGpz7JCSSXFDsyHXxJJsQyHr2BIXJXa1nCsBZMrYTvF6XhtwI7iRGmEfJ+AmeKof0IEIKSviSjTf8sgXp.dF1Z37a9j47GQ6nMxkeDzydhQzCLF5C7rlgYsPQJ4goTLYNmS7U3fStA4V0KhbwxBgdnz.3UGn40eotl11NhFcCNJKtLh6uhKzD9xf4iPmCdatIaEAcM0PyzhUSxc0ECqGm0D3If4XKXlR9PzPeI.FnU96uuf+jOYGo9Ehc+d.enMXkq.i1VXavNk9BX2+CQcrB8LaPYYKFMCzoE6UegKQW79iUKQNlrH+XMwAfehYLpXSuBHenn3nllYokYfMeddWawe4y6PAEYp9Vi28Dv58dvrP8R9djvNRavPvw68rc9lQZfoVms.mTtbAWM3O9AjE+HVTLdruPFDaumRLe95H3jtf16I1a9LnSVGunZfnWLB7gfMFrNf2w9TJvDYuxU7c7MA4c.LUxnEEbFqGCMdiZ.Wi0ggLuyTDecFWvS4ZWLhfSB3Qf.h0umubiuBeVXi742IrVVfxgeMKvppfrln1JuuTKdOqUnLOcB4YC9ZDbF1MIGOgRkr.+RKuuQvwiHCoIUBjD+bI2hglf5zmh1ekLDguSPvv8IP6QigL6Rd1IvtD2mvu6tA1IQqeL09apVrXfwjXVGKjqzxXYfEwKKODrm4ujxFVRq.gaDOLiIWkC6Ua5JLxMwFKmZkMxFKY9pYKmQ1bJtTZIKghJA6mDlADtkBLkKrHuHNhQmL98.TkWgR6YY+U3Vg4KagmNbgaibmif0ZerPnwKYGvXNuLbDcnmPcb4d+iq1b64ynqd5PPMMr+XjnA.W06PLH+VoY32DyYwE4JuHMwoalwimyGZVtQQC1dPAtilWArzYAQD..N7o3KEJllkjPProaGjWPc6HghHN9jFwik7WbInaJaL27MXHCFv.EsKCIaxVHFrzroX8kmj0Gx3+g.6YFfSfJ7EDA1SH.DrjcSFu.R1C3DR2J9NCmnkKV44xtzXNxPCX155uOFuy7cB.Co3xMTgXpA6AEWZku2gv9k76HU48Lic9BN67EvXWA9wW8ULn1CKHiSt8FrnyUlMOy.oxxOnxx4HIOKz0fcvqbP3cPrs.d178eHdOBQW0Q3dOLbsn8zPO13t0lpt.LKC6XisquaG5wUYZkC1tWzNxMtALTcY9aF.OYKI.sNAWCTACbwh2fnVAP.t9uvLtSfxmEf.0JqgqjvBWEQYAaUvJ3hSqfUzfabVxDmnVXw7MDgnisxAfg5uH.h23gT2Idep3cthw+EdIKwb6VR3hsjr+wRxtoJEwcQoHVxKoD0tZoolyhuY8fE.D4UAGAWS7lfmw8zkcvDScrKBkjCnttZ8nKYzyx1gxVfLaoSEirkQKTv4WUnOvt+wrqjavguhm5YzSAXhiugKgrJhB4HG1pUj8cF+pGke0LSr95oV1n+g0L0pFOmwXBJn3r5W+MHyVdNxLFMnoCEuzcOBnK9djUYaEOldji1vytcRXlGWJqGrP9HGARA9Z0YJ1y4VWOWIcxjjmqXjaRbRAYXt2QhOOWVTYjEMiyvHghhy9.cMyu9aqqY94bShCtx4Y+IBDBPwicKP+4haAZ3cMJigNdMPYadNCi.BuVsKsAd64xj86yUu1Rua9vQaxf3gw.wLYhBwVasI78d6.e8hlvWMwzVO.R2sOl9gSj9.L8qePz5yZ+IrzP+8l.w8iAhkj4hlOyr1sZWckuY0w6C+SC7wEa16k2esseRuWNtgmd6Gr3qghVcrwVe6nFMd3QqcquCZ0pauqm9qafsZQVZimY9rSa.Pr6hxbwqxg3mGAhB3wNV2IgW4Mlpw+TQi8uGP9MGO43ootj0bkb99flrG9w0mI54uZdV6ymSLOdZMfjz7qmCMNbwZ6mjichHuAMVhq+Y4BNNkKVG.DNeYHWLv+o43V1uXs9yyI6BMl93hDTKnYIwqDExNQFlNEuF533M1+A9Ur.Z+0KHfx.VnOb8+q+W9mAZmhI+BeyDRW5BYJv+RuLg9X.9TRjUon3qx7vWV+jb78ONW70bi3vWHH1CWR.NjY4Bz.X+IIxRUTXqGKrmDXcYe9OiCDWYBPnbt1hXM6eWVtFG8J3bWIJmiHRxtcMXFmJxHjFpLWlKyx2jJhy01WT3VwGK4x9EyGG+54hiRavVldlrmjaskUUpC+UC9qJ7WE3OU1eU1A+RAu++3CswmTvq8O9.lZME1s8GepM6QE1k7m8Xa1yJr61O6w1rmYe0NhH6SSlI7nLhlgLh7IiQHH3mlis8HkmNTA2.iRvthTB1RjR39gTB2Ljh7NgThtMnHzy0SfCknDiUxnfjMHB2NrQncVI072ZifuyonCwu9MeHTRjKrnCyukYVS91DFpU+WV2cT2tFmhKS8qxfWhRLB1h6RTdwmA+WVOYTPnOzn32XN3++d84XJ5+IpSlqkbSQISpF30lg2+02IZNS3aO5HkTEnOdiO0XCLtqzbpPSGL0YfuIucsNgZBqcgg2eNrXElBmetQCQtCrsrG121xni7RIdB0CYnTGY5HVhaSOOzUbPN+hMdB0jpIGOk+lM12vhp4b.ahyr4KWMYapLYwCdrxtuHGGtD1cv9ipXL9S3vVI2gfPpCN5Hf+kAIIAji54i1m5RaqwfSnHcOP763gMJLucncLNhZFUvLc.JegELuUBh5q92lAQ8SrGg29tCzfYhnAMLVVsGANZv2lqE0z0eYphzk8sp1hZoyRfV0EEp5uvZrPU+BunApckORBTaX6CeLEn1ILfma.yCOwf9pyw990939+rajfXwtxaPrX+uTXNwhcZDJmFgxoQnbZDJmFgxoQnbZDJmFgxoQnbZDJmFgxoQnbZDJmFgxoQnbZDJmFgxoQn7++OBkA98zSLC3Whf9wvsoHnawYkQhVW1rlvxiD1PS1M7wcptGZDfxzPkNMToSCU5zPkNMToSCU5zPkNMToSCU5zPkNMToSCU5zPkNMToSkkogJcZnRmFpzogJcZnRmFpzu29+HWW1vidUQf89mxcq5K8g9ykMPp+w+IIh4jiWr0Vcrdw2t2KF7xUOt4So0e1Vu5wsGs2qWzVaPyAmNhtUmU5s8Cew9s6X0rgcs9acr6yZ7v1O5jCratoYki25Uc+FsGty20XM6li6W1ZqZs1avCewK7bF1Dzpe4Vad+MG+vWeqlZuDZuq2V6sR0ags+gNMurgbcDIyAi2eaVHVu51.e5jvPptNFB0d7zHKTTd6pqrIODraAM5UM9GLe18VzBp5pFu796dZCnk6IGB1wl14965s5X81UOswkI3rW6xEb1pW5fyNyF+sXvYuw+wq+yqmFb1mevO+AH3rku+BSLQI.2e1e8Dz1Igb9zOTAycR.WZPdmFj2oA4cZPdmFj2oA48kMHuu3QY2ENvtqjFX2+UcfcWIMvtSCr62NA186iwXfVGG6+PG9l6vIqeJKGftszXAzctCvzD0o2NG3Cy3OzoSztZpFV4h1vpWzFV6h1vUtnMr9EsgqdQa3ZmeCwfIeyQd1C3SYyj4fl6x19c1r7a9Fa1Ql+OPAy6jD
-
@ulrik Thanks for this, definitely a pointer in the right direction. I'll have a proper play around with it tomorrow :)