Ok, I'll bite.
I am trying to use the new MIDI control trigger to control sliders and the volume in different apps. However, I am already failing at finding an efficient way to extract the value of the controller.
I am trying to start with a simple example, setting the system volume:
As yo can see, the %TriggerValue% token returns a comma separated list of four entries, the third being the value (as in the level) that I am interested in. How do I now access this value?
I cannot use bracket notation as it is not a number-only list. Do I need to use Regular Expressions to get the value?
Thanks!
Edit: @peternlewis shows an example of MIDI-controlling a slider in the What's New in KM 8 video (with collapsed actions, unfortunately). Did anybody figure out how to build such a macro?
However, performance seems to be much worse than in Peter's example. Does anyone know, if performance could be improved. I certainly don't expect this macro to respond super quickly, but the example Peter shows looks much more real-time.
Edit: And now I have simplified it to this, still the same problem:
Hm, I think the macro might be firing to often. If I have a look at the system volume slider in the menu bar, it somewhat jitters back and forth (instead of moving in one direction linearly). Is there a way to make sure to only trigger a macro once the previous run of the macro is finished? Or is it automatically handled like this?
Or, alternatively, is there a way to make a macro only trigger, say, 4 times a second or something like that?
So, I had to place a Semaphore Lock before the Apple Script. After doing that, the macro is very responsive and I can control system volume in (perceived) real-time. Placing it at the beginning of the macro did not work, because then KM seemed to queue up all the macro executions and let them all play one after the other which made for some very slow fading. If I place it before Apple Script action, it seems to work.
Before I mark this as solved, could maybe someone confirm, if this is the correct approach? On one occasion, when I tried to go crazy on the MIDI slider I seem to have crashed the Apple Script Engine of KM, at least it would not execute the Apple Script anymore, even if I took the Semaphore Lock off again. I had to restart the KM engine. However it hasn't happened since. So, is it generally the correct approach?
Two things I’d check first - see what triggering is actually happening, and make sure they make sense. Check what trigger values you are getting and how many of them.
MIDI can definitely send a lot of packets, and that is heading beyond what Keyboard Maestro is designed for, so it’s going to be something to keep an eye on in terms of performance issues.
With the Semaphore Lock, for this case, I would consider setting the timeout very low, and to not report any timeout issues. Then multiple extra moves would be thrown away. The down side would be you wont end up with the final value though, which might be an issue.
Hey, i'm trying to use the action for a simple use case of assigning a physical knob to control the volume of itunes. I've tried playing with a few actions in Keyboard Maestro, but its not working yet- it only seems to change itunes volume when it reaches a certain point in the knob circumference . Is the approach that i took the right way to do it or are the approaches above better for this situation? Or is there a different way? Is there something that i'm doing wrong?
@peternlewis
Thank you, as a previous KM6 user, I didn't know about the timeout option. I set it now to 5 Hundreths, moved the Semaphore Lock to the top of the macro and now it seems to work nicely in most cases.
One more question: I am trying to use a MIDI knob. Is there any trigger option to determine, if I turn it up or turn it down? With the default trigger options I seem to be unable to. It get's even more complex when I want to use a knob as an infinite knob, so it keeps triggering actions even when I turned it all the way down (I physically can keep turning the knob, and it keeps sending 0 values or 127 values in the other direction).
I managed to implement the desired behaviour with KM logic, but as you can see it is rather clumsy, I need to save the knob's previous value, compare it with the current value and then if the difference is 0 also check, if the value is 0 or 127. See this macro that simply moves a text cursor around:
While the performance of this macro is actually alright, the logic feels very clumsy. So, is there any easier way to figure out, if a MIDI controller is turned up or down?
No. There really should be a control change option for "increases / decreases", which should be simple enough to add.
How you would handle a controller that keeps sending 0's or keeps sending 127's, I'm not sure. That would not be an increase or a decrease. I think for that, you would have to write your own state system, like you do.
While I agree that it is not an increase/decrease and should not be included in triggers that are named like that, I still think it would be extremely useful to have a trigger that includes these "changes at the extremes". In the above Text Cursor macro for example, it would not really help me much to only have increase/decrease (without the extremes) at my hand. Even if I catched the increasing/decreasing, I still would need to check if there is a change that does neither increase nor decrease and then I need to check, if it changed at the lower extreme (0) or upper extreme (0). So the macro would basically just stay as "cluttered" as before as soon as I need some infinite scrolling functionality.
What would be useful to have is either yet another pair of triggers, named something like "controller 1 turned up" / "controller 1 turned down" (because turning up or down is what is physically happening with these endless knobs, even if the MIDI value does not change), that would trigger if a controller is turned down, no matter if from 123 to 118 or from 0 to 0 or turn up, no matter if from 8 to 17 or from 127 to 127.
Or alternatively there could be triggers named "changed at minimum" that only triggers when I turn a knob from 0 to 0, respectively "changed at maximum" which fires when I turn a knob from 127 to 127 (or whatever the maximum is, it is probably easiest to catch by checking for a change that did not change the most recent value while the most recent value is not 0).
I hope this makes sense to you. I am planning out a lot of MIDI macros currently with the new KM8 available and a lot of them will require this infinite knob turning (as the text cursor example above). So I think there could be a demand for such triggers and personally I would use them much more often compared to all these equals, greater equals, smaller equals triggers.
Could you not simply trigger on increase, and on changes to 127?
And then in the other macro, on decrease, and on changes to 0?
Ie, just add two triggers to each macro?
I don't know much about MIDI, but how can Keyboard Maestro know that 0 to 0 is "turned down" on a controller? Surely it could mean anything. If you had a 2d control of some sort and were sliding it along the bottom edge, you'd probably get 0 to 0 changes that were not "turned down" per se.
You can presumably already do that, since you know what the min/max is.
Note the difference between "changes" and "changed" in the MIDI options.
Oh my, thanks @peternlewis. That of course will work, didn't think of that. In fact, most of those endless spin macros then I will probably do with the three triggers changes, changes to 0 and changes to 127 with only changes, as I want to catch the exact difference to the previous MIDI value. Still, increases and decreases will be useful for cases, where you just want to increase and decrease stuff in a simple manner where you don't care about how many steps you turned the controller.
True, didn't think of that. I am also no MIDI expert, I just bought this little (physical) MIDI controller a while ago to control Adobe Lightroom and now I am super exited that with KM 8 I can suddenly control any app I want.
One more question: A MIDI value token to return the value of a MIDI trigger only is probably to specific to ask for? Would be useful to simplify those macros. Or would it alternatively be possible to have a syntax like %TriggerValue[3]% to save the step with the extra variable?
Good thread I was just getting on to find out how this was done as well. I am still confused though of how the "Keyboard MaestroForm Example Testing" was made in the video at 1:26min. Was that some other program? There are several things in applications and slider adjustments that I would love to make with CC like screen brightness, system volume (as mentioned in this thread), window position and basically anything that has continuos variables in an app like color depth, font size etc.
Thanks the MIDI Example Macros.kmmacros is helpful, I’ll see if I can get TouchOSC to connect to it. I have been using TouchOSC I think since the first month it came out. It’s a great app that solved a lot of problems for me in the early days, I mostly have replaced it with native control apps for DAW’s these days. Keep up the great work Peter.
Reviving a bit of this old thread. I'm using an Ortho Remote bluetooth knob and it's quite smooth and precise, the performance issue of tons of macros queued up got resolved with the semaphores as you have mentioned (I added an extra pause action after the keystroke or else it would seem to still queue tons semaphore lock and all).
However it isn't quite clear to me how to go about the infinite looping support? I have tried changes/changed to 0 (or 127 at the other extreme), increases, decreases, packets mode (via the recording option, great feature), etc... nothing seems to trigger a change at the ends after it reaches it, so I don't know if it is a configuration I have to take care of at the Audio MIDI Setup preferences?
I don't really need to keep track of how many actual steps where taking during the last timeout but only to trigger (it will be throttled by the lock and pause). I was thinking if there's a way to 'recenter' the midi value from KM? so when it detects a decrease, it sets it back to 64 and I'm hopping that the pauses plus the timeouts will abort that instant change from > 64 back to 64 (when 'increasing').
Or if there's currently a way to go about it?
EDIT: a small clarifcation/patch on my logic, if there's an action way to reset the midi, then the 'infinite' looping could be instead by detecting a 'changed to' < 64 for decreasing and setting it back to 64 or detecting a changed to > 64 and setting it back to 64.