MIDI Keyboard Object Legato Behaviour


#1

Does anyone know if it would be possible for a custom object to recreate the legato note-handling often found on analogue monosynths, whereby if a note is held while a second note is played, the held note is retriggered when the second note is released?

With the current Keyboard input objects, the first note is cut off by the second, but does not retrigger when the second note is released.

a|x


#2

I already have an implementation of this... I was going to replace the midi/in/keyb with it, but then was undecided since it may not be what everyone wanted.

I guess I should post it in the community library for now.


#3

doesn't midi keyb lru do this already? at least here it works (though i'm not sure if my controller resends the note on, once the second note is released, will have to check in the code)


#4

There are some limitiations
Though it was a while ago that I looked at this, so it's a bit fuzzy, so perhaps lru is 'good enough' for your needs

Here's the thread where I demo'd the proposed fix

( note: this was not The final version of the obj as I've got a version l sitting around that I think is a bit different/newer)


#7

That would be cool, thanks. Will check it out when I get home.

Would be cool to have an option to toggle the gate output off and on again when the second note is released. This would introduce a minimum 1 k-rate cycle delay between the second note being released and the first being retriggered.

Many monosynths don't retrigger their envelopes until all notes have been released though, so maybe this should be the default behaviour.

In the case of overlapping notes, a second gate output could be added to allow slew/lag to be turned on on legato notes.

a|x


#8

I also welcome this addition. I wanted my AD envelopes to retrigger on each key press the other day.
Definitely need this!

Thanks!


#9

I think that's a different issue.

a|x


#10

yeah, this should actually just work


#11

sorry for my ignorance, so you want a keyb-object that:

-does not retrigger when you play more then one note
-does retrigger the old note when you release the new note (if old note is still held of course)

right?

with lru you get:
-does not retrigger when you play more then one note
-does update pitch if you release new note and old note is still held (but no retriggering)

EDIT:

i just did some tests and i get this with lru object:

-if i use gate2 held notes are retriggered, but also overlapping notes. but that is not what you want, right?

-if i use gate1 held notes are not retriggered overlapping notes are also not retriggered.

EDIT2: your object (ltest2) @thetechnobear, does act very weird on 1.0.12, there is no retriggering at all when more than one note is held...


#12

ok , ive uploaded the keyb object I had.

@lokki , sorry, I don't have time to get back into this topic, have a read of the thread I linked to, this was the reason for the change and so hopefully explains the change in behaviour.
( if you agree with it or not thats a different thing, and part of the reason I didn't end up releasing it.)

I tested it on 1.0.11, and was happy that it gave me behaviour that was consistent will real hardware synths, Ive not tried recently (this would require me diving into what the issues were), but I see not reason why 1.0.12 would break it.

BUT, I dont claim its perfect, at the same time as this topic, I also was PM'ing Johannes, and during that discussion concluded the current model/objects were not ideal, for various reasons there are too simplistic ... but they need changes in the voice allocation code (which is not an object) to be improved - another reason I put it on the back burner.


#13

all good, i did read the thread but don't seem to get it at all then... no worries.


#14

sorry to come back to you with this @thetechnobear . but @toneburst asked about an object that retriggers legato held notes after new ones are released, you mentioned that you have an object for just that. now i tried your object and here it does not do that. what it does is sustain the last played note pitch as long as you hold the "first" note. so pitch does not jump back to the first note and there is no retriggering from gate or gate2. probably i am missing something really obvious. attached is my test-patch.
the first held note acts like a sustain pedal for the other notes...

legatotest.axp (2.7 KB)


#15

Ah, yes, definitely not what I had in mind, and I don't know of any monosynths that operate as @lokki describes.

Pitch should definitely jump back to the original note when the later note is released, in order to emulate most monosynth behaviour.

There are two options in terms or gates. Either:

  1. Gate is held high until all notes are released
  2. Gate is toggled low and then high again whenever a new note is played

There could be two gate outputs, one for each behaviour.

Thinking about it, it actually gets more complicated when you start to think about what happens if more that two notes are held.

I think the sanest way to deal with that would be the the pitch always jumps to any new note that is pressed. When that note is released, the pitch would jump to the most recently-pressed note that is still being held.

I guess you'd achieve this by adding each note to an array, and remove each note from the array when released. When a note is released, the pitch jumps to the highest-numbered array index containing a note-value.

If index 0 of the notes array doesn't hold a key number when a new note is pressed, we can set a gate output of type 1 (as above) high.

If on release, index 0 or the keys array only contains the note number of the just-released key, then we can set the gate low again.

a|x


#16

yeah, sorry my memory failed me, and not having time to go back and check.

anyway, having a look at the object and also the previous thread, I kind of remember what whats going on now :wink:

keyb (and variations) have a bugged legato/retrigger handling, the thread I linked was about this, its got some quite particular cases... but the more you play with it, the more you find its flaws :wink:
so I fixed this issue (and Ive just retested - it works correctly), but its only handles retrigger/legato within the confines of the objects 'behaviour' ... in the case of keyb, there is no concept of note allocation, so can have no idea of returning to a previous note.

btw, please also note johannes comment about adsr (its an important point, that can cause confusion)

so this, fixed behaviour would have to be transferred to other objects like lru, so that they would have correct retrigger/legato handling... this never happened because I didn't get enough feedback that it was ok - needed for an object that is used by everyone all the time!

to get to the monophonic behaviour as toneburst wants, it needs to take this, and then implement monophonic note priority in a different object.. , this would need to track ALL notes that currently held down by that voice for it to work properly. (hence why you dont want the overhead in the basic keyb object) , basic variations could then allow for high or low note priority. definitely something that belongs in the factory library.
(bizarrely, I thought I had an object for this, but cant find it... perhaps, id just worked out what was required to implement then forgot about it .. i dont really play mono patches)

im not convinced you'd want 'live switching of modes' as this means you carry various overheads even if your now using them even if its just reduce optimisation paths/more memory

btw - perhaps a point not made clear in the above posts... there are many mono strategies, lru, high, low, are just 3... with legato/retrigger is on a different 'dimension' i.e. forming 6 combinations, but there are more (I think)


#17

Just tried it myself, same situation here, it's not what I meant.

Say for example that I have a note playing on every step of a 16-step sequence, and each step has a basic AD envelope of it's own. I need the envelope to retrigger each time the note is triggered by each step of the sequence, but I can't get it to do that because the envelopes completely ignore when they're been retriggered, they carry on regardless until the end of the envelope is reached.

If the envelopes could talk they would be saying, right, I just got triggered, so don't bother me again until I've finished my current cycle. Once I've finished, I'll accept another trigger request from you. It doesn't seem bothered in the slightest that several other steps of the sequence have passed in the meantime, and that none of them got the envelope retrigger they expected.

This seems like more of an envelope issue to me, maybe they just need a reset inlet on them.


#18

this was the point made by Johannes, that I quoted... some envs reset on trigger, others do not. there is inconsistency.

as I was trying to explain in my last post, there are actually multiple 'issues' surround this, and they exist in different objects - which is why different people have different ideas as to what is broken , it just depends which bit of the puzzle they are looking at.

hence my mistake, I remembered the issue, but forgot Id only fixed the particular issue the Reggie has raised.
apologies for any confusion I may have inflicted.


#19

Please, no apologies, I'd hate to have the workload you and Johannes must have with Axoloti!

I was really just adding the info to clarity of my own personal use of it, but as you say, as it's an inconsistency thing among the envelopes etc, I can always look for other envelopes. Only reason I specifically used AD is because that's all I needed, it was really just for efficiency, to keep the CPU usage low.


#20

i can get number 1 by using gate1 of keyb lru.
i can get number 2 by using the gate2 of keyb lru.

check attached patch.legatotest2.axp (3.5 KB)


#21

@lokki I think I discovered that already. Actually, it may have been you who pointed it out to me when I posted a thread about legato a while back.

The whole envelope retriggering thing is a bit of a diversion from my original post, though.

a|x


#22

The non-retriggering envelope issue was pointed out because your thread is discussing a retriggering issue, and they might have been related.