HISE Logo Forum
    • Categories
    • Register
    • Login

    Making a Mono Mode

    Scheduled Pinned Locked Moved General Questions
    14 Posts 3 Posters 487 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.
    • CasmatC
      Casmat @d.healey
      last edited by

      @d-healey definitely! I’m now debating between going for the sample switching method of legato vs going for the pitch glide method of legato.. I tried your legato script to see how it’d sound l, but after messing with the controls for a while, when it glides up/down, you can hear all the samples in between and they all play from the start, is there a way on your legato script to make it sound more “glidey” instead of that strumming sound?

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

        @Casmat yeah you need to use a start offset modulator and drop in another script to control it

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

        CasmatC 2 Replies Last reply Reply Quote 0
        • V
          voiceover63
          last edited by

          Test
          https://www.locutortv.com/
          https://www.locutortv.es/

          1 Reply Last reply Reply Quote -1
          • CasmatC
            Casmat @d.healey
            last edited by

            This post is deleted!
            1 Reply Last reply Reply Quote 0
            • CasmatC
              Casmat @d.healey
              last edited by Casmat

              @d-healey revamped mono script:

              /*
              The MIT License (MIT)
              
              Copyright © 2017, 2018, 2019, 2020, 2021, 2022 David Healey
              
              Permission is hereby granted, free of charge, to any person obtaining
              a copy of this file (the “Software”), to deal in the Software without
              restriction, including without limitation the rights to use, copy,
              modify, merge, publish, distribute, sublicense, and/or sell copies of
              the Software, and to permit persons to whom the Software is furnished
              to do so, subject to the following conditions:
              
              The above copyright notice and this permission notice shall be included
              in all copies or substantial portions of the Software.
              
              THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS
              OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
              FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
              THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
              LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
              OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
              */
              
              Content.setWidth(650);
              Content.setHeight(50);
              
              reg lastNote = -1;
              reg retrigger = -1;
              reg eventId;
              reg vel;
              reg eventIdQueue = [];
              reg tempId;
              reg retrigId;
              reg noteNum;
              reg rootNote;
              
              //GUI
              const var bypass = Content.addButton("Bypass", 10, 10);
              
              const var time = Content.addKnob("Time", 160, 0);
              time.setRange(0, 2000, 0.01);
              
              
              inline function onTimeControl(component, value)
              {
              	eventIdQueue = [];
              };
              
              Content.getComponent("Time").setControlCallback(onTimeControl);
              
              
              function onNoteOn()
              {
                  if (!bypass.getValue())
                  {
              		if (!retrigId == undefined) Synth.noteOffByEventId(retrigId);
              		vel = Message.getVelocity();
              		noteNum = Message.getNoteNumber();
              		
              		if(Synth.getNumPressedKeys() == 1) rootNote = Message.getNoteNumber();
              		
              		if (lastNote == -1)
                      {
                          lastNote = Message.getNoteNumber();
                          eventId = Message.makeArtificial();
                          Console.print("Case1");
                      }
                      else
                      {
                          if (time.getValue() > 0 && eventId != -1)
                          {
                              Message.ignoreEvent(true);                
                              Synth.addPitchFade(eventId, time.getValue(), Message.getNoteNumber() - rootNote, 0);                    
                          Console.print("Case2");
                          }
                          else
                          {
                              if (eventId != -1) Synth.noteOffByEventId(eventId);
                                  
                              eventId = Message.makeArtificial();
                              Console.print("Case3");
                          }
                          retrigger = lastNote;
                          lastNote = Message.getNoteNumber();
                      }
              
              	    eventIdQueue.push(
              	    {
              	        "eventId": Message.getEventId(),
              	        "noteNumber": Message.getNoteNumber()
                      });
                  }
              }
              
              
              
              
              function onNoteOff()
              {
                  if (!bypass.getValue())
                  {
                      Message.ignoreEvent(true);
                      
              	    for (id in eventIdQueue)
              	    {
              	        if (time.getValue() == 0)
              	        {
              	            if (id["eventId"] == Message.getEventId() + 1) tempId = id;
              	        }
              	        else
              	        {
              		        if (id["noteNumber"] == Message.getNoteNumber()) tempId = id;
              	        }
                      };
              	    eventIdQueue.remove(tempId);
              	    if (!Synth.isKeyDown(rootNote) && time.getValue() == 0) rootNote = eventIdQueue[0]["noteNumber"];
              	    
                      if (!noteNum == undefined && !Synth.isKeyDown(noteNum) && time.getValue() == 0)
                      {
                          if (!retrigId == undefined) Synth.noteOffByEventId(retrigId);
                          retrigId = undefined;
                      }
                      Console.print(Message.getNoteNumber());
                      Console.print(noteNum);
                      //Console.print(rootNote);
                      if (Message.getNoteNumber() == noteNum && eventIdQueue.length > 0 && time.getValue() == 0)
                      {
                          eventIdQueue.reverse();
                     	    retrigId = Synth.playNote(eventIdQueue[0]["noteNumber"], vel);
                          noteNum = eventIdQueue[0]["noteNumber"];
                          Synth.noteOffByEventId(eventId);
                          eventIdQueue.reverse();
                    	    lastNote = retrigger;
                          retrigger = -1;
                          Console.print("test");
                      }
                      
                      if (eventId != -1)
                      {
                        if (eventIdQueue.length > 0 && time.getValue() > 0)
                        {
              	          eventIdQueue.reverse();
              	          Synth.addPitchFade(eventId, time.getValue(), eventIdQueue[0]["noteNumber"] - rootNote, 0);
              	          noteNum = eventIdQueue[0]["noteNumber"];
              	          eventIdQueue.reverse();
              	          lastNote = retrigger;
              	          //retrigger = -1; --Causes wierd audio glitches since first if statement on the onNote callback is activated
                        }
                        else
                        {
                            Synth.noteOffByEventId(eventId);
                            eventId = -1;
                            Console.print("RAH1");
                        }
                      }
              
                      if (!Synth.getNumPressedKeys())
                      {
                          Synth.noteOffByEventId(eventId);
                          lastNote = -1;
                          Console.print("RAH2");
                      }
                  }
                  else if (eventId != -1 && eventId != undefined)
                  {
                      Synth.noteOffByEventId(eventId);
                      eventId = -1;
                      lastNote = -1;
                      eventIdQueue = [];
                  }
                  /*Console.print("new");
                  for(i in eventIdQueue)
                  {
                  	        Console.print(i);
                  };*/
              }
              
              function onController()
              {
              	
              }
               function onTimer()
              {
              	
              }
               function onControl(number, value)
              {
              	
              }
               
              

              I made some changes to your script to get last note retriggering working! Most everything works, except for one thing, I tried finding the cause of the issue (you may see some console print statements scattered), but unsuccessful. Basically, the problem occurs when you try to "glide" from two notes. Lets say you press C, then while holding C, you press E, E plays, but as soon as you let go of C, E stops playing.

                  if (Message.getNoteNumber() == noteNum && eventIdQueue.length > 0 && time.getValue() == 0)
                  //...
                  if (eventIdQueue.length > 0 && time.getValue() > 0)
              

              I think i traced the problem to these if statements where the first one does what I mentioned above, but when I deleted the Message.getNoteNumber() == noteNum line (the second if statement), Instead of E stopping, It gets retriggered. Any ideas to fix?

              Edit: there's also probably a lot of unnecessary code since i didn't replace most of your existing code which may/may not be functional due to my changes... I only removed the lastTuning variable since it was the one causing the pitch issues, all to fix was just add a rootNote var

              Thanks!

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

                @Casmat

                eventIdQueue.push(
                {
                "eventId": Message.getEventId(),
                "noteNumber": Message.getNoteNumber()

                This kind of thing is slow/inefficient. Use a midi list:
                ml.setValue(Message.getNoteNumber(), Message.getEventId());

                if (!noteNum == undefined

                This logic is confusing, do you want to check if noteNum is defined or if it's not defined?

                You probably want to use if (!isDefined(noteNum))

                Same here

                if (!retrigId == undefined)

                Don't put if statements on a single line, it makes the intent of the code less clear at a glance.

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

                CasmatC 1 Reply Last reply Reply Quote 0
                • CasmatC
                  Casmat @d.healey
                  last edited by

                  @d-healey I’m stuck trying to figure out how I can use a midi list in my case.. I tried to read the docs but there’s little info, how can I use the midi list to replicate the array system I had? In the previous system, I had stored the event Id and note number in an object that is created for each note on and deleted on the note off. The objects could be ordered in a list such that the last value would be the next one in line to be retriggered. How could I replicate this? And would this solve notes turning off when others are released?

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

                    @Casmat said in Making a Mono Mode:

                    The objects could be ordered in a list such that the last value would be the next one in line to be retriggered. How could I replicate this?

                    This shouldn't be needed. In a mono system there is only ever one active note and one old note. With retrigger you have potentially two old notes. So at max you need to keep track of those three notes.

                    And would this solve notes turning off when others are released?

                    If you are making artificial notes you still need to turn them off.

                    A midi list is an array with 128 elements that is optimized for this kind of task.

                    To create a midi list use:

                    const eventIds = Engine.createMidiList();

                    To store the event triggered by note 60 (for example):

                    eventIds.setValue(60, eventId);

                    To store events as they come in to on note on you would replace 60 with Message.getNoteNumber() and eventId with Message.getEventId(); But you can also store artificial events too.

                    To the get the eventId of note 60:

                    local eventId = eventIds.getValue(60);

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

                    CasmatC 1 Reply Last reply Reply Quote 0
                    • CasmatC
                      Casmat @d.healey
                      last edited by Casmat

                      @d-healey ohhh, I’m trying to recreate Vital’s mono mode on the “newest” voice setting which keeps track of held notes and prioritizes the newer/latest notes. I’m guessing I wouldn’t be able to hold that much note numbers in midilists, right?

                      If you are making artificial notes you still need to turn them off..

                      I thought I took care of all the hanging notes, are there more I didn’t get? The problem is that is I’m doing a regular string of notes, when I let go of the old note while holding a new note I want to hear, the new note retriggers again when the old one is let go

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

                        @Casmat said in Making a Mono Mode:

                        I’m trying to recreate Vital’s mono mode on the “newest” voice setting

                        I'm not familiar with that

                        I’m guessing I wouldn’t be able to hold that much note numbers in midilists, right?

                        A MIDI list is just a fast array, so you can definitely use it for this. You just might need more than one.

                        I thought I took care of all the hanging notes, are there more I didn’t get?

                        I dunno, I didn't try it. I was responding to this question

                        And would this solve notes turning off when others are released?

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

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

                        27

                        Online

                        1.7k

                        Users

                        11.8k

                        Topics

                        102.5k

                        Posts