Resources usage

Is there in principle a way of loading resources on/off of the device with FirmwareSender? Shouldn’t that be able to download and upload whatever flash it needs?

Yes, FirmwareSender works with them the same way as patches (there’s no difference at its level). But I’m pretty sure that it doesn’t read from device slots, there’s just no support in current MIDI protocol for that.

Btw, there’s also integration in OwlProgram for uploading resources now, you can use something like make RESOURCE=/path/to/resource SLOT=SLOT_NUMBER resource . Resource slots follow patch slots, so 42 would be used by settings and you can write your own data in remaining 11 slots.

If it works correctly, new firmware will show upload progress bar and you will see new resource in resource browser page. You can also delete from that menu after clicking on it to enter delete mode. And resources that start with double underscore would be write protected in that menu (but can still be overwritten).

The current state of play (ie develop branches):

  • firmware supports new SysEx functions for storing a resource by name, and for retrieving stored resource names
  • Patch class has a new Resource* Patch::getResource(const char* name) function
  • FirmwareSender has been updated to pack, send and store a binary resource by name
  • resources such as samples can thus be stored by the user and accessed by a patch

To test it I’ve been doing the following:

  1. convert wav file to 48k mono float32 raw file with sox:
    sox sample.wav -r 48k -c 1 -t f32 sample.raw
  • send raw file to device and store as sample.wav:
    FirmwareSender -in sample.raw -out "OWL*" -name "sample.wav"
  • load test patch, e.g. ResSampler

I’ll create a simple web utility to upload resources, and a method for deleting (uploading with the same name automatically replaces an existing resource).

Would be great to have the ability to upload a wav in the browser and convert it to the correct raw format with JS, but that’s way beyond my front end coding skillz.

I think that we’ll eventually start supporting storing WAV files in resources. Then we could have a few service calls for getting WAV data or individual cue points. In such case, only non-audio data would require storing raw data as resources.

I would like to follow up on this…
Based on the notes on the 22.4 release it sounds like resources are now a working/shipping feature!
I see resource is documented in the API now.
I am going to update to 22.4 and try to write a patch on my Magus that uses resources.
I was wondering, is there a specific patch where source code is available that provides an example of using/selecting resources? This would save me time.
This thread mentions a “quad sampler” patch, but I didn’t find that patch in either the OwlProgram repo or in rebeltech.org/patch-library. Does “quad sampler” use resources? Is source available?

Hey Andi, welcome back!

Resources were usable for a while now, aside from a few changes to its API while we were still deciding how to make them convenient enough.

Here’s how data is loaded in Martin’s QuadSampler patch that you’ve mentioned.

We don’t have a way to select them dynamically yet, even though it makes sense for a device with display like Magus/Genius. So for the time being you have to hardcode resource name in your patch statically, but of course any resource contents can be used with that name later.

1 Like

Thanks, so, I tried writing some code that uses Resources, and two things confused me…

First off, minor, Patch::getResource(), it says it “raises an error” if the resource does not exist…
Not sure what that means but it sounds bad. (EDIT: I tried it and when it prints the error it appears to terminate my patch! So that’s very bad…)
Is there a way to check if a resource exists before “getting” it?
I see if I call Resource::open or Resource::load open a nonexistent resource, it just returns NULL… should I be using those instead if I don’t know yet whether the file exists (because they return NULL instead of “raising an error”)?

Second off… I can’t figure out how to create a resource!
I tried calling new Resource(name, size, someData) experimentally to see if that would create a resource with the given size and resource, but that is protected.
Are patches allowed to create resources?

Well the error is the error message / status that you will get.

Yes

Currently you can’t write to flash from patches. It was implemented initially, but Martin decided against this due to flash wear concerns. So to write to resource storage you would have to store them in web UI or using FirmwareSender

Thank you for the help!

I’d be very curious if @mars could be convinced to reconsider on the patch saving.

[This] (NanoKontrol2Seq: 8 channel CV sequencing on Magus!) (see video) is the project I was hoping to make use of patch-side Resource save on. The idea is it uses the Magus to turn a particular midi controller into a sort of musical instrument/sequencer. You ear-tune up to 8 (maybe someday 16) CV values for each of (up to) 8 notes. Tuning all those values takes a long time and once you are done you obviously want to save your work! The sequences can’t be uploaded from the computer because they never existed on the computer, they were created entirely on the Magus. Connecting via USB to the computer and downloading them from there is probably a nonstarter(?) because while using the sequencer patch you want to MINIMIZE CV noise, and keeping USB HOST connected adds noise.

The inability to save sequences is made especially brutal by the known-issue bug where once USB DEVICE disconnects it cannot reconnect. In my experience with the patch so far, it is frequent that the nanoKontrol gets jolted and temporarily disconnects. But since disconnections are permanent now I must reboot the Magus, which means losing my sequence…

I understand the concern about flash wear. I am trying to figure out if there is some way to protect the device from aggressive saving. In the case of the sequencer patch, it currently saves only at the user’s request, so they at least know what they are doing to their flash…

One idea is maybe the patch uploader could have a checkbox for “allow patch side saving”, and Resource could deny saves to a patch if the user has not approved it. That might mean adding unaccessible complexity to the the patch uploader tho.

Hint: Martin’s been rarely available for last few months and this might not go further than just discussion.

I recall that the objections were specifically about writing to flash from user code (considering that this is controlled by somebody else when the patch is downloaded from the web). But I was told that triggering this from MIDI is probably OK.

Also, Witch has some kind of parameter persistence support, but I don’t quite understand how it works. I see that it has parameter loading, but nothing in firmware seems to store them. So I assume that the resource generation with patch settings is done somewhere in its web frontend. But we could do that in firmware too, i.e. there’s SAVE_SETTINGS MIDI CC defined that is not used for anything AFAICT.

Theoretically we have a few spare bits in resource header’s flags that could be used for something like this. But it only notifies users that patch will be writing to resources, not how many times it can happen. So the flash wear issue is still present.

We probably could just restrict patches to write to flash just once if it’s triggered by code.

Hm, like, CC 107 is sent, it saves? That makes sense, although I was hoping to implement in my patch something like, if you hold the REC button for 0.5 seconds it saves, if you hole CYCLE and hold REC for 0.5 seconds it reverts. That would be the friendliest version of the feature. And codewise that would probably still look like a save triggered by the patch…

So I am thinking about this from an end-user perspective… if a user has a sequencer, and there is a button in the sequencer to save their patterns, but the user can only use it once per boot up… that will feel illogical/unfriendly, and might lead to weird behavior like saving and then immediately rebooting the device. It might make sense from a system design perspective but less so at the user level for the kind of applications I’m thinking about…

Here is a question, you said this feature was in at some point. If I were willing to build my own firmware, could I dig that code out of the git history and patch it back in? Then I would only be ruining the flash on my own device… (Assuming I can get the firmware to build again of course.)

Sure, but it’s been a while since that was written and many things have changed. Here’s the initial version for resources support in firmware (+ some more commits from that branch) and patch side.

Note that:

  1. it also had some sort of indexing support - you could get number of resources and address them by ID to get names
  2. since then there was a big refactoring for flash storages to add support for external flash chip, some calls for saving resources are probably different
  3. it took 3 rewrites for this to be accepted upstream and I think Martin also made a few big changes to Resource class after that. IIRC only first version had write access.

This should give you an example of exposing parts of firmware to user patches via service calls. Ideally we would hear what @mars has to say about this, maybe there’s some approach that he would be willing to add to upstream.

1 Like