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.
    • d.healeyD
      d.healey @Casmat
      last edited by d.healey

      @Casmat That will work (if you want to make it better you need to do this xfade/pitch fade with each pair of notes between the first note and the last).

      The sample position isn't important (or maybe it is to you?). Just as long as the samples are looped and the loop doesn't include the transient.

      By the way, my legato script does this :)

      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 thanks David! Will update you with what I find!

        By the way, my legato script does this :)

        GPL though :confounded_face:

        The functionality im planning on implementing is this:

        • Mono Retrigger Mode, no glide, just basic retrigger
        • Mono Legato Mode, glide! Basically what you said in your post
        • Anchor/Last note retrigger, if a note is held and another note is pressed and let go, the note held is played, both for legato and retrigger mode
        d.healeyD 1 Reply Last reply Reply Quote 0
        • d.healeyD
          d.healey @Casmat
          last edited by

          @Casmat said in Making a Mono Mode:

          GPL though

          I think you mean

          GPL though :party_popper: 🍾 :person_raising_hand_dark_skin_tone: :person_raising_hand: :clapping_hands_medium-light_skin_tone: 😂 :1st_place_medal:

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

          CasmatC 1 Reply Last reply Reply Quote 1
          • 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

                              30

                              Online

                              1.7k

                              Users

                              11.8k

                              Topics

                              102.5k

                              Posts