qlcplus
qlcplus copied to clipboard
Add MIDI Note Off Triggers Scene behaviour
Hi,
This PR introduces a new MIDI Plugin setting. As it stands right now, when QLC+ receives a Note Off command, it gets auto-mapped to value 0. Because of this, a Note Off can never toggle a switch, which can be very much desired.
The specific use case for this is as follows: effects and chases cannot be flashed, and as such have to be toggled. When programming lights through MIDI in Cubase, I want to make sure that whenever I point anywhere in the track, all of the correct animations immediately start playing, and not for those animations to be triggered at specific points in the song only. To do this, I use very long MIDI notes (for the length of the chorus for instance). To make sure the animations stop running, I always need a second note at the very end of that note (see screenshot below).
This is very counter intuitive for me and has lead to many cases of animations still going on when they shouldn't have (not nice to see moving heads go crazy when a quiet bridge sets in ...). Having the ability to toggle a scene whenever a MIDI note ends is a great feature in my opinion.
This PR doesn't affect existing behaviour, only provides users the ability to configure the plugin in a way that might better suit their needs. It has drastically improved my own flow for sure!
The PR is an initial proposal and I'm very welcome to feedback. I'm not a C++ or Qt developer and just try to adhere to the existing code style. Let me know!
Edit: the name noteOffTriggersScene is probably not the best yet, does anyone have a better suggestion?
Edit2: I also updated the documentation to reflect this new configuration option
Coverage: 28.062%. Remained the same when pulling b379117bcd11921bd38e7b10926abdf316c986b3 on Timebutt:add-midi-note-off-behaviour into 3be5b34cea08a74cb17c342f7e9cf4b67bfd1481 on mcallegari:master.
Hi, sorry for the huge delay. I am reviewing this PR but I'm not convinced this is the proper solution to the problem. If you have a look at the Generic MIDI input profile, you will see that every control is set to "Slider". This is to handle notes velocity when you want to attach notes to a fader rather than a button. This is nice to control the intensity of a QLC+ function.
With your solution, note off would be equal to 64 which is a magic number and doesn't really represent an "off" state. I am investigating if acting on an input profile could be a better place. For example, a MIDI input profile has an option called "MIDISendNoteOff" which is near the topic we're discussing here.
Would it work for you if considering the note off event would be handled in a input profile rather than plugin level?
Hey @mcallegari! It's been a while for me too, so had to dig up my own code for a sec to be up to date ;)
The 64 I am currently using is the default value the MIDI specification defines when a MIDI device can generate Note-Off messages, but does not implement the velocity feature.
From the spec (see http://midi.teragonaudio.com/tech/midispec.htm and section Note-Off):
The second data byte is the velocity, a value from 0 to 127. This indicates how quickly the note should be released (where 127 is the fastest). It's up to a MIDI device how it uses velocity information. Often velocity will be used to tailor the VCA release time. MIDI devices that can generate Note Off messages, but don't implement velocity features, will transmit Note Off messages with a preset velocity of 64.
Thinking about this more, that specific line of code should basically be rewritten as *value = MIDI2DMX(data2);, identical to the Note-On and other cases, as the velocity of the original message should simply be retained IMO. In that case someone could still send Note-Off with value 0 and retain the existing behaviour.
Implementing this using an input profile is definitely also a way to go, but wouldn't that be more complex than the proposed solution, both in implementation as user experience? I can definitely think up a scenario in which a user would like per note control over this setting, but at the same time think in real life this is a per MIDI input on/off type of thing.
I do see what you mean with the fader and setting values through a MIDI note velocity, pressing and releasing a note would basically always result in the fader receiving the value 64 in the currently proposed solution (and even after refactoring to *value = MIDI2DMX(data2); as most devices will send 64). This would probably break other people's flows when using a global control indeed.
Curious to hear your thoughts, I'll give it some more thought myself as I hadn't considered the slider case. An ideal scenario would be to retain the event type all the way up to the control. A slider could opt to not consider Note-Off events for instance, but that information gets stripped after midiToInput() of course. That would blow up the scope tremendously though I fear ;)
The setting I'm referring to in input profile is global and only refers to MIDI profiles:
Handling one setting per note would definitely be more cumbersome, especially for users.
One additional note: the setting you proposed is stored in the QLC+ configuration file, which is not portable across platforms. An input profile instead can easily be copied as a file and is referenced in the project file IO section.
In that case the Input Profile seems the right way to go. Moreover because it's very closely related to the existing setting indeed. I'll try and find the time to rework my PR here and will get back to you!