HISE Logo Forum
    • Categories
    • Register
    • Login

    Some basic questions

    Scheduled Pinned Locked Moved Scripting
    74 Posts 4 Posters 21.8k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Christoph HartC
      Christoph Hart
      last edited by

      Ah, OK now it all comes back to me :)

      But I have this weird feeling that the EVENT_ID system is more suited for the KONTAKT architecture and I don't know if imposing this system on HISE would be smart.

      For example there are no artificial notes. You simply generate notes or ignore notes and every processor gets the messages that the previous processors created / deleted.
      The next conceptual difference is that due to the modularity of this system, the ScriptProcessor cannot know which voices its messages are going to start (it only manipulates the incoming MIDI buffer), so adding functionality like changing pitch values of a started note by scripting would need some weird loopback system which seems a little hacky to me.

      I'd rather add more specialised Modulators that can be controlled by a script than adding the functionality to scripting because it raises the reusability of those modules and feels somehow cleaner for me.

      I would suggest we take a look at the bigger picture in order to find out what behaviour (on the highest level) you need. For example why would you want to know "which note to turn off if the same key has been pressed twice and both notes are still sounding"? I came pretty far by either killing the old note in the new note on or limit the number of voices with the "Voice Amount" property.

      1 Reply Last reply Reply Quote 0
      • d.healeyD
        d.healey
        last edited by

        Yes, coming up with an alternative way to accomplish the same tasks in HISE sounds good. I've been trying to think of some more specific examples where I use event IDs:

        My main use for them at the moment is for a artificial legato and glide/portamento feature which relies on cross fading two notes and changing their pitches over time (in a loop). So that as the two notes cross fade their tunings also overlap until the note that fades out is tuned to the new note's starting tuning, and the new note's destination tuning is whatever key has been played - kind of hard to explain but this was used in the famous SIPS and WIPS KSP scripts to achieve a musical sounding legato effect.

        In my true legato scripts I always turn off the old note before playing a new one (to prevent hanging notes) and some instruments I've worked on have same note legato transitions and the intervals are mapped to the same keys as the sustain notes (but in different groups) so I could end up with three samples triggering for one note but I only want to hear a max of two at a time (during cross fades) so I need to be able to turn the old ones off using their ID - if there are release samples too then things get more complex.

        Libre Wave - Freedom respecting instruments and effects
        My Patreon - HISE tutorials
        YouTube Channel - Public HISE tutorials

        1 Reply Last reply Reply Quote 0
        • Christoph HartC
          Christoph Hart
          last edited by

          
           <processor type="SynthChain" id="PortamentoTest" bypassed="0" gain="0.47315123677253723" balance="0" voicelimit="64" killfadetime="20" iconcolour="0" packagename="" views="32.rk1bzA.....A.........DC....a..............." currentview="-1"><editorstates bodyshown="1" visible="1" solo="0" folded="0"><childprocessors><processor type="MidiProcessorChain" id="Midi Processor" bypassed="0">
                <editorstates bodyshown="1" visible="0" solo="0" folded="1">
                </editorstates></processor>
              <processor type="ModulatorChain" id="GainModulation" bypassed="0" intensity="1">
                <editorstates bodyshown="1" visible="0" solo="0" folded="1">
                </editorstates></processor>
              <processor type="ModulatorChain" id="PitchModulation" bypassed="1" intensity="1">
                <editorstates bodyshown="1" visible="0" solo="0" folded="1">
                </editorstates></processor>
              <processor type="EffectChain" id="FX" bypassed="0">
                <editorstates bodyshown="1" visible="0" solo="0" folded="1">
                </editorstates></processor>
              <processor type="SineSynth" id="Sine Wave Generator" bypassed="0" gain="1" balance="0" voicelimit="1" killfadetime="50" iconcolour="0" octavetranspose="0" semitones="0" usefreqratio="0" coarsefreqratio="1" finefreqratio="0" saturationamount="0">
                <editorstates bodyshown="1" visible="1" solo="0" gainmodulationshown="1"><childprocessors><processor type="MidiProcessorChain" id="Midi Processor" bypassed="0">
                    <editorstates bodyshown="1" visible="1" solo="0" folded="0"><childprocessors><processor type="ScriptProcessor" id="Script Processor" bypassed="0" script="// [onInit]
          // ===============
          // onInit Callback
          
          glideTime = Content.addKnob(&quot;glideTime&quot;, 19, 9);
          // [JSON glideTime]
          Content.setPropertiesFromJSON(&quot;glideTime&quot;, {
            &quot;text&quot;: &quot;Glide Time&quot;,
            &quot;visible&quot;: true,
            &quot;enabled&quot;: true,
            &quot;x&quot;: 0,
            &quot;y&quot;: 0,
            &quot;width&quot;: 128,
            &quot;height&quot;: 48,
            &quot;min&quot;: 0,
            &quot;max&quot;: 20000,
            &quot;tooltip&quot;: &quot;&quot;,
            &quot;bgColour&quot;: 0,
            &quot;itemColour&quot;: 4294967295,
            &quot;itemColour2&quot;: 4294967295,
            &quot;textColour&quot;: 4294967295,
            &quot;macroControl&quot;: -1,
            &quot;zOrder&quot;: &quot;Normal order&quot;,
            &quot;mode&quot;: &quot;Time&quot;,
            &quot;style&quot;: &quot;Knob&quot;,
            &quot;stepSize&quot;: 1,
            &quot;middlePosition&quot;: 400,
            &quot;suffix&quot;: &quot;&quot;,
            &quot;filmstripImage&quot;: &quot;Use default skin&quot;,
            &quot;numStrips&quot;: 0,
            &quot;isVertical&quot;: true
          });
          // [/JSON glideTime]
          
          GlideEnvelope = Synth.getModulator(&quot;GlideEnvelope&quot;);
          
          var lastNote = 0;
          // [/onInit]
          
          // [onNoteOn]
          // =================
          // onNoteOn Callback
          
          function onNoteOn()
          {
          	if(Synth.isLegatoInterval())
          	{
          		GlideEnvelope.setIntensity(lastNote - Message.getNoteNumber());
          	}
          	else
          	{
          		GlideEnvelope.setIntensity(0);
          	}
          
          	lastNote = Message.getNoteNumber();
          }
          // [/onNoteOn]
          
          // [onNoteOff]
          // ==================
          // onNoteOff Callback
          
          function onNoteOff()
          {
          
          }
          // [/onNoteOff]
          
          // [onController]
          // =====================
          // onController Callback
          
          function onController()
          {
          
          }
          // [/onController]
          
          // [onTimer]
          // ================
          // onTimer Callback
          
          function onTimer()
          {
          
          }
          // [/onTimer]
          
          // [onControl]
          // ==================
          // onControl Callback
          
          function onControl(number, value)
          {
          	GlideEnvelope.setAttribute(GlideEnvelope.Attack, value);
          }
          // [/onControl]
          
          ">
                        <editorstates bodyshown="1" visible="1" solo="0" oninitopen="0" onnoteonopen="0" onnoteoffopen="0" oncontrolleropen="0" oncontrolopen="0" ontimeropen="0" contentshown="1">
                        </editorstates></processor></childprocessors></editorstates> </processor>
                  <processor type="ModulatorChain" id="GainModulation" bypassed="0" intensity="1">
                    <editorstates bodyshown="1" visible="0" solo="0"><childprocessors><processor type="SimpleEnvelope" id="DefaultEnvelope" bypassed="0" intensity="1" attack="38" release="58">
                        <editorstates bodyshown="1" visible="1" solo="0"><childprocessors><processor type="ModulatorChain" id="Attack Time Modulation" bypassed="0" intensity="1">
                            <editorstates bodyshown="1" visible="0" solo="0" folded="1">
                            </editorstates></processor></childprocessors></editorstates> </processor></childprocessors></editorstates> </processor>
                  <processor type="ModulatorChain" id="PitchModulation" bypassed="0" intensity="1">
                    <editorstates bodyshown="1" visible="1" solo="0" folded="0"><childprocessors><processor type="TableEnvelope" id="GlideEnvelope" bypassed="0" intensity="1.1892070770263672" attack="320" release="20" attacktabledata="24..........9C...vO...f+.........vO" releasetabledata="24..........9C...vO...f+.........vO">
                        <editorstates bodyshown="1" visible="1" solo="0"><childprocessors><processor type="ModulatorChain" id="AttackTime Modulation" bypassed="0" intensity="1">
                            <editorstates bodyshown="1" visible="0" solo="0" folded="1">
                            </editorstates></processor>
                          <processor type="ModulatorChain" id="ReleaseTime Modulation" bypassed="0" intensity="1">
                            <editorstates bodyshown="1" visible="0" solo="0" folded="1">
                            </editorstates></processor></childprocessors></editorstates> </processor></childprocessors></editorstates> </processor>
                  <processor type="EffectChain" id="FX" bypassed="0">
                    <editorstates bodyshown="1" visible="0" solo="0" folded="1">
                    </editorstates></processor></childprocessors></editorstates> </processor></childprocessors> 
            <macro_controls>
              <macro name="Macro 1" value="-2.3040434428601907e+024" midi_cc="-92127378">
              <macro name="Macro 2" value="-418416332451610620" midi_cc="-1090121960">
              <macro name="Macro 3" value="-1.1368151686694912e+022" midi_cc="-2119832504">
              <macro name="Macro 4" value="4.48624021795433e-039" midi_cc="0">
              <macro name="Macro 5" value="0" midi_cc="0">
              <macro name="Macro 6" value="0" midi_cc="0">
              <macro name="Macro 7" value="0" midi_cc="0">
              <macro name="Macro 8" value="0" midi_cc="0"></macro> </macro></macro></macro></macro></macro></macro></macro></macro_controls></editorstates></processor>
          
          

          This patch shows an example of how a table envelope could simulate the glide / portamento effect by controlling the intensity of a table envelope. This is by no means a useable setup for your use case, but it shows how the two modules can be connected to achieve the same behaviour as scripting the fades.

          For your behaviour, you would need to somehow pitch the releasing note and this is not possible with this modulator, but since glide is a pretty common function, I could simply write a custom modulator that does exactly this.

          @2j0kfb8j:

          and the intervals are mapped to the same keys as the sustain notes (but in different groups) so I could end up with three samples triggering for one note

          Well in HISE you would seperate the sample types into different sampler modules and simply write scripts for each type.

          I did some legato interval sampling and I came up with this solution:

          Lets assume the samples have this filename structure, where the first note is the start note and the second note is the target note:

          Sample_C1_C#1.wav
          Sample_C1_D1.wav
          ...
          
          

          Then you would need to create a sampler with 128 groups. The automapper settings map the first note to the group index and the second note to the root note of the sample. So in this case, both samples would go into group 24 (=C1) and get the root note C#1 and D1.

          A ScriptProcessor in this sampler would simply select the group index (= the starting note) in case of a interval :

          if(Synth.isLegatoInterval())
          {
          	Synth.enableRoundRobin(lastNote);
          }
          else
          {
          	Message.ignoreEvent(true);
          }
          
          lastNote = Message.getNoteNumber();
          
          

          This is everything you need to implement true legato samples. You might want to kill the old note and change the attack time of an envelope in the sustain samples between intervals and non-interval notes, but that would be another script in another sampler, so there is no need for checking which event-id causes which voice to start.

          @2j0kfb8j:

          if there are release samples too then things get more complex.

          If you need release samples, you would simply add another sampler with a release trigger module and don't care about the other samplers.

          1 Reply Last reply Reply Quote 0
          • d.healeyD
            d.healey
            last edited by

            This looks promising, how does the fade out work with that true legato script? is it using the ADSR envelope to achieve it?

            A glide modulator would is a very good idea, especially if we can activate it via a CC or key switch (I imaging this is already possible), some control of the parameters (fade time, pitch bend amount etc.) would be useful too. The way I have scripted my glide is that it glides between each sample, so if I were to glide from C1 to E1 it would actually be gliding between the samples C1-C#1, C#1-D1, D1-D#1, D#1-E1, this way it preserves the formants across even full octave glides which is really nice when simulating a trombone slide for instance. I can also put in a little pause at each step of the glide to create effects like trumpet rips or just a more staggered glide.

            Libre Wave - Freedom respecting instruments and effects
            My Patreon - HISE tutorials
            YouTube Channel - Public HISE tutorials

            1 Reply Last reply Reply Quote 0
            • Christoph HartC
              Christoph Hart
              last edited by

              @3415c09g:

              This looks promising, how does the fade out work with that true legato script? is it using the ADSR envelope to achieve it?

              If you call Synth.noteOff() then the envelopes will jump into release fade and will fade out, so yes, this is how it works.

              The kind of glide you described is a little bit more complicated because it involves selecting different samples (which again is in the ScriptProcessor ballpark). I'll think of something here and maybe this might be a reason to add some script fade API calls :)

              1 Reply Last reply Reply Quote 0
              • d.healeyD
                d.healey
                last edited by

                :D this is great! I wish I had more time to play around with this... soon!

                Libre Wave - Freedom respecting instruments and effects
                My Patreon - HISE tutorials
                YouTube Channel - Public HISE tutorials

                1 Reply Last reply Reply Quote 0
                • M
                  MIDIculous
                  last edited by

                  I agree that this feature has to be done. I've been looking a long time for this and it is very rare with mixed results. For synth leads and bass sounds it is invaluable. I do know it is possible as Korg, Roland, and especially Ensoniq keyboards can do this great with samples, but it is an invaluable feature.

                  @d.healey:

                  Yes, coming up with an alternative way to accomplish the same tasks in HISE sounds good. I've been trying to think of some more specific examples where I use event IDs:

                  My main use for them at the moment is for a artificial legato and glide/portamento feature which relies on cross fading two notes and changing their pitches over time (in a loop). So that as the two notes cross fade their tunings also overlap until the note that fades out is tuned to the new note's starting tuning, and the new note's destination tuning is whatever key has been played - kind of hard to explain but this was used in the famous SIPS and WIPS KSP scripts to achieve a musical sounding legato effect.

                  In my true legato scripts I always turn off the old note before playing a new one (to prevent hanging notes) and some instruments I've worked on have same note legato transitions and the intervals are mapped to the same keys as the sustain notes (but in different groups) so I could end up with three samples triggering for one note but I only want to hear a max of two at a time (during cross fades) so I need to be able to turn the old ones off using their ID - if there are release samples too then things get more complex.

                  1 Reply Last reply Reply Quote 0
                  • d.healeyD
                    d.healey
                    last edited by

                    Hi, it seems you've made great progress with HISE since I last checked in! What's the latest with multi-mic sample sets?

                    Libre Wave - Freedom respecting instruments and effects
                    My Patreon - HISE tutorials
                    YouTube Channel - Public HISE tutorials

                    1 Reply Last reply Reply Quote 0
                    • Christoph HartC
                      Christoph Hart
                      last edited by

                      Sorry for the late response, it got a bit quiet around here :)

                      Multimic samples are implemented, here is a blog post that describes the procedure:

                      http://hise.audio/blog/posts/handling-multi-channel-samples

                      1 Reply Last reply Reply Quote 0
                      • d.healeyD
                        d.healey
                        last edited by

                        Thanks, it looks pretty comprehensive. I'll have to test it out

                        Libre Wave - Freedom respecting instruments and effects
                        My Patreon - HISE tutorials
                        YouTube Channel - Public HISE tutorials

                        1 Reply Last reply Reply Quote 0
                        • d.healeyD
                          d.healey
                          last edited by

                          Can the individual samples of a multi-mic sample have their start position offset?

                          What I'm thinking of here is if I record an instrument with close, stage, and far mics, they are going to be offset slightly with the mics farthest away the most delayed. When all mics are active this is fine but if, lets say, all the mics except the far mics are purged then there could be a noticeable delay between pressing the key and the start of the sample. So in this situation is might be nice for the user to be able to shift the start position of the sample.

                          Libre Wave - Freedom respecting instruments and effects
                          My Patreon - HISE tutorials
                          YouTube Channel - Public HISE tutorials

                          1 Reply Last reply Reply Quote 0
                          • Christoph HartC
                            Christoph Hart
                            last edited by

                            I don't think this is practical. Moving the sample start means resetting all preload buffers (the beginning of the sample that resides in memory until the hard drive can fetch the rest).

                            If you really care about this delay, you could remove a fixed amount from the far sample (so that it is "in sync" with the close mic) and introduce a artificial delay using the delay FX, which can be altered on the fly.

                            1 Reply Last reply Reply Quote 0
                            • d.healeyD
                              d.healey
                              last edited by

                              Ah that sounds like a workable solution

                              Libre Wave - Freedom respecting instruments and effects
                              My Patreon - HISE tutorials
                              YouTube Channel - Public HISE tutorials

                              1 Reply Last reply Reply Quote 0
                              • LevitanusL
                                Levitanus
                                last edited by

                                What is about globals? I mean are they global for unique plugin or for any plugin in the project?
                                Generally, in the any future would be grate to have both separately, but now I need only to know :)

                                1 Reply Last reply Reply Quote 0
                                • Christoph HartC
                                  Christoph Hart
                                  last edited by

                                  Globals are only accessible in one plugin. Making shared stuff across different plugins in a DAW is a source of constant trouble so I wouldn't bother with this...

                                  1 Reply Last reply Reply Quote 1
                                  • d.healeyD
                                    d.healey
                                    last edited by

                                    Might be possible in the HISE player though, no?

                                    Libre Wave - Freedom respecting instruments and effects
                                    My Patreon - HISE tutorials
                                    YouTube Channel - Public HISE tutorials

                                    1 Reply Last reply Reply Quote 0
                                    • LevitanusL
                                      Levitanus
                                      last edited by

                                      i'm trying to understand some basic concepts and can't assume, where I'm wrong here:
                                      Here I'm trying to implement waitting, and expect that note would be delayed by 1 second but it isn't at all...

                                      <?xml version="1.0" encoding="UTF-8"?>
                                      
                                      <Processor Type="ScriptProcessor" ID="Script Processor6" Bypassed="1" Script="Globals.interval = 2;&#13;&#10;Globals.attack = false;&#13;&#10;Globals.legato = false;&#13;&#10;Globals.glissando = false;&#13;&#10;Globals.sus = false;&#13;&#10;&#13;&#10;var note = 0;&#13;&#10;var velocity = 0;&#13;&#10;&#13;&#10;var newnote = 0;&#13;&#10;var lastnote = 0;&#13;&#10;var i = 0;&#13;&#10;var prev_note = 0;&#13;&#10;var temp = 0;&#13;&#10;var rel_off = 0;&#13;&#10;var fading = 0;&#13;&#10;var fade_id = 0;&#13;&#10;var exit = 0;&#13;&#10;&#13;&#10;var wait = {&#13;&#10;&#9;ms:0,&#13;&#10;&#9;start:1,&#10;};function onNoteOn()&#10;{&#13;&#10;&#9;note = Message.getNoteNumber();&#13;&#10;&#9;velocity = Message.getVelocity();&#13;&#10;&#9;&#13;&#10;&#9;//if (lastnote = 0){&#13;&#10;&#9;&#9;//Globals.attack = 1;&#13;&#10;&#9;&#9;//Globals.sus = 1;&#10;&#9;//}else {&#13;&#10;&#9;&#10;&#9;//};&#13;&#10;&#9;Message.ignoreEvent(true);&#13;&#10;&#9;wait.start = 1;&#13;&#10;&#9;wait.ms = 1000;&#10;}&#10;function onNoteOff()&#10;{&#10;&#9;note = Message.getNoteNumber();&#10;}&#10;function onController()&#10;{&#10;&#9;&#10;}&#10;function onTimer()&#10;{&#10;&#9;if (wait.ms != 0){&#13;&#10;&#9;&#9;if (wait.start == 1){&#13;&#10;&#9;&#9;&#9;wait.ms = Engine.getSamplesForMilliSeconds(wait.ms);&#13;&#10;&#9;&#9;&#9;wait.start = 0;&#10;&#9;&#9;}&#13;&#10;&#9;&#9;if (wait.ms == 1){&#13;&#10;&#9;&#9;&#9;Synth.playNote(note, velocity);&#10;&#9;&#9;}&#13;&#10;&#9;&#9;wait.ms -= 1;&#10;&#9;};&#10;};&#10;function onControl(number, value)&#10;{&#10;&#9;&#10;}&#10;">
                                        <EditorStates BodyShown="1" Visible="1" Solo="0" contentShown="0" onInitOpen="0"
                                                      onNoteOnOpen="0" onNoteOffOpen="0" onControllerOpen="0" onTimerOpen="1"
                                                      onControlOpen="0"/>
                                        <ChildProcessors/>
                                        <Content/>
                                      </Processor>
                                      
                                      1 Reply Last reply Reply Quote 0
                                      • d.healeyD
                                        d.healey
                                        last edited by d.healey

                                        Well I'm not 100% sure what you're trying to do but you can't use the timer without starting it :) If you just want to delay note ons you might find what you need in my humaniser script - http://forum.hise.audio/topic/151/humaniser

                                        Message.delayEvent(Engine.getSamplesForMilliSeconds(randNoteOnDelay));

                                        Libre Wave - Freedom respecting instruments and effects
                                        My Patreon - HISE tutorials
                                        YouTube Channel - Public HISE tutorials

                                        1 Reply Last reply Reply Quote 1
                                        • LevitanusL
                                          Levitanus
                                          last edited by

                                          just want to delay note

                                          no, it's just smple visible action for debugging)))

                                          use the timer without starting it

                                          ahhh))) Thakns

                                          1 Reply Last reply Reply Quote 0
                                          • LevitanusL
                                            Levitanus
                                            last edited by

                                            what the difference between playNote and addNoteOn?

                                            1 Reply Last reply Reply Quote 0
                                            • First post
                                              Last post

                                            11

                                            Online

                                            1.8k

                                            Users

                                            12.1k

                                            Topics

                                            104.9k

                                            Posts