V2.0 SDK is released!

To all plugin developers: the SDK has been tagged with api-v2.0.0.

Please re-compile your plugins with this SDK and test on firmware v2.0.0-rc1

Since this is no longer a dev firmware, remove the -dev-13 tag from the plugin file name.
Also, we have relaxed the requirements for the -fw-X.Y tag. Instead, you should bump up the plugin version. So if you previously had released:
Myplugin-v1.0.4-dev-13.mmplugin

then this v2.0 SDK release should be called:
Myplugin-v1.0.5.mmplugin

…or feel free to name it with any version you wish, as long as it’s newer than the latest -dev-13 release.

What will happen next is that we’ll manually test all plugins on v2.0 firmware and verify there’s nothing needed to be changed in the SDK. If it’s all good, then we’ll change the website to host the v2.0 plugins and v2.0 firmware

18 Likes

Congratulations Dan! This has been a ton of work and represents a huge step forward for the Meta Module.

3 Likes

Congrats! Thanks for all of your efforts to make this happen!

1 Like

Everything seems to work fine with kocmoc plugin, compiles and runs

Note that this is a prerelease testing version of the plugin and it includes a new module that’s not yet in the VCV Rack library

I had to add the new tag in the Github Action:

The Chilly Cheese module seems to work fine on an api-v2.0.0 build and running on the v2.0.0-rc1 firmware.

@janne808: a new diode filter, cool! The only thing is that the plugin-mm.json format has been updated. The MetaModuleIncludedModules field now needs to be a dictionary:

I’ll finish the transition from our examples repo to your repo with this release.

Looks good, thanks for that!

I totally missed this but it should be fixed now on v2.0.10:

Sounds good.

1 Like

@danngreen

I’ve tagged and kicked off v2.0 releases for all of my ports. Let me know if I missed any. I am also out of town so cannot test them, I just upped the tag version and re-ran the workflow for a new release.

1 Like

Our parser is reporting syntax errors with the trailing commas after the name field. I think that’s it though

Most are good, but we are getting json errors for four plugins:

Fehlerfabrik: extra [ and ] in MetaModuleIncludedModules:

Mockba: trailing comma on line 166:

SanguineMonsters: same error as Mockba (trailing comma after last module)

RPJ: same thing again (trailing comma)

Fixed it:

Maybe there should be a simple sanity check in the Github Action script? Something like

jq . -e plugin-mm.json >/dev/null || exit 1

Good idea! I’ll put that in the example workflow.

I tried using cmake’s native JSON string support to validate, but it lets through too many mangled cases.

I’ll add a validation check to the plugin-sdk as well so you can catch errors before pushing, but it’ll just issue a non-fatal warning if it can’t find the jq executable.

Thanks - rebuilt those four as v2.0.1

Perfect! Everything checks out!

@danngreen is midi::Message size being set in all cases?

Im using getSize() to validate the message, that worked on vcv desktop.
but when I moved it over to MM It was failing.. didn’t seem to be being set correctly so my code was rejecting all messages.
I removed check and my code worked as expected.

Ah, that’s a bug. I accidentally set the default size to 0, whereas Rack sets it to 3 (some messages set the size manually, so those ones should work the same).
You can ignore that for now if your code works.

The main difference is the MM midi::Message data has a max size of 3 bytes (it’s an array), vs. the Rack midi::Message data has unlimited size (it’s a vector). But hopefully that’s all behind the scenes (once I fix the size bug)

1 Like

yeah, Id noticed it was defaulting to 0 - cool, I guess I could fork/patch the sdk.
a couple of questions…

a) talking vector vs array - how do you handle sysex?
do you just pump it out in 3 bytes chunks, a bit like how usb midi is done?

b) midi output w/multiple ports
when a (usb) midi device has multiple ports, do you send to all?
sending to all could be problematic for some devices, I use.
however, unfortunately, just sending to the first would be even worst :laughing:

it be nice for input and output, if we could specify which port we want to send to ?!
this would be possible within the rack sdk, by having each port as a ‘fake’ device, as it does vcv.
this would also make modules ‘more compatible’ since thing like appendMidiMenu() would work.

Id suggest just for now, it just the one midi device, so can be simplified down to just a usb index for port… and means you get support for usb midi hubs
but means later, could be extended to support more ‘normal’ usb hubs for multiple midi devices.

ooh, I had another question… not related to midi.

expander support?
am I correct in saying expanders are not supported?

for some ideas Im working on, Id find these incredibly useful.
basically, with the smaller screen on the MM, Id like to keep the module width to ‘reasonable’ size
so Id like to use expanders for adding ‘optional’ parameters or extra jacks etc.

Im thinking if the MM force the expanders on to the same core, then this could be pretty efficient?!
share same address space, and you ‘know’ code cannot run at same time, so no locks necessary?!

(all assumes from within 4ms Metamodule hub, you can tell when modules are ‘connected’ , and so force core affinity)

It’s not handled, we just ignore SysEx start (0xF0) to SysEx end (0xF7).
I think it could be added easily, we could split it up in chunks like you say, I don’t think it would be hard.
I did it that way to avoid allocations, and so the MIDI frames can be aligned to audio frames.

It just sends to the first one it finds, which I know is not ideal. Supporting multiple ports would be contained in this PR for USB hubs. But we would still need a MIDI device and port “chooser”. I was thinking something along the lines of the File Browser, where a module can call as async function to have a window pop open with a list of attached devices.

Correct. Some good ideas for their implementation here: Support for VCV expander modules, with proposed design

It might offer a boost for that expander/main-module combo, but not necessarily for the entire patch.
But you would still want some sort of sharing mechanism if a module and its expander are both accessing the same block of data, right? E.g. the producer/consumer message system in VCV. Or do what the Venom modules do and have the main module be the only thing that accesses the data (so, no sharing at all).

Hmm… I’m not sure but I would hope we can handle it like we handle cables: First process the same-core cables in parallel on each core, and then sync the cores with a barrier, and then process the cables that cross cores in parallel on each core, then sync again (so the processes are always reading from different cores and writing to different cores).
The SCU unit on the A7 that handles sharable memory between the two A7 cores is poorly documented, and by “poorly” I mean there is only a tiny amount of generic docs for a related architecture, and it’s inaccurate… so that’s the source of my uncertainty!

Re: core affinity: since a late v2.0-dev release, core affinity is dynamic, and can be re-assigned anytime a module is added or removed, or the patch is loaded/re-loaded. Basically we run the patch a few times and measure each module and its cables, then come up with a partition that gives fairly equal times between cores.