• Zero-effort sustain controller

    6
    1 Votes
    6 Posts
    2k Views
    d.healeyD

    I think most samplers respond to the sustain pedal correctly by default, I'm not sure what you'd put on the UI for this, maybe a sustain pedal on/off indicator? Seems a little unnecessary though and would just take up space. Probably best to just mention it in the manual if it isn't already.

  • Retrigger On Release

    2
    1 Votes
    2 Posts
    791 Views
    Christoph HartC

    Nice. I have nothing to add about the functionality - it pretty much says what it does :) However I'd like to propose another way of posting these kind of snippets.

    Post only the script (Edit -> Save Script to clipboard) with Javascript syntax highlighting (you can use ```javascript for the start tag to enable Javascript syntax highlighting). /** * Auto Retrigger on Release * Author: David Healey * Date: * Modified: * License: GPLv3 - https://www.gnu.org/licenses/gpl-3.0.en.html */ //INIT Content.setHeight(50); const var velocities = Engine.createMidiList(); const var btnEnable = Content.addButton("Enable", 0, 10); const var cmbCC = Content.addComboBox("CC Trigger", 150, 10); for (i = 0; i < 128; i++) { cmbCC.addItem(i); } //FUNCTIONS //CALLBACKS function onNoteOn() { velocities.setValue(Message.getNoteNumber(), Message.getVelocity()); } function onNoteOff() { if (btnEnable.getValue()) { Synth.playNote(Message.getNoteNumber(), velocities.getValue(Message.getNoteNumber())); } } function onController() { if (Message.getControllerNumber() == cmbCC.getValue()-1) { Message.getControllerValue() > 64 ? btnEnable.setValue(1) : btnEnable.setValue(0); } } function onTimer() { } function onControl(number, value) { } Then you can add an example patch as HiseSnippet that demonstrates the behaviour. This is a sine generator with an AHDSR Envelope (important because you'll get stuck notes otherwise!): HiseSnippet 1320.3oc4XskbaaCEkzxbZDiiaxLs8aL9KIGaJI+HMiScsdXKakHaqQTws8qTHRHILgDPgDTNpcxlnqftT5RnKkrCZAHHMorYsi5zlXOgeQbu2CvAmKvEfriG0B46S8TTueuoiQJpKoYNkvF0XDDSTZsuh5xZGC8YHOfzT8oig99HaEU0bGJLnleQkvm2uWcnCjXgRLonbFEagZicwrDq+b0WfcbZBsQ8vtohdqpsrnjFTGZ.mO4zJqLFZ8Z3PzIPQXKnoLAiN2WQsr1laX385J8+kZF7mIM2n9l8di30mW2nqqQ3Smydd4VxWUrB77PD1Yb3JpZp+E+QU6.aLi5YxfLDuOWrN0dp4H54D4PeF1G22AIZTQwjyIo4lTGawjW7tRiQXG6NwRnuBuu6jHn4jB5WocL1Feg8Dg8ggN.IHRKspKbczqRZ5UNS5UIC5ojhcKJYGmDT6.GHaVlIxrQNvzYS5sHLDwGyllNy+IktORqClYMJa9tPF7kmn9+luQI+GncvfAHKVBYWTq4O9wMSurjJ2WyDSPgatCIxWG1F7CvIHvgHBxSHpWy16+7+9s2mZw3idOOHweL0elN1D4h6QIBAIw3K8QM8PuoqHIm1dCJzKSWueul74XlXLgr.uvUK0boAD1LqNx8AmRRWaX1MMohOiBEK9InPwbTGS8pa8djlokGdLKwifaeiVWDyCObH+.hSIftHGDjmISyPILkE9sbZkVcUcvpfZALJHAG8BbQNGQ81ArObB1FbDB5flJruOe9sCP7FWiwCvH6cDMZyW.R74dNrS6IaBVGLhwF6uSoRme94FCIAFTugkbjA4WZ3Xm02znrAhXLh45nuZIc8RkZcRqd5MnhBELCeD6HDd3HVgsKW7Y5570r9LvDnGXBxgZgYXjOXWvAjg7kVFVdHNuD4m1XeVgYAzmQNf.4pOO93tGZaWOfwnjBqH8sxZfxqApHFqDjVt8azXVTMnt8o0ousvJbO8jRGGaksiQqOf5AJf4nJ+L.F7cfJa7T9KO9wE0+U87g8nneZwPtEv73emXp27kmznWqSOwTznQs1sqWqwKL0GDPrDKh44lSnLzojBgcRhBHjoyfNAnBGyWLvOi1XHhIB8j.29HuBEWCjxwYRbSKTTNtWt6GLP1+3AfBWHZg.CGhhE0yy8lOr3kwXG3TAp+4QNEMGdCzTPn7u6RbRn5dTGGQ.wzJE9D2w8BX2ckorTbd8JEyKoclPihB78fmrEXujkJIBakhfcxxd4rnrnTaDa4dt5bo.IjpbsQzGwwckJc5eXUOrjKKSEHkzhfYmNFcQa45lXKkUtHUm1Thdj1Z3jIivRLkwIdQaUDmsGENOTVXoqkiJcI23of4kktmlTVUB0izmXnbYzOLBc7FvP7KokrK7R8Q0NUuUbQq+kk6WRx2uPq1Q6a1Mhlguyq4I1YMFcyzrFiwu5di.uIybp99HK3zqXUF7UszFwGtzlOhOKRZaTMr6tvvu2upYfOalKs7S+Q7IRotFxk0vbeXZ3Mbc+qKO+.M4LBDdina22ld4XtJk+a2jcIsv0.2Ez0uTKZ04cBgcYsnMN2Ej1q8C.y844G.1kFvvjgGC42x9s7JU7qpXx+vKKDmIDBxwW7iPVPbtorcYQa4WdQrKG+WRhbVQzVMxYkXmeTFCWnkG8UVxyjE0buWnE97lD9WgxqcrnMnR7ovBswkee7WYYID604pS1H1XtQr4biXq4Fw1yMhmL2H914FwSuFDhO9Q7EctxsdJJ+8GlOHe

    This allows both to check out the functionality faster as well as making the code more readable in the forum - also then you don't need to specify the license since it's already in the code - DRY :)

  • Zimmer Bend

    2
    1 Votes
    2 Posts
    1k Views
    Christoph HartC

    Amazing, the cluster sound when used with the sines that go both up and down really gives that Joker Theme vibe (you just need to replace the sines with cello samples and run it through a guitar amp :)

  • Random, Cycle, Synthetic, Hybrid Round Robin

    13
    1 Votes
    13 Posts
    3k Views
    d.healeyD

    Version 3.0: Major revision.

    Incorporated Christoph's randomising system. Added namespace for RRTypes Removed random no repeat mode - I could see no point in keeping it when we have the random full cycle Aimed for simpler code and lower CPU usage so the RR is no longer per note it is for the whole keyboard. Reset timer is still per note though CPU usage of on note callback is now around 0.60 on average on my system (before it was running up to 3.5!) Added sample range knob for synth and hybrid modes. This is used to set how far from the played note the sample borrowed modes will take samples from. So setting it to 1 means the samples 1 down and one up from the played note will be used, as well as the actual note's sample. /** * Multi-Round Robin script v3.2 * Author: David Healey, Christoph Hart * Date: 07/01/2017 * Modified: 20/02/2017 * License: GPLv3 - https://www.gnu.org/licenses/gpl-3.0.en.html */ //INIT reg noteNumber; reg groupList = []; reg groupIndex; reg offsetList = []; reg offsetIndex; reg offset; namespace RRTypes { const var OFF = 1; const var REAL = 2; const var SYNTH = 3; const var HYBRID = 4; }; namespace RRModes { const var CYCLE = 1; const var RANDOM = 2; const var RANDOM_CYCLE = 3; }; const var timer = Engine.createMidiList(); const var excludedIds = "(elease)"; //Regex string of words in sampler IDs to exclude RR from const var samplerNames = Synth.getIdList("Sampler"); //Get the ids of all child samplers const var samplers = []; //Get child samplers for (samplerName in samplerNames) { if (Engine.matchesRegex(samplerName, excludedIds) == true) continue; //Skip excluded IDs samplers.push(Synth.getSampler(samplerName)); //Add sampler to array samplers[samplers.length-1].enableRoundRobin(false); //Disable default RR behaviour } //GUI Content.setHeight(100); //RR Type and Mode Combo Boxes const var cmbType = Content.addComboBox("Type", 0, 10); cmbType.set("items", ["Off", "Real", "Synthetic", "Hybrid"].join("\n")); const var cmbMode = Content.addComboBox("Mode", 150, 10); cmbMode.set("items", ["Cycle", "Random", "Random Full Cycle"].join("\n")); //Number of groups knob const var knbNumGroups = Content.addKnob("Num Groups", 300, 0); knbNumGroups.setRange(1, 100, 1); //Playable Range controls const var knbLowNote = Content.addKnob("Low Note", 450, 0); knbLowNote.setRange(0, 126, 1); const var knbHighNote = Content.addKnob("High Note", 600, 0); knbHighNote.setRange(1, 127, 1); //Reset timeout knob const var knbReset = Content.addKnob("Reset Time", 0, 50); knbReset.setRange(1, 60, 1); knbReset.set("suffix", " Seconds"); //Microtuning knob const var knbMicroTuning = Content.addKnob("Microtuning", 150, 50); knbMicroTuning.setRange(0, 100, 0.1); //Borrowed Sample Range const var knbSampleRange = Content.addKnob("Sample Range", 300, 50); knbSampleRange.setRange(1, 12, 1); //----------------- //FUNCTIONS /** Swaps two elements in an array randomly. */ inline function swapRandomly(arr) { local firstIndex = Math.randInt(0, arr.length); local secondIndex = Math.randInt(0, arr.length); local temp = arr[firstIndex]; arr[firstIndex] = arr[secondIndex]; arr[secondIndex] = temp; } /** Swaps every element in the array. */ inline function swapEntirely(arr) { local i = 0; while(++i < arr.length) swapRandomly(arr); } inline function resetGroupList(count) { local i; for (i = 0; i < count; i++) { groupList[i] = i; } } inline function resetOffsetList(count) { local i; //Build array going from -value to +value+1 (always need to account for 0) for (i = 0; i < count*2+1; i++) { offsetList[i] = i-count; } } //CALLBACKS function onNoteOn() { noteNumber = Message.getNoteNumber(); if (cmbType.getValue() != RRTypes.OFF && noteNumber >= knbLowNote.getValue() && noteNumber <= knbHighNote.getValue()) { //Group based RR if (knbNumGroups.getValue() > 1 && (cmbType.getValue() == RRTypes.REAL || cmbType.getValue() == RRTypes.HYBRID)) //Real or Hybrid RR { switch (cmbMode.getValue()) { case RRModes.CYCLE: groupIndex = (groupIndex + 1) % groupList.length; break; case RRModes.RANDOM: groupIndex = Math.floor(Math.random() * groupList.length); break; case RRModes.RANDOM_CYCLE: if (++groupIndex >= groupList.length) { groupIndex = 0; swapEntirely(groupList); } break; } } //Reset groupIndex to 0 if only one group is present or the reset time has elapsed if (knbNumGroups.getValue() == 1 || Engine.getUptime() - timer.getValue(noteNumber) > knbReset.getValue()) { groupIndex = 0; resetGroupList(knbNumGroups.getValue()); } //Set active group for each sampler if (samplers.length > 0) { for (sampler in samplers) { sampler.setActiveGroup(1 + groupList[groupIndex]); } } //Synthetic sample borrowed RR if (cmbType.getValue() == RRTypes.SYNTH || cmbType.getValue() == RRTypes.HYBRID) //Synthetic or Hybrid RR { switch (cmbMode.getValue()) { case RRModes.CYCLE: offsetIndex = (offsetIndex + 1) % offsetList.length; break; case RRModes.RANDOM: offsetIndex = Math.floor(Math.random() * offsetList.length); break; case RRModes.RANDOM_CYCLE: if (++offsetIndex >= offsetList.length) { offsetIndex = 0; swapEntirely(offsetList); } break; } //If reset time has elapsed, reset index if (Engine.getUptime() - timer.getValue(noteNumber) > knbReset.getValue()) { offsetIndex = parseInt(Math.floor(offsetList.length / 2)); resetOffsetList(knbSampleRange.getValue()); } //If the played note + the offset are within the playable range if (noteNumber + offsetList[offsetIndex] > knbLowNote.getValue() && noteNumber + offsetList[offsetIndex] < knbHighNote.getValue()) { Message.setTransposeAmount(offsetList[offsetIndex]); //Transpose the note Message.setCoarseDetune(-offsetList[offsetIndex]); //Use coarse detune so setting can be picked up by later scripts } } //Apply random microtuning, if any if (knbMicroTuning.getValue() > 0) { Message.setFineDetune(Math.random() * (knbMicroTuning.getValue() - -knbMicroTuning.getValue() + 1) + -knbMicroTuning.getValue()); } timer.setValue(noteNumber, Engine.getUptime()); //Record time this note was triggered } } function onNoteOff() { } function onController() { } function onTimer() { } function onControl(number, value) { switch(number) { case knbNumGroups: groupList = []; resetGroupList(value); break; case knbSampleRange: offsetList = []; resetOffsetList(value); break; case cmbType: switch (value) { case RRTypes.REAL: knbSampleRange.set("visible", false); if (knbNumGroups.getValue() == 1) { number.setValue(RRTypes.OFF); } break; case RRTypes.SYNTH: knbSampleRange.set("visible", true); break; case RRTypes.HYBRID: knbSampleRange.set("visible", true); if (knbNumGroups.getValue() == 1) //If there are no RR groups then Hybrid defaults to synth { number.setValue(RRTypes.SYNTH); } break; } break; case cmbMode: resetGroupList(knbNumGroups.getValue()); resetOffsetList(knbSampleRange.getValue()); offsetIndex = 0; groupIndex = 0; break; } }
  • Round Robin + Humaniser + Velocity Curve Master Control

    1
    0 Votes
    1 Posts
    730 Views
    No one has replied
  • Release triggers

    4
    0 Votes
    4 Posts
    1k Views
    d.healeyD

    Here's my updated release trigger script. I've added a mute button so that release triggers can be disabled. I've also added a legato button: when this is enabled release triggers won't be played for each note of a legato phrase, they will only play when the last key is lifted.

    /** * Release Trigger v1.0.1 * Author: Christoph Hart, David Healey * Date: 09/01/2017 * Modified: 30/06/2017 */ //Includes //Init Content.setHeight(175); Content.setName("Release Trigger"); reg attenuationLevel = 1.0; reg timeIndex = 0; reg time; const var velocityValues = Engine.createMidiList(); const var lengthValues = Engine.createMidiList(); const var btnMute = Content.addButton("btnMute", 0, 10); btnMute.set("text", "Mute"); const var btnLegato = Content.addButton("btnLegato", 150, 10); btnLegato.set("text", "Legato"); btnLegato.set("tooltip", "When enabled release samples will only be triggered when no other keys are held."); const var btnAttenuate = Content.addButton("Attenuate", 300, 10); const var knbTime = Content.addKnob("Time", 450, 0); knbTime.setRange(0, 20, 0.1); const var tblTime = Content.addTable("tblTime", 140, 0); tblTime.setPosition(0, 60, 575, 100); for(i = 0; i < 127; i++) { velocityValues.setValue(i, 0); lengthValues.setValue(i, 0.0); } //Functions //Callbacks function onNoteOn() { if (!btnMute.getValue()) { Message.ignoreEvent(true); velocityValues.setValue(Message.getNoteNumber(), Message.getVelocity()); lengthValues.setValue(Message.getNoteNumber(), Engine.getUptime()); } } function onNoteOff() { //If not muted and a velocity was recorded in the note on callback - this prevents release triggering for the wrong articulation if (!btnMute.getValue() && velocityValues.getValue(Message.getNoteNumber()) > 0) { Message.ignoreEvent(true); //Only play release triggers if legato is disabled or legato is enabled and no keys are held if (btnLegato.getValue() == 0 || (btnLegato.getValue() == 1 && Globals.keyCount == 0)) { //Calculate attenuation if(btnAttenuate.getValue() == 1) { time = Engine.getUptime() - lengthValues.getValue(Message.getNoteNumber()); timeIndex = (time / (knbTime.getValue()) * 127.0); if (timeIndex > 127) timeIndex = 127; if (timeIndex < 0) timeIndex = 0; attenuationLevel = /*velocityValues.getValue(Message.getNoteNumber()) **/ parseInt(tblTime.getTableValue(timeIndex) * 127); } else { attenuationLevel = velocityValues.getValue(Message.getNoteNumber()); } if (attenuationLevel < 1) attenuationLevel = 1; Synth.playNote(Message.getNoteNumber(), attenuationLevel); //Play release note } velocityValues.setValue(Message.getNoteNumber(), 0); //Reset velocity for note } } function onController() { } function onTimer() { } function onControl(number, value) { switch (number) { case btnMute: velocityValues.clear(); lengthValues.clear(); break; case btnAttenuate: knbTime.set("visible", value); tblTime.set("visible", value); break; } }
  • Humaniser

    3
    0 Votes
    3 Posts
    1k Views
    d.healeyD

    Aha that's interesting, I tried with longer note delays and got stuck notes - now I know why :)

    Edit: Here's the revised version.

    <?xml version="1.0" encoding="UTF-8"?> <Processor Type="ScriptProcessor" ID="Humaniser" Bypassed="0" Script="/**&#10; * Humaniser v1.1&#10; * Author: David Healey, Christoph Hart&#10; * Date: 08/01/2017&#10; * License: GPLv3 - https://www.gnu.org/licenses/gpl-3.0.en.html&#10; */&#10;&#10;//Includes &#10;&#10;//Init&#10;Content.setHeight(100);&#10;reg randNoteOnDelay;&#10;reg randNoteOffDelay;&#10;reg randVelocity;&#10;reg randFineTune;&#10;reg randVolume;&#10;reg randCC;&#10;&#10;const var noteOnDelays = Engine.createMidiList();&#10;noteOnDelays.fill(0); // default is -1, so we need to set it to zero.&#10;&#10;const var ccNumbers = [];&#10;&#10;for (i = 0; i &lt; 129; i++)&#10;{&#10;&#9;ccNumbers[i] = i;&#10;}&#10;&#10;//GUI&#10;const var knbNoteOn = Content.addKnob(&quot;Note On&quot;, 0, 0);&#10;knbNoteOn.setRange(0, 100, 0.1);&#10;knbNoteOn.set(&quot;suffix&quot;, &quot;ms&quot;);&#10;knbNoteOn.set(&quot;tooltip&quot;, &quot;Note On: adds random delay (0 ms - 100 ms) to the Note On of each note.&quot;);&#10;&#10;const var knbNoteOff = Content.addKnob(&quot;Note Off&quot;, 150, 0);&#10;knbNoteOff.setRange(0, 100, 0.1);&#10;knbNoteOff.set(&quot;suffix&quot;, &quot;ms&quot;);&#10;knbNoteOff.set(&quot;tooltip&quot;, &quot;Note Off: adds random delay (0 ms - 100 ms) to the Note Off of each note.&quot;);&#10;&#10;const var knbVelocity = Content.addKnob(&quot;Velocity&quot;, 300, 0);&#10;knbVelocity.setRange(0, 100, 1);&#10;knbVelocity.set(&quot;suffix&quot;, &quot;%&quot;);&#10;knbVelocity.set(&quot;tooltip&quot;, &quot;Velocity: adds or subtracts random value in selected +-range of played velocity.&quot;);&#10;&#10;const var knbFineTune = Content.addKnob(&quot;FineTuning&quot;, 450, 0);&#10;knbFineTune.setRange(0, 100, 1);&#10;knbFineTune.set(&quot;tooltip&quot;, &quot;Fine Tuning: detunes each note randomly in the selected +-range - up to 1 semi-tone.&quot;);&#10;&#10;const var knbVolume = Content.addKnob(&quot;Volume&quot;, 600, 0);&#10;knbVolume.setRange(0, 8, 0.1);&#10;knbVolume.set(&quot;suffix&quot;, &quot;dB&quot;);&#10;knbVolume.set(&quot;tooltip&quot;, &quot;Volume: changes the volume of each note randomly from -8db to +8 db.&quot;);&#10;&#10;const var cmbCC1 = Content.addComboBox(&quot;CC 1&quot;, 0, 60);&#10;cmbCC1.set(&quot;items&quot;, ccNumbers.join(&quot;\n&quot;));&#10;cmbCC1.set(&quot;text&quot;, &quot;First CC&quot;);&#10;cmbCC1.set(&quot;tooltip&quot;, &quot;First CC Number: Select a CC number to humaniser.&quot;);&#10;&#10;const var knbCC1 = Content.addKnob(&quot;First CC&quot;, 150, 50);&#10;knbCC1.setRange(0, 100, 1);&#10;knbCC1.set(&quot;suffix&quot;, &quot;%&quot;);&#10;knbCC1.set(&quot;tooltip&quot;, &quot;First CC: adjusts the CC value by a random percentage in the +-range selected.&quot;);&#10;&#10;const var cmbCC2 = Content.addComboBox(&quot;CC 2&quot;, 300, 60);&#10;cmbCC2.set(&quot;items&quot;, ccNumbers.join(&quot;\n&quot;));&#10;cmbCC2.set(&quot;text&quot;, &quot;Second CC&quot;);&#10;cmbCC2.set(&quot;tooltip&quot;, &quot;Second CC Number: Select a CC number to humaniser.&quot;);&#10;&#10;const var knbCC2 = Content.addKnob(&quot;Second CC&quot;, 450, 50);&#10;knbCC2.setRange(0, 100, 1);&#10;knbCC2.set(&quot;suffix&quot;, &quot;%&quot;);&#10;knbCC2.set(&quot;tooltip&quot;, &quot;Second CC: adjusts the CC value by a random percentage in the +-range selected.&quot;);&#10;&#10;//Functions&#10;&#10;//Callbacks&#10;function onNoteOn()&#10;{&#10;&#9;//Note On&#10;&#9;if (knbNoteOn.getValue() &gt; 0)&#10;&#9;{&#10;&#9;&#9;randNoteOnDelay = Math.floor(Math.random() * knbNoteOn.getValue());&#10;&#9;&#9;Message.delayEvent(Engine.getSamplesForMilliSeconds(randNoteOnDelay));&#10;&#9;&#9;noteOnDelays.setValue(Message.getNoteNumber(), randNoteOnDelay);&#10;&#9;}&#10;&#10;&#9;//Velocity&#10;&#9;if (knbVelocity.getValue() &gt; 0)&#10;&#9;{&#10;&#9;&#9;randVelocity = -1;&#10;&#9;&#9;while (randVelocity == -1 || randVelocity &lt; 1 || randVelocity &gt; 127)&#10;&#9;&#9;{&#10;&#9;&#9;&#9;randVelocity = Math.ceil(Message.getVelocity() + ((Math.random() -0.5) * 127) * knbVelocity.getValue() / 100);&#10;&#9;&#9;}&#9;&#9;&#10;&#10;&#9;&#9;Message.setVelocity(randVelocity); //Apply random velocity&#10;&#9;}&#10;&#10;&#9;//Fine Tuning&#10;&#9;if (knbFineTune.getValue() &gt; 0)&#10;&#9;{&#10;&#9;&#9;randFineTune = Math.floor(Math.random() * (knbFineTune.getValue() - -knbFineTune.getValue() + 1)) + -knbFineTune.getValue();&#10;&#9;&#9;Message.setFineDetune(Message.getFineDetune()+randFineTune);&#10;&#9;}&#10;&#10;&#9;//Volume&#10;&#9;if (knbVolume.getValue() &gt; 0)&#10;&#9;{&#10;&#9;&#9;randVolume = Math.random() * (knbVolume.getValue() - -knbVolume.getValue() + 1) + -knbVolume.getValue();&#10;&#9;&#9;Message.setGain(Message.getGain() + randVolume);&#10;&#9;}&#10;}&#10;&#10;function onNoteOff()&#10;{&#10;&#9;//Note Off&#10;&#9;if (knbNoteOff.getValue() &gt; 0)&#10;&#9;{&#10;&#9;&#9;randNoteOffDelay = Math.floor(Math.random() * knbNoteOff.getValue());&#10;&#9;&#9;randNoteOffDelay += noteOnDelays.getValue(Message.getNoteNumber()); //Add any note on delay for this note&#10;&#10;&#9;&#9;Message.delayEvent(Engine.getSamplesForMilliSeconds(randNoteOffDelay));&#10;&#9;}&#10;}&#10;&#10;function onController()&#10;{&#10;&#9;if (Message.getControllerNumber() == cmbCC1.getValue()-1 &amp;&amp; knbCC1.getValue() &gt; 0)&#10;&#9;{&#10;&#9;&#9;randCC = -1;&#10;&#9;&#9;while (randCC == -1 || randCC &lt; 1 || randCC &gt; 127)&#10;&#9;&#9;{&#10;&#9;&#9;&#9;randCC = Math.ceil(Message.getControllerValue() + ((Math.random() -0.5) * 127) * knbCC1.getValue() / 100);&#10;&#9;&#9;}&#9;&#10;&#10;&#9;&#9;Message.setControllerValue(randCC);&#10;&#9;}&#10;&#10;&#9;if (Message.getControllerNumber() == cmbCC2.getValue()-1 &amp;&amp; knbCC2.getValue() &gt; 0)&#10;&#9;{&#10;&#9;&#9;randCC = -1;&#10;&#9;&#9;while (randCC == -1 || randCC &lt; 1 || randCC &gt; 127)&#10;&#9;&#9;{&#10;&#9;&#9;&#9;randCC = Math.ceil(Message.getControllerValue() + ((Math.random() -0.5) * 127) * knbCC2.getValue() / 100);&#10;&#9;&#9;}&#9;&#10;&#10;&#9;&#9;Message.setControllerValue(randCC);&#10;&#9;}&#10;}&#10;&#10;function onTimer()&#10;{&#10;&#9;&#10;}&#10;function onControl(number, value)&#10;{&#10;&#9;&#10;}&#10;"> <EditorStates BodyShown="1" Visible="1" Solo="0" contentShown="1" onInitOpen="0" onNoteOnOpen="0" onNoteOffOpen="0" onControllerOpen="0" onTimerOpen="0" onControlOpen="0"/> <ChildProcessors/> <Content> <Control type="ScriptSlider" id="Note On" value="0"/> <Control type="ScriptSlider" id="Note Off" value="0"/> <Control type="ScriptSlider" id="Velocity" value="0"/> <Control type="ScriptSlider" id="FineTuning" value="0"/> <Control type="ScriptSlider" id="Volume" value="0"/> <Control type="ScriptComboBox" id="CC 1" value="2"/> <Control type="ScriptSlider" id="First CC" value="0"/> <Control type="ScriptComboBox" id="CC 2" value="12"/> <Control type="ScriptSlider" id="Second CC" value="0"/> </Content> </Processor>
  • Scrolling Controls Vertically

    2
    0 Votes
    2 Posts
    929 Views
    Christoph HartC

    Nice. Another way using a Slider as scrollbar:

    HiseSnippet 1063.3ocsV8uaaaCDlxwZXVctXcXO.D9urGbbjbriSVQvZiWxlSWRLpJLFPwPmrDsMQkIMjnRhaPdP2awdC1NpeKWkl3ALA3Dwu6NxO9wSGuwdbahuO2Co7r2sdEAo7MplqYhECWXQYnQ+LR44pWX4KHd3HnSVuxx2m3fTT14Wj.J0phBe96e5DKWKlMICBglvo1jeitjJxP+yW8Fpq6YVNj2QWly6duZjMmMj6xC.9ripNZkk8GslStzR5VEUz0TxM9HEc0861w6iFS+zq6.OtiN+n0SNhzoy0mC+N0HDM44jNcP1AddDlXBDNRQU4efGE0ScnBtmovRPf4bmS3NqMWvugEszSn9zotD4.CjIvoHXzvETWmwIxlOBoTcblHtSjH98pWPcno3Yh42FZ.mEQd4ToRQJUs.kLdHJcF20QNAO.8TxQupQz6Epl1dzUhLKRt8cwnO.6hLhp7WUUGxYBPN63SD+JgNegn4955sdYcMM37yWfu1xCKOpVw8D3iwIta43L1hQba1HwXi13d8ai2+nVuTau8vu+byqtLMx+PK25.bZEwSPI9m4wWJ8qvrbWcMLtwMTGwhF+Ht2AFsCAVDxN.wnmQcs6iWk8JtL00JPb3MAbbAI7kw7TqRp2F2MOwSs8nLO+rDQ8aARpGQ50vq6BDtcw8j9Qarm5O3vHjUVxj6g7kq3L3EvTNoIziobOGhmI8SjrkIB6sVNz.eI5l5StcSl33a6wccmZsg37FFeZyFoFkZiwgswPNwioD4iISIRnem4DQyXInEdWbW8hhRx3TMoXfwvsh2vyiJsHSGL5ar+fA8iLHH2JxLcvfAC5Zz+oJs9h0tRUswD4Vy1xsQjPloYRwoL4R9WXWC6A3W97HogGMEJN56dHZlkhs4Aa3zOKfYKnbFlytjKHWwZ1R6NsZZ2qsokYyJyjjcxSNhWYVk0089Bg0jErbJwqMnOtAjP+nyhAwGebVZVq5Z0fsXsZoaGodzD9FoM7MRGc7OfaJ+2twyjbblqERBj9TZ1QKPcpcOvSnDZwBvZOsBv1QmT4bjyFwnhqVQRGGIxIH5nTwMOTlnlGMTLKwsLnOupOJN6Ap+WI1cvUQX0+mGWm2zkBE.PTn59yTSUbTnPl+VczSXB9JUYV0lwBOe9kOvUfbm.WKQw6Ek8RDa.RUJbyyH4VwmJVmmUawkk5kdYoQYx1SjtuPcLUXunb9VoD9JOG9eluwsdTW8zYyH1hLxVU8re++ZeFaAUdKOPPYyuvR3QuE5x5xfklPIUaBvDFb2ouryqJxTynw5xwRkwjvbzSZKK1ngbrRrQiDinkVPZ5GrixGkM270gH.mXgsHVC5UEFiMRxDk7dIzw0GrskBwt.yKOhtacD6u0Qzaqin+VGwAacDC15HN7KDgr81WGH3Ki9r.g9W.cVOd9A

    Although you could add the scrollbar logic also to the viewport ScriptPanel (and also support mouse wheel scrolling).

  • Understanding HISE

    4
    0 Votes
    4 Posts
    2k Views
    Christoph HartC

    Yeah, I had to get another server for the forum, but I'll migrate back to my original hoster and resolve this DNS mess soon.

    I thought emails worked (I am using a Gmail account for the mails), but I'll investigate.

    Everything you mentioned could be also changed via scripts. I would recommend a JSON file with all instrument definitions which contains the parameters for all envelopes, sample maps / filters, etc.

    Another possibility is to embed everything into your app. In this case you can actually swap out the whole preset on the C++ side by calling MainController::loadPreset().

  • This topic is deleted!

    1
    0 Votes
    1 Posts
    1 Views
    No one has replied
  • How do you purge samples?

    2
    0 Votes
    2 Posts
    831 Views
    Christoph HartC

    To purge a whole sampler is pretty simple (but impossible to know until there is some documentation):

    Sampler = Synth.getChildSynth("Sampler"); Sampler.setAttribute(12, 1); // 12 is the index for purging attribute and '1' is purged ('0' is normal and '2' is disabled)

    I wouldn't call this in a MIDI callback because it blocks the audio processing, but for control callbacks it is perfectly fine.

    You can also purge selected samples within a sampler. This procedure is a bit more complicated and I'll decide the next blog tutorial to it (you can also automap the samples with these API calls).

13

Online

1.9k

Users

10.7k

Topics

93.2k

Posts