Faust problems

Hi,

I’ve got Owl Modular mostly for running some Faust code on it, but so far it’s not very encuraging.

  1. This simple patch for using comb filter from Faust’s standard library gives unexpected results.
import("filter.lib");

maxdel = 12;
md = pow(2, maxdel) : int;

comb_delay = hslider("Comb delay [OWL:PARAMETER_A]", 256, 0, md, 1);
g     = hslider("Comb neg FB gain [OWL:PARAMETER_B]", 1, 0, 1, .001);
it    = hslider("Interpolate [OWL:PARAMETER_C]", 1024, 1, 2048, 1);

process = fbcombfilter(md, comb_delay, g);

The sound gets distorted instantly instead of applying comb filtering as long as delay is above 0. The amount of distortions gets higher with lower buffer settings used by module, but even with largest buffer it still distorts. CPU usage is very low, typically around 5%. And the patch works as expected if I run the same code on my desktop.

  1. I often run into situations where my code won’t compile due to old version of Faust installed here. Sometimes its a matter of changing some imports, but ofent it has led to segfaults, misterious data type errors or failures to compile code that works fine with current version of Faust. To make things worse, I can’t even find info which version is running here (looks like most of the work happened 3+ years ago?). Is there any possibility to bring Faust’s version up to date? There’s been many additions to their libraries and I believe also many improvements have been made for compiling code.

  2. Another problem that I’ve ran into is that if I try to run faust2owl on latest Faust, it just segfaults for me. So I can’t generate a patch on current dev version and after trying a few older version I didn’t find the one that works. Before I start troubleshooting it and asking Faust developers for help, could you confirm that its supposed to work after just installing Faust itself, or do I have to install something else in order for it to work? My impression is that it faust2owl would use a template file for generating C++ file for Owl patch and should work out of the box, so that must be a regression in Faust environment.

hello antisvin, very happy to hear you’re a Faust coder!

Yes the Faust part of the system has been a little neglected recently, I’d be glad to bring it up to date. What version are you running?

  1. we use OwlProgram to compile patches for the OWL. There are instructions in the README: GitHub - pingdynasty/OwlProgram: Dynamically loaded OWL program
    Instead of calling faust2owl we use our own version of the OWL architecture file with faust -a FaustCode/owl.cpp
    It is possible we need to push some changes to the Faust project. Is it faust2owl itself which crashes?
    The code that is produced is not meant to run stand alone, but to be cross compiled to run on the OWL. For this you need the libraries and tools in the OwlProgram project.

The Faust version we are using on the live server is v0.9.72

I’m having problems compiling even some of the Faust examples (e.g. clarinet.dsp) with the current master Faust branch. Same with release v0.9.90.

Getting errors like these: effect.lib:47: ERROR: redefinition of symbols are not allowed : BoxIdent[levelfilter] is already defined in file "effect.lib" line 47

Recognise that?

Hi Martin,

I forgot to mentioned I’m running this on Linux, btw.

I was initially running latest version from Faust github, although right now I’ve downgraded to stock version from ubuntu repository - 0.9.95 but that didn’t help with segfaults. I’m more interested in running development version because there’s beeen some awesome additions with physical modeling library - http://faust.grame.fr/library.html#physmodels.lib . Not the easiest synthesis method to understand, but I’m hoping to run some of that stuff on Owl.

Now back to troubleshooting.

Since faust2owl is just a bash wrapper script, the segfault certainly comes from the faust executable. I haven’t realized that there’s a custom version of owl.cpp in OwlSim, but actually it only differs with a single header include path - faust/audio/dsp.h has been renamed to faust/dsp/dsp.h in recent Faust.

The good news is that simply running faust -a FaustCode/owl.cpp works without segfaults withe either of those files. I’ll check if I will be able to eventually compile that later today and will write some updates here.

What faust2owl runs is faust -i -inpl -a owl.cpp -cn mypatch mypatch.dsp -o TEMPFILE_NAME and the segfault disappears if I remove -inpl flag. OwlProgram makefile also includes this flags, so it was crashing when I’ve tried using it before. Looks like I’ll have to troubleshoot this with faust devs and also compare both backends (it can be built with GCC or LLVM and they sync both branches simultaneously).

I surely have seen issues with imports, but going the other way around - running code from recent version on older one that Owl currently uses as host environment.

They’ve made some rearrangements with module imports. Now the recommended way is to just add import(“stdfaust.lib”)’ and use short fully qualified names. I can tell that in current version they’ve moved that function to filters.lib, while effects.lib has been removed (or more like deprecated, since it’s still present as old/effects.lib). So you would usefi.levelfilter` in this case.

I think that current approach looks less messy (you don’t have to remember exact library name). But it’s likely to have some backwards compatibility problems with older versions. I could spend some time to check current faust patches in OwlPatches repo if you think this effort would help. But for offering recent Faust in Owl web interface you’d probably have to support both versions in order to prevent existing user patches from breaking. Don’t know if it’s realistic to expect that to happen.

So far the latest version I can get to work locally is 0.9.85, which is the last release before they rearranged the libraries. I see no reason not to upgrade the live server to this version.

As you point out, the later versions break backwards compatibility. I was just thinking the other day how we’re going to need, sooner or later, some way of selecting the compiler version in the online compiler…

Apart from that, I’ve not been able to compile faust2 from source, nor have I had much joy with the master branch, as several Faust examples are not working for me.

physmodels.lib looks interesting, is it the successor to FAUST-STK? Romain Michon - Faust-STK

One of the examples I can’t get to compile in the latest faust code is faust/examples/faust-stk/clarinet.dsp, which we have a version of as an OWL patch: https://hoxtonowl.com/patch-library/patch/Clarinet/

Sorry to hear about your problems compiling. I think both branches worked for me every time I’ve updated them from GIT and I don’t have problems building from their latest commits (just checked it).

I think that physmodels.lib is a brand new library mostly written from scratch. Besides the actual instrument models it has generic code for physical modeling and stuff like 3D CAD models import. It looks like they’ve ported most if not all faust-stk examples using primitives in that library. I.e. compare faust/clarinet.dsp at 0.9.73-mr2 · grame-cncm/faust · GitHub and https://github.com/grame-cncm/faust/blob/master-dev/libraries/physmodels.lib#L1567-L1578 . The code is quite different and actually looks more meaningful to me now. I guess with the new version you should just replace that patch with the one using physmodels.lib

They’ve also added DX7 emulator as a separate library - something that I didn’t really expect to see. It’s not even in their reference docs yet, but the code is here - Romain Michon - Faust Tutorials

FYI I’ve updated the live site version to FAUST v0.9.85, which supports the old style libraries and doesn’t break our existing patches.

Ok, so I can definitely see some improvement with the patch that was giving me problems. The old env wouldn’t build due to missing oscp (an oscillator with phase control in oscillators.lib). Then I’ve copied missing code from latest faust and it would build, but fail with segfault.

Now I can build it without that copy-pasted code, but it still segfaulted. I’ve made a few changes to cleanup code and instead of a segfault I’ve got a more meaningful error message:

/opt/OwlProgram.online/Tools/gcc-arm-none-eabi-5_2-2015q4/bin/…/lib/gcc/arm-none-eabi/5.2.1/…/…/…/…/arm-none-eabi/bin/ld: /tmp/owl/owl-build-ysn9Fo/patch.elf section.bss’ will not fit in region PATCHRAM’ /opt/OwlProgram.online/Tools/gcc-arm-none-eabi-5_2-2015q4/bin/…/lib/gcc/arm-none-eabi/5.2.1/…/…/…/…/arm-none-eabi/bin/ld: regionPATCHRAM’ overflowed by 478944 bytes collect2: error: ld returned 1 exit status make[1]: *** [/tmp/owl/owl-build-ysn9Fo/patch.elf] Error 1 make: *** [patch] Error 2 ERROR: Patch build failed.`

So I guess the patch was trying to reserve too much RAM to run on actual hardware. It’s a bit surprising, since it was running an additive oscillator and I thought that current implementation in Faust should be summing sines on the fly. So I’d expect it to waste CPU but use very little memory. I will try using a precomputed table to see what difference does it make.

The good news is that I’ve figured out how to cross-compile code in OwlProgram - that is using latest faust. I get the same memory error, which is expected. I also had to rebuild FirmwareSender since current binary segfaulted on me during patch upload.

I’ve tried building one of physical models (brass) and it works great. CPU usage goes to 56-60% at lowest buffer size setting, memory is 16824. Most of those models use more modulation inputs than Owl has, so I’d have to either use MIDI for additional parameters or control more than one channel with a single parameter (i.e. control vibrato frequency and amplitude with a single scaled input).

I need to access gate input in my patch. I can see the LED changing color on high signal, but doesn’t seem like I can do anything useful with it now. I see that Faust file has access to params A-E, but not gates (push buttons).

Also, it seems like it would make more sense to represent gate in / out as separate IO channels, since there’s no way to set the parameter in faust.

Good work, glad you got it working.

Button: we never figured out how to make this work in Faust.

In the architecture file there are buttons and checkbuttons which are currently ignored.

Looking at the code, I think I can put something together to make the buttons available, but my Faust isn’t good enough to know if I’ve done it right.
And yes, setting the gate will be an issue. A separate IO channel would be possible but we would have to scan it at the end of each block to check if it has changed, which will incur an overhead.

Another thing I’m unclear about is MIDI: how does Faust handle incoming MIDI notes?

@Stas I’ve added button support so that you can read the Pushbutton state with a Faust button.

It’s in the current OwlProgram master branch. I’ve not deployed it to live yet, I’d like to test against a few more patches first. Let me know if you try it out. To use it, add [OWL:Push] to a button or checkbutton.

Also I’ve made the PARAMETER_ part of [OWL:PARAMETER_X] optional, so you can use [OWL:A] et c.

This looks very useful for when / if we switch to the new Faust version, a script that converts to the new style libraries: faustCompressors/newlib.sh at master · magnetophon/faustCompressors · GitHub

Regarding your PATCHRAM overflow issue, I’m finding the same thing with newer versions of Faust. It turns out they now generate a 65k table of floats for math calls such as sin. This is why the patches no longer fit in memory. I’m looking into options.

Faust support MIDI the same way as it does OWL CV inputs - using parameter metadata. It’s actually has decent MIDI integration IMO - http://faust.grame.fr/news/2016/01/14/controlling-with-midi.html . If you look into physmodels.lib, most of the instruments defined there also have a MIDI-enabled frontend.

I haven’t tried using it on OWL yet, but I will eventually want to write a few patches controllable with faders, i.e. a filterbank and maybe some additive oscillators.

Here’s an example of clarinet patch based on physmodels lib.

import("stdfaust.lib");

process = pm.clarinetModel(freq : pm.f2l, pressure, reedStiffness, bellOpening)
with{
        freq = hslider("Frequency[OWL:PARAMETER_A]",440,50,1000,0.01);
        reedStiffness = hslider("Reed stiffnes[OWL:PARAMETER_B]",0.5,0,1,0.01);
        bellOpening = hslider("Bell opening[OWL_PARAMETER_C]",0.5,0,1,0.01);
        breathGain = hslider("Breath gain[OWL:PARAMETER_D]", 0.1,0,1,0.01)*0.05;
        pressure = hslider("pressure[OWL:PARAMETER_E]", 0, 0, 1, 0.01) : si.smoo;
        blow = pm.blower(pressure, 0.05, breathGain,vibratoFreq,vibratoGain);
        // Don't bother with vibrato - we can modulate frequency instead
        vibratoFreq = 0.1;
        vibratoGain = 0.1;
};

I plan to convert all instruments from that lib to OWL (15 in total, although 6 of them are different bell models). Then I’ll look into creating custom firmware (I’ve understood how to do it from reading docs). I will consider porting some from faust-stk code as well, but it doesn’t have a very a proper model separation and may require some refactoring .

I will certainly try using push button. Regarding output - the only other possibility I can think of would be by using foreign function calls API. But I’m not sure if we can expose patch object state like that and I AM sure that it would be more cumbersome to use. Example for this feature:

SR = fconstant(int fSamplingFreq, <math.h>);
BS = fvariable(int count, <math.h>);
tanh = ffunction(float tanhf (float), <math.h>,"");

As for oscillator’s memory usage - I suppose you mean sinwaveform table. To make things worse, I was using oscp function that also ends up creating another table for cosine data. I will try to rewrite my code to use a single table instead of oscp. That should cut memory by 65k and I can likely use a smaller table size. Calculating sines on the fly could be a bad idea in this particular case, because I want to use 10-20 oscillators as partials at once for this patch.

Maybe you’ll have to use a patched oscillators.lib on server that would create smaller tables if there won’t be noticable degradation.

Edit: I was wrong about tables being generated for sin or other math calls. Certain oscillators e.g. osci will generate tables. But the default osc will not.

Incidentally sin and cos calls are very efficient on the OWL, as we have implementations optimised for the hardware.

Foreign functions - I didn’t know about these. Looks interesting, we can probably use them to set output parameters.

Haven’t found any issues with latest update and gate input works as expected.

If we’ll end up using foreign function calls for gate output, it makes sense to add a library that would have a wrapper for this. That would be slightly prettier. But I don’t quite see how this can be handled without performance overhead. We’d still be streaming data into that unit for every sample, because that’s how Faust works.

And we’ll have to check if output button’s state changed for every sample, it could be that runnning a single pass over the whole buffer gives a smaller performance hit. The good thing here is that it happens only if gate out function call is actually used by the patch.

But I have another concern about using FFI call. If it would send the gate immediately, that could bring audio and gate output out of sync. For example, I was thinking about a patch where we have a clocked output with divider/multiplier settings and want to send triggers when a new cycle begins. Or is there some buffering for sending gate and audio outputs at the same time?