HISE Logo Forum
    • Categories
    • Register
    • Login

    How to linear crossfade from one (phase aligned) sample to another

    Scheduled Pinned Locked Moved General Questions
    10 Posts 4 Posters 303 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.
    • T
      tonewolf
      last edited by tonewolf

      Something for which I don't seem to be able to find a simple solution...

      I have an attack sample (let's call it A1), and a release sample (let's call it R1).

      If I trigger A1 and release it, I want the R1 sample start point to be offset by the length of time A1 was held for. It needs to be sample accurate as the original samples are phase aligned.

      What I'm doing at the moment is logging Engine.getUptime() when A1 is triggered, and then logging the same when it is released to calculate the note length (this gives me the note length in seconds). I'm then multiplying that number by sample rate (in my case 88200), to give me the sample offset value. I'm then using Synth.playNoteWithStartOffset to offset the R1 sample by that amount.

      On A1 noteOff, my idea was to 10ms linear fade out the A1 sample and 10ms linear fade in the R1 sample. But it's not working. A1 and R1 are out of phase.

      Any help with this much appreciated!

      Douglas.

      T 1 Reply Last reply Reply Quote 0
      • T
        tonewolf @tonewolf
        last edited by

        Okay, silly mistake on my end (I had a detune on the noteOn callback).

        So I can actually get these to play back as I want. However, Still some advice requested on how to set up the cross fade between samples.

        As I said: on A1 noteOff, my idea is to have a 10ms linear fade out on the A1 sample and 10ms linear fade in the R1 sample. I'm currently doing this with the TableEnvelope, as it seems to be the best way I can get a linear fade out and fade in.

        However, what if I wanted to adjust the curve (length and type) depending on how long the A1 sample was held for? Is TableEnvelope still the way to go? AHDSR envelope seems more flexible, but I can't see a way to adjust the release curve.

        Any help with this much appreciated!

        Douglas.

        A 1 Reply Last reply Reply Quote 0
        • A
          aaronventure @tonewolf
          last edited by

          @tonewolf you'll have to dive into scriptnode and create your own custom modulator or envelope for this.

          script envelope modulator is what you want (that's the polyphonic one).

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

            The simple envelope is also purely linear in its default setting so for that use case I would just stick to this.

            T 1 Reply Last reply Reply Quote 1
            • T
              tonewolf @Christoph Hart
              last edited by

              @Christoph-Hart Is the Simple Envelope polyphonic? Also, am I able to modulate the release time? I was using the Table Envelope because it appeared there was AttackTime and ReleaseTime modulators.

              Basically, for any given performance of a single note (this is a piano library) the logic I'm looking for is this...

              1. User triggers a noteOn event, which triggers the noteOn sample

              2. noteOff event triggers a bit of script which does the following calculations...

                a) calculate length of note (we have been logging noteOn and noteOff timestamps)
                b) we offset the start point of the release sample by length of the the held note
                c) we adjust the Attack Time of the noteOff sample, which is calculated according to the note length
                d) we adjust the Release Time of the noteOn sample, which is calculated according to the note length

              3. we enter into the noteOn release phase, and we play the noteOff sample.

              So, if I triggered 5 notes and then released them individually after holding them each for different lengths of time, they might all need to have different Attack Times and Release Times.

              Perhaps I was doing something wrong, but when I was testing out the logic, it seemed like the release was being adjusted globally.

              What would be the most efficient way of doing this? Last night I came to the idea of just using Synth.addVolumeFade(eventId, 50, -100); in the noteOff callback, and that seemed to work pretty well (or at least, it did actually do what I wanted and sounded correct, but I kept on getting an error message in the console telling me the noteOn with IDNNN didn't exist!).

              1 Reply Last reply Reply Quote 0
              • T
                tonewolf
                last edited by

                This is my script for the attack samples...

                function onNoteOff()
                {
                   local eventId = Message.getEventId();
                   local noteNum = Message.getNoteNumber();
                   local noteLength = Globals.noteOnArray[noteNum]['noteLength'];
                   local fadeTime = .128;
                   if(noteLength <= .045) {
                   	// it must have been shorter than or equal to 45ms	
                   	fadeTime = .01;
                   } else if (noteLength <= .16) {
                   	// it must have been longer that 45ms, but shorter or equal to 160ms
                   	fadeTime = (((noteLength - .045) / .115) * .1) + .01;
                   } else if (noteLength <= .45){
                   	// it must have been longer than 160ms, but shorter or equal to 450ms
                   	fadeTime = (((noteLength - .16) / .290) * .018) + .110;
                   }
                   Synth.addVolumeFade(eventId, fadeTime*1000, -100);
                }
                

                It functions well, but that last line generates an error in the console log...

                "onNoteOff() - Line 25, column 21: NoteOn with ID1 wasn't found"

                which seems to break the script and I can't add anthing after that line.

                Any clues? The noteOff cancelling out the noteOn eventID?

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

                  @tonewolf The eventId there is the local variable you've assigned to the note off event ID at the top of your script. I don't thin you can fade out a note off message. You'd need to play a note instead and capture its event ID.

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

                  T 1 Reply Last reply Reply Quote 0
                  • T
                    tonewolf @d.healey
                    last edited by tonewolf

                    @d-healey my noteOn callback is empty, so the Sampler is simply triggering the mapped sample.

                    From what I can tell, the Event ID is the same for the noteOn as it is for the noteOff. That is to say, if I place the following in the onNoteOn() callback, also in the onNoteOff() callback...

                    Console.print(Message.getEventId())
                    

                    ...it returns the same ID for both.

                    T d.healeyD 2 Replies Last reply Reply Quote 0
                    • T
                      tonewolf @tonewolf
                      last edited by

                      btw, more experimenting and sticking this...

                      Message.ignoreEvent(true);
                      

                      ...at the top of the noteOff function call, and then this...

                      Synth.addVolumeFade(eventId, fadeTime*1000, -99);
                      Synth.noteOffByEventId(eventId);
                      

                      ...does not throw an error. Seems a bit cludgy, though.

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

                        @tonewolf

                        I'm fairly certain you can't kill real events, you have to make them artificial. For your use-case I think it's just a matter of making the note artificial in the onNoteOn callback and storing the ID. Then you can control it how you want in the note off callback.

                        Here's an example

                        HiseSnippet 932.3oc4W8zaaaCEmJ1pn1cqXsqnXG0gcvAHqvZqqs.EEMIN1EFqNwHJMa2JXod1lHTjZTTdyXXe21Gg8QoG18sGkThjVTybL5Vw1zAC+9G46u+dRS0JFjjnzDmNmrJFHNejavJoYwfETtjL9.hyscmPSLf1Km09qhoIIPHwwo0KrLb5zlj871muOUPkLnjEgbphyfWxi3lRtS28a3BwHZHbBOph1Ob2wLkbfRnRQ+okaeRLkcFcNbH0p1VtDmaLLjaT5.C0.InN6qBWErP8Cxb8Okmvei.rD9j.7fxYSFrfKBmddrlPHNtSKi7V4Q98bmvC4WvuLC7IYB7JsnZNvYqqxk7uFtjSEWpctKcG2.llGaJkX8ma4NVhEjYTLUW0Ux0k37KtCTnBRyChnmAizHwEFz6Q86uiG9y1OcVpjY3JomRdnx.GI6sc2epamt+bWu+rnYyZTl8ZzJg.zMJ1Vc0Wkg8joQuAz63sjJRgKTDC+54zard4TVdTWQQkbrjaNJFJnGoDg1bk8+WtBPJRa3+d03CnFpsnTvC0KFzFt0cbN.Vhc04knNtG.ImYTwXe8kpeXmiJLUPM0amryMEBv7QsZnsPIS3lUUmqtF8X8uxdr00Eui6TtgsnYebqF7QLS82gOVLY9wtCmMCXlRGrs6nuaSGCW+q+14W+sbC3RHCVL6xueFs22RWBdu.jf1l77uBjweccQFiWajwiXF75OQSkIwpjZGb.DwOQIsYgRluJAABfu+Xa0rJ+AJptQQu84ivfrQaBnlTcVawdQpTooVaPq50g1q2na8IhJ52.NY6O.P28eOAc+oEbK8H+Fgv+MWML2CVhHOiCeWH0Eh8dl2D7nv8jY386gnTy3LNUza6m9tAy6zsSVG8CnggmpDoQfssqWwYtimee6hhuv2to3CDru66KX++OB0Wqmry49X.OJV.CkKAAFjY93cwnZFMUXNma8NxIJoJdgRxYUGyOFLZ974ftpu2X.smwfuDWIm6s6wf.nUgr97ceIB0P0XdB1vbw0+UqZrd8Yt4tqmsG16euqna8e6UzGqRMb47ITrI7GQbhCSiBvMiL.ucoDDVrCmsrS44z8sz4qFkgYD+N9THz2R6THz+bg+ibGQTlV8ZVNpnsO8lYbv3Vl8EOcvO8Bo87IYHkUqkQ3ZsWyX0OpKY3WtoF9UapgObSM7q2TCezlZ3i2TCexesg125XuTiJJezjPlLcX1ZFGmgRJ1kmMQP9C3+t.QK
                        

                        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

                        19

                        Online

                        1.7k

                        Users

                        11.8k

                        Topics

                        102.3k

                        Posts