[WIP] FaustGen - a UGen for interpreting Faust code

This is a great idea Lucas. the Faust API actually is pretty much made like this - it has a DSP factory that is made from the (sucessfully parsed) faust code and then you can spawn dsp computing objects from that so I think this is a very reasonable scenario for us!

I’ve pushed some more code today trying to seperate as much as possible of the parsing into the NRT thread.

I’ve also added a TODO list with the things we need to solve before this is good to go. I’ll soon close up shop for the summer so if anyone’s interested in working on any of these problems while I’m away from the keyboard let me know - PR’s are very very welcome!

You can already statically compile Faust DSP code to ugen using the faust2supercollider tool. The point of this FaustGen project is more of a dynamically programmable ugen AFAICS.

It would be dynamic the sc way, the server would be running and creating an ugen will be part of creating a synthdef. The difference would be in the entry point/api. I can see (dis)advantages in both approaches.

The controller approach as shown is much more direct for live coding Faust, and that is a good use case, but that implies that the synthdef graph cannot change, the dynamic entry point is the ugen, hence the input/output problem. The other way, the graph changes with the ugen which is more common in sc, the dynamic entry point is the synthdef. Regarding the control, the first approach has to set the data after a synth is created and to have two ways to set the synth parameters, /n_set for node controls and /u_cmd for ugen code. The second approach has to set the data before and the node control is as usual.


// first, better for live coding faust with f.eval

SynthDef(\test, { args otherParam; Out.ar(0, FaustGen.ar(1, otherParam)!2 * 0.5) }).add; // async

z = Synth(\test); // sync

f = FaustGenController.new(z,1);
f.eval(faustCodeOrFile); // async

z.set(\otherParam, 123); // sync

// second, I thought more idiomatic

s.sendMsg(\cmd, \load_faust, faustCodeOrFile); // async
SynthDef(\test, { args otherParam; Out.ar(0, FaustGen.ar('faustCodeName', otherParam)!2 * 0.5) }).add; // async

z = Synth(\test); // sync
z.set(\otherParam, 123); // sync

Synchronous commands are important for precise timing and each approach has a different order, that is something to consider too. I think booth approaches are complementary for different use cases. Side note, before Spacechild1 I can’t remember anything that uses /u_cmd (neither /cmd in plugins to be fair), it looks like a powerful forgotten feature to me.

1 Like

I agree and I’ve already suggested it to Mads (in private). I think, both methods you have mentioned above have their merits and should be supported.

Yeah I agree - this is something we should have.

I added support for flexible numbers of inputs/outputs today…

1 Like

Sorry for resurrecting the topic. Is there any update about the project? I can’t stop thinking about all the good things that could result from a nice embedded FaustGen object.

1 Like

Hi Bubo ! I haven’t had time to work on this in a while. Hope to get more time in the fall. The project is not too far from finished with it’s first version in my opinion. BUt among other things there are some realtime optimizations that need to be done to make the allocation safe. If you feel adventurous (and are prepared to see it change alot) you can download and compile it from source and try it out and feel free to add feedback on it for things we can add to the todo-list :slight_smile:

There are instructions for building here:

1 Like

OK Thanks! I’ll start experimenting with it :slight_smile: . I don’t really mind if there are updates breaking my code.The Faust code will still be functional!

I wanted to take some time during the holidays to try out FaustGen, but I get an error in the very end of building it (I replaced my user name with Xs):

In file included from /home/[XXX]/Downloads/git/faustgen/faust/compiler/generator/llvm/llvm_dsp_aux.cpp:44:
/home/[XXX]/Downloads/git/faustgen/faust/compiler/generator/llvm/llvm_dsp_aux.cpp: In member function ‘virtual bool llvm_dsp_factory_aux::writeDSPFactoryToMachineFile(const string&, const string&)’:
/home/[XXX]/Downloads/git/faustgen/faust/compiler/generator/llvm/llvm_dsp_aux.hh:55:36: error: ‘F_None’ is not a member of ‘llvm::sys::fs’; did you mean ‘OF_None’?
   55 | #define sysfs_binary_flag sys::fs::F_None
      |                                    ^~~~~~
/home/[XXX]/Downloads/git/faustgen/faust/compiler/generator/llvm/llvm_dsp_aux.cpp:480:56: note: in expansion of macro ‘sysfs_binary_flag’
  480 |   raw_fd_ostream out(machine_code_path.c_str(), err, sysfs_binary_flag);
      |                                                      ^~~~~~~~~~~~~~~~~

make[2]: *** [faust/build/CMakeFiles/staticlib.dir/build.make:1658: faust/build/CMakeFiles/staticlib.dir/__/compiler/generator/llvm/llvm_dsp_aux.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:269: faust/build/CMakeFiles/staticlib.dir/all] Error 2
make: *** [Makefile:156: all] Error 2

Any idea why this could be the case? Maybe something to do with the (latest) version of LLVM I have installed? (I know it caused problems with running FaustLive at some point.) Or something else?

I’m on Arch and have both the Faust and SuperCollider repositories cloned to their relevant places relative to the FaustGen repository.

EDIT: In case it’s relevant, I have LLVM version 13.0.0-6 on my system.

oh wow. That’s weird. I haven’t had time to finish faustgen yet but hope fully soon. And I also haven’t tested it since I upgraded but testing it now I get the same error as you when compiling. Oh crap. It looks like it might be an incompatibility issue between faust and llvm - will open an issue with faust.

1 Like

It seems that LLVM 13 caused some problems with Faust that have been (at least partly?) fixed in the bleeding edge version of Faust. Updating to LLVM 13 broke FaustLive for me when using the regular Faust Arch package but worked again once I switched to the git version. This was the Github issue I made back then:

Just in case this helps locating the problem.

2 Likes

I just tried installing bleeding edge faust from the github repo and compiling with that did not do the trick either.

Yes, same here, I also tried compiling FaustGen with the bleeding edge version of Faust.

ah I see you need to use the master-dev branch. I did not try that yet.

Recompiling with the master-dev branch worked! But now SuperCollider throws me this error after I recompiled the class library (again, user name Xed out):

*** ERROR: dlopen '/home/[XXX]/.local/share/SuperCollider/Extensions/FaustGen/FaustGen/FaustGen_supernova.so' err '/home/[XXX]/.local/share/SuperCollider/Extensions/FaustGen/FaustGen/FaustGen_supernova.so: undefined symbol: _ZN16llvm_dsp_factory9getTargetB5cxx11Ev'
Server 'localhost' exited with exit code 0.

I tried to delete FaustGen_supernova.so (since I’m not using Supernova anyway), but now I get the same for scsynth:

*** ERROR: dlopen '/home/[XXX]/.local/share/SuperCollider/Extensions/FaustGen/FaustGen/FaustGen_scsynth.so' err '/home/[XXX]/.local/share/SuperCollider/Extensions/FaustGen/FaustGen/FaustGen_scsynth.so: undefined symbol: _ZN16llvm_dsp_factory9getTargetB5cxx11Ev'
Server 'localhost' exited with exit code 0.

So there’s still some kind of LLVM problem. (I haven’t replaced the Faust libraries on my system with the master-dev ones though, just used the branch for compilation.)

The master-dev branch should fix the problem, but you’ll have to replace the compiled libraries.

2 Likes

Thanks! I kind of guessed so. I’ll wait with the FaustGen testrun then until the fix arrives in the master branch, don’t want to mess too much with my libraries…

The build works again now. (with faust built from master branch) If you’ve already cloned the repo and tried before it’s important to run

git submodule update --remote

Inside of the repo to update the faust submodule to include the latest changes.

1 Like

Soundfile primitive support added on this fork: Commits · sletz/faustgen-supercollider · GitHub, working on macOS for now.