Getting the play positions of held notes



  • Hi,

    I saw David Healey's video on using timers to get note held, and was intrigued:

    I've hit a dead end while using timers to get the play positions of held notes though.

    Here's the code I ended up with:

    // onInit
    const var timer = [];
    const var eventPlayPos = [];
    
    function onNoteOn()
    {   
        Message.ignoreEvent(true);
        
        var eventId = Synth.playNote(Message.getNoteNumber(), 64);
        timer[eventId] = Engine.createTimerObject();
        eventPlayPos[eventId] = 0;
        timer[eventId].setTimerCallback(function(){
            //Console.print("note held");
            
            // this of course only gets the play position at the most recent eventId. It would be nice if eventId could be local to this function. 
            // You can only define local variables in an inline function or a callback though, and if you define a local variable outside of this function, it can't see it here.
            Console.print(eventPlayPos[eventId]);
            eventPlayPos[eventId]++;
        });
        timer[eventId].startTimer(((60/hostBpm) * 1000) / 12);
    }
    
    function onNoteOff()
    {
        var artificialEventId = Message.getEventId()+1; // this doesn't seem like a good idea...
        timer[artificialEventId].stopTimer();
    }
    


  • I should give more context as well:

    One of the reasons I'm trying to do this is for legato.
    I'd like to make it so when you play a legato note, it plays the sample from wherever you were in the previous one.

    Kontakt's Unisono - Portamento script has an option to do this if you set the Mono Mode to Legato. It's quite handy!
    fb0135cf-2740-4c3e-802a-b261637bd048-image.png



  • Ok, to answer my own question 😜

    // onInit
    const timerInterval = 0.05;
    Synth.startTimer(timerInterval);
    const sampleLength = (60 / 110) * 16;
    var keyDown = Engine.createMidiList();
    var legatoPlayPos = 0;
    
    function onNoteOn()
    { 
        keyDown.setValue(Message.getNoteNumber(), 1);
        if (keyDown.getValueAmount(1) == 1) {
            Console.print("first note played");
            legatoPlayPos = 0;
        };
    };
    
    function onNoteOff()
    {
        keyDown.setValue(Message.getNoteNumber(), 0);
    };
    
    function onTimer()
    {
        if (keyDown.getValueAmount(1) >= 1) {
            normalizedIntensity = (legatoPlayPos * timerInterval) / sampleLength;
            // set the intensity of sample start constants here
            legatoPlayPos++;
        };
    };   
    

Log in to reply
 

17
Online

1.2k
Users

3.9k
Topics

34.4k
Posts