Updates to offline compiler

Thanks a lot Stas,
I will start to check it out these days.

Cheers Jan

1 Like

Hmm, I’m trying to build a heavy patch (using my hvcc fork) using develop branch and run in to:

/usr/lib/gcc/arm-none-eabi/8.3.1/../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/8.3.1/../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard/libc.a(lib_a-sbrkr.o): in function `_sbrk_r':
/build/newlib-kGgvwE/newlib-3.3.0/build/arm-none-eabi/thumb/v7e-m+fp/hard/newlib/libc/reent/../../../../../../../../newlib/libc/reent/sbrkr.c:51: undefined reference to `_sbrk'
collect2: error: ld returned 1 exit status
make[1]: *** [compile.mk:159: Build/patch.elf] Error 1
make: *** [Makefile:110: patch] Error 2

Anything I’m missing here? is there something wrong with my gcc?

Something with missing linker flags as mentioned here? → c - Undefined reference to _sbrk - Stack Overflow

Hmm using newer Gcc toolchain is a good idea, but it probably won’t help here. Does your fork use printf function by chance? I think it was leading to some similar error. Otherwise, @mars might want to have a look at generated patch source

Not really planning to move away from debian stable at the moment :wink:

No printf in the OWL generator no. Just the same snprintf() that is also in your HvUtils.h
I don’t use these files that are included in OwlProgram: https://github.com/pingdynasty/OwlProgram/tree/develop/HeavySource

snprintf, like printf, uses heap allocations, that’s probably why you get the sbrk dependency.
Heap allocations in the audio process is a bad idea. Why do you need it, is it just for debug output?

The question is: why do you use it? → https://github.com/pingdynasty/OwlProgram/blob/develop/HeavySource/HvUtils.h#L137

I don’t think this is actually called anywhere in my build, though.

[edit: ok I realize it is called in the OG HvMessage.chttps://github.com/Wasted-Audio/hvcc/blob/feature/owl/hvcc/generators/ir2c/static/HvMessage.c so this could be the cause of this?]

We don’t use hv_snprintf, and it is true that we could hide the macro definition in a header guard. But it would make no difference.

Well yes, that’s why we have our own version of that file.

Check, I understand (kind of). I’ll look at including the overloaded file in my integration.

Also still struggling a bit to understand why/how @owl_param is used in this way, but I may start a different topic about this :slight_smile:

I’ve discussed not using @owl_param with Martin before and suggested to replace it with Heavy’s native primitive. I recall that we’ve eventually figured out that we need owl_param to be able to specify both parameter ID and name (as a string) since that’s what OWL firmware needs.

1 Like

I wonder if there is a better way to retrieve this then to “fork” the workflow like this, though.

In the end my preference would be that patches could run on various targets without too many changes.
But lets discuss that over on my repo perhaps :slight_smile:

If you have any idea how this can be achieved, it would remove a major obstacle from switching to upstream hvcc! But this might require extending hv_param to allow such optional functionality.

There are some other ideas like a @hv_enum we want to implement, so maybe a more general approach could still be useful also for other integrations.

Once we get the tests working again I hope that my branch will be the new “upstream” :wink:

1 Like

Regarding the @owl attribute: specifically what we need is the ability to assign a [send] or [receive] to a specific hardware control, such as Parameter A, or Button 5. And without resorting to ‘magic’ names, like we have to do in gen~ (because gen does not support custom attributes).

So given something like [r Gain @owl A] we know it is a parameter called Gain, assigned to A. The optional arguments for min, max and default values are nice to have but not strictly necessary.

1 Like

So what I have implemented in my fork is an optional “type” to each @hv_param. This can be fully customized in the generator how it’s employed. So far I’ve only used it for [receive] in DPF, like so: https://github.com/Wasted-Audio/hvcc/blob/develop/hvcc/generators/c2dpf/templates/HeavyDPF.cpp#L108
We need to check if this can also be used for [send] (where I think is the main issue for this).

Then maybe we could simply decide to use a type owl (or is it A B etc?) and then treat these parameters in the same way through the jdata dict?

The Daisy integration is very different, but they try to support many different i/o configurations. Your platform has a well defined i/o interface in that sense, right?

I would say that OWL’s IO params are also loosely defined, perhaps even more than what you can expect from Daisy. I.e. some devices could use a param ID as input, while others might end up with the same value as outputs. This is especially important on Magus and some upcoming hardware that is based on MAX11300 chip that can reconfigured on the fly to be input or output. This is toggled by trailing > character in parameter name and that’s also why being able to assign custom string literals is crucial on OWL.

Second difference is that params are also controllable by MIDI, so it’s not uncommon to have more params that are physically present and control them with a controller. Daisy doesn’t really have an equavalent to such generic parameters, it just lets you read knob values by ID and this means that your patch might be unusable on another device.

1 Like

@mars could you remind me how to write the metadata required to assign gen outputs? Like the output for the gate and cv outs for a gen patch to be offline compiled? Also how come this example OWL Patch Library – Rebel Technology has out 6 - what is that on the lich? I think there are only 5 outs no? or is that just the light

There’s some info about metdata in OWL docs and some butt-ugly PHP script that is used on web patcher.

1 Like

nice! thanks a lot for this info. I didn’t realize we have the means to spin up our own webserver compiler too. Don’t know how hard it is or if it is up to date, but will check it out. Knowing how to do the metadata stuff would be great for offline compiling since it is required for assining those lich controls. Anyway, will read up on it and maybe @mars will be back in the next few months and we would level up our understanding of the platform more.

I think that was made with the Witch in mind. Witch has two gate outputs, controlled with B5 and B6. And two CV outputs, corresponding to output parameters F and G.

Well the easiest thing to do is to upload the patch to the patch library, then do the assignments by setting parameters when you click Edit Patch. The parameters and buttons that show on the About patch page are used to produce the metadata file, which is generated at patch compilation.

You can otherwise add your own metadata.h to the patch source directory if you compile offline.

Here’s an example of what that might look like:

#define OWL_METADATA 1

const char* PatchMetadata::name = "Test Patch";
const int PatchMetadata::channels_in = 2;
const int PatchMetadata::channels_out = 2;
const int PatchMetadata::parameter_count = 5;
const int PatchMetadata::button_count = 4;

const PatchMetadata::Control PatchMetadata::parameters[] = {
     {PARAMETER_A, CONTROL_INPUT, "Freq"},
     {PARAMETER_B, CONTROL_INPUT, "Cutoff"},
     {PARAMETER_C, CONTROL_INPUT, "Gain"},
     {PARAMETER_F, CONTROL_OUTPUT, "Freq>"},
     {PARAMETER_G, CONTROL_OUTPUT, "Gain>"},
};

const PatchMetadata::Control PatchMetadata::buttons[] = {
     {BUTTON_A, CONTROL_INPUT, "Trigger"},
     {BUTTON_B, CONTROL_INPUT, "Overdrive"},
     {BUTTON_E, CONTROL_OUTPUT, "Trigger"},
     {BUTTON_F, CONTROL_OUTPUT, "Overdrive"}
};
1 Like

great thank you for the detailed example!

im using the offline compiler to test @antisvin 's gen~ wav file playback support which is working out really great so far. So i stumbled on this problem where i needed to do the metadata locally to play around with some tempo synced playback and slicing. Will post results!