Hi, I am trying to find a way to activate or select a specific VST with Autohotkey.
I’ve created a couple of AHK scripts to navigate through patches by either clicking the mouse button or scrolling or using the arrow down and hitting enter.
All of these require manually positioning the mouse in a certain position on the VST GUI h which is tedious
I would like to automate the scripts even further by
activating the target VST or VST effect (bringing it to the foreground if hidden)
navigating to the precise mouse co-ordinate which is required to click or scroll in the right place and auto advance while auditioning patches
I am confident I can do item 2 but I am having a great deal of problem with item 1 - activating the target window
I’ve used the window spy application to get the plug -in window details but it doesn’t seem to activate the chosen VST.
I’m guessing that somebody else has almost certainly tried to accomplish this with autohotkey before. Are there any pointers please?
Here’s a screenshot if it helps. I cant seem to get my AHK script to select the Massive window, even though ‘Window Spy’ v2 can see and identify it correctly
Here’s how you can get a handle to the plugin window.
#SingleInstance force
#Requires AutoHotkey >=2.0
DetectHiddenWindows True ;Must be used to detect a plugin window
hwnd := WinExist("01 - Massive") ;Get a handle to the window
if hwnd {
WinActivate(hwnd) ;Make the found window active
MouseMove 1, 1 ;Move mouse cursor relative to the found window
}
Btw, I think my first effort failed because of bad coding. I was activating Cubase first, then Massive - and the AHK triggers were actually going into Cubase. I didn’t realise that you could go directly to Massive.
It’s so nice to set up a loop cycle when writing and just sit back and listen to hundreds of patches cycle through so you can pick out the ‘best fits’. Saves lots of clicks and RSI!
I think my next thing will maybe be to write a separate AHK2 so I can press a single button on my Stream Deck XL and automagically add the currently playing patch to my favourites.
Unfortunately in Massive, pretty sure this requires using / navigating within the patch selecter at the lower left, rather than the selecter at the top.
Patches can be advanced in this lower left box by pressing Arrow Down + Enter so I have created a separate script for this method.
Another challenge is, the favourites sub-menu only pops up with a right click and is not accessible via keyboard or keyboard shortcut - I think I will have to use some colour/image detection to access it.
It was a slog as I’m not an AHK expert, but I got ‘Massive - Add to Favorites’ working using trimmed screenshots. I’m off to bed! Thanks again for your support!
Thanks for your great work! I’m now trying to enhance by sync-ing up the automatic patch changing etc with the start of each loop through MTC.
Regarding your midi library -
The folder \Examples contains a number of examples of usage. Extract this folder to a location of your choice.
(To run one of the examples, simply double-click the .ahk file.)
That’s just how GitHub works, I’m afraid. That file only includes the source code of the library.
If you scroll down just a little bit on the page you screenshot, there are installation instructions guiding you to the correct zip file.
You can also click on the release link on the right side of that same page.
Sure - apologies - I just grabbed the zip from there in a rush without reading the instructions properly.
I’ve had a bunch of problems with MTC all evening. The messages from Cubase seem to be outputting fine as comms tests passed with Cubase → Loopmidi → Midi-Ox at the first attempt…
When I try to route via the same port with your library, the same script fails (I’ve tried a number of both old and newly created Loopmidi ports so the screenshot may look like they are not consistent, but they were at time of testing).
Hi @Skope!
Unfortunately I noticed that the example file MMC.ahk was using callback names from an old beta version of MIDIv2 and as such did not work as intended. My apologies.
I have made the necessary changes to the example file and updated it on GitHub. Here it is in case you want to try it. Just replace the old MMC.ahk with this one: MMC.zip (1.8 KB)
Keep in mind that you will have to edit the script to change MIDI Port names.
myInputName := "MIDI In" ; Change this to the name of your MIDI In port
myOutputName := "MIDI Out" ; Change this to the name of your MIDI Out port
Hi @mlib I was testing yesterday evening but couldn’t get it to work so thanks very much for the fast fix! I also tried implementing with the alternative bassmidi.dll Library but that seems to be a little archaic with potentially some x64 issues - but could even be my auto hotkey installation (but I doubt this as Windows user32.dll responds as expected)
Anyway, no need to apologise - You are providing some really useful tools to the community!
However, I’m thinking I’ve spent too long on getting the automatic loop sync enhancement working, as manually calculating the BPM and inserting inside the code was working ‘good enough’ for me. I generally start projects at 120 or 170 BPM so doesn’t need to be regularly changed. (Or I could have two hard-coded scripts for those bpms)
Having said that, I do like a challenge, so might spend some more time on it today. If so, I’ll check out the updated MMC script, but just to ask, there’s no chance that your main Midiv2 library also needs any updates?
Not that I’m aware of, no. The documentation should also be correct. I haven’t made any changes there.
If you do find something that doesn’t appear to work, don’t hesitate to let me know.
Hi @mlib - I’ve sent you a PM with info and current ahk2 requesting
Add a Built-in Handler for Real-Time Messages
Right now, 0xF8 (MIDI Clock) and similar real-time messages (0xFA, 0xFC, etc.) aren’t routed to a separate callback.
Having a dedicated “OnClockPulse” or “OnRealTime” approach could simplify syncing or BPM calculations.
Option for a General Short-Message Callback
A function like OnShortMsg(dwParam1, dwParam2) could capture all unrecognized short messages. That way, users can parse them without modifying _midiInCallback().
Documentation Update
A quick note explaining how to patch _midiInCallback() or where to insert logic for unhandled status bytes (like 0xF8) would save time for new users.
Thanks @Skope for your comments. I’ll address your thoughts one by one below.
Add a Built-in Handler for Real-Time Messages
I purposefully did not implement handling of MIDI Clock messages. In my testing, AutoHotKey is not fast and accurate enough to handle time sensitive messages like these. Just to prove my point, I found one of my test functions I used for receiving MIDI Clock signals.
The function above uses a Windows API function to get the system time with an accuracy of 100-nanosecond intervals. Even still, this is the output I get when sending MIDI Clock at 120 BPM:
Besides MIDI Clock related messages, what other type of Short MIDI Messages do you find are missing?
Some Short messages are quite straight forward. Such as a Note On message or a Control Change message. Other messages require little bit of massaging before they are usable. Pitchbend or MIDI Time Code are examples of such.
Exposing a “Catch All” callback would require a much greater level of support and documentation than having ready to use callbacks for each message type. When creating something like this, there is always a balance between complexity and user friendliness that needs to be considered.
Documentation Update
A quick note explaining how to patch[…]
This is outside the scope of the library.
The purpose of this library, and any programming libraries, is to provide an easy to use platform for accessing a more complex system.
Anyone is free to do what they want with the source code as it is released under a GPL3.0 license.
To learn more about programming in AutoHotKey, see the official AutoHotKey Documentation.
I understand your point about the timing not being 100% accurate. I noticed that the vast majority of the reported bpms in your test were very close to 120 BPM, at 119.xx
I did have an idea for a work around though - take an average of a set of sample bpms and round it up (Or similar method), but I understand that this might be more trouble than it’s worth.
I’ve spent a couple of days on this so I think I’ll just revert back to the manual BPM input at the start of my script - it was working very well apart from the hardship of having to do 3 key presses and a mouse click at the beginning