VCVRack / VCV-Prototype

Other
130 stars 23 forks source link

Add Faust script engine #10

Closed AndrewBelt closed 3 years ago

AndrewBelt commented 4 years ago

http://faust.grame.fr/

Advantages:

Disadvantages:

agraef commented 4 years ago

LLVM isn't a strict requirement. It's needed for loading Faust dsps dynamically as LLVM bitcocde, but there are other, more traditional ways to run Faust dsps as plugins in other environments. Indeed, that's what Faust is all about, support as many plug-in environments as humanly possible. :) So we could just make the VCV plugin format one of our targets in Faust, rather than supporting Faust scripting via the embedded Faust->LLVM JIT compiler.

I've been involved with Faust development and I've written quite a few Faust architectures over the years, like pd-faust, faust-lv2 and faust-vst. And I've also dabbled around with VCV quite a bit lately, and I really love it! So I'm tempted to do a VCV architecture for Faust some time in the not-too-distant future. If noone beats me to it, that is. ;-)

In fact, I can already run Faust modules inside VCV Rack using VCV Host and faust-vst, see the screenshot below (the Faust modules there are karplus, chorus and freeverb in the second row of the rack). But of course having proper VCV support in Faust would make things easier/nicer, since a proper GUI could be generated automatically from the Faust program.

vcv-faust

pauldavisthefirst commented 4 years ago

Albert, it's the not-too-distant future. Go for it!

AndrewBelt commented 4 years ago

@agraef You could write a transformer from Faust to Rack plugins, but this issue is orthogonal to that. VCV Prototype is designed to allow users to write scripts for VCV Prototype in several languages. In order to do that, some way of interpreting Faust will have to be included in VCV Prototype.

agraef commented 4 years ago

@pauldavisthefirst Thanks for the reminder. :) Unfortunately, I haven't had the time to dive into VCV's plugin API yet, and with all the remote teaching currently going on over here, I'm swamped with other things. I'd still like to get on with it, but it'll probably be some weeks before I'll have enough spare time on my hands again.

@AndrewBelt Yes, I realize that this issue is about something different, but I only volunteered to do the Faust architecture bit, because that's the part that I'm most proficient with. Stephane Letz would be the right guy to get in touch with for the scripting approach, as he's written the libfaust interface and consequently knows it much better than I do.

sletz commented 4 years ago

In progress here. BTW I'm working with @mzuther to possibly share some DSP or C++ architecture files he developed for his ProtoFaust project. We also have a backend using the fresh MIR project, see https://github.com/vnmakarov/mir/issues/54, which could be an alternative to LLVM at some point, even if slower.

agraef commented 3 years ago

@sletz Very nice, thank you, also to @mzuther for your work! And sorry again for dropping the ball on this, there's been so much other stuff to do.

sletz commented 3 years ago

PR here, using the Interpreter backend which is much simpler to compile: https://github.com/VCVRack/VCV-Prototype/pull/44. Now the point is to check if the speed is acceptable.

AndrewBelt commented 3 years ago

@sletz I've merged your PR to the faust branch of this repository and gave you write access. The branch is not ready to be merged into the main v1 branch because I need to learn how it works first.

sletz commented 3 years ago
  • What is temp_cache? Why do we need it? It seems too hacky for production.

temp_cache is used to save/restore a precompiled byte code version of the DSP. This speed up loading patches that contains Faust DSP code. Is there a less hacky way to implemented this cache idea?

  • Why use std::function? Typically there are cleaner ways to achieve what std::function does.

This is used to implement controller update by creating callback functions. What do you suggest as a cleaner way ?

  • When I load a .dsp file in VCV Prototype, no sound is generated and this is directly printed to the terminal.
which: no faust in (/usr/bin/:... the rest of my PATH)

As explained here the Faust compiler is used in an embedded way, that is using it as a library and dynamically compiling/executing DSP programs, using the Interpreter backend. This is easier than having to compile to LLVM IR and embed the full LLVM compilation chain.

Have you followed what is described here ?

First, nothing should print directly to stdout/stderr. It should go through Rack's logger such as WARN(...). Second, I get no feedback in Prototype's LED display that it's not working. It just says "Created DSP", not very descriptive. Third, it seems that FaustEngine relies on an external binaries. Everything should run in Rack's OS process.

First we need to be sure the described compilation process works for you.

  • It would be nice to port some of the examples like gain, rainbow, and vco to Faust. It's also required to have a template.dsp example that is copied when the user selects "New script".

OK.

AndrewBelt commented 3 years ago

Is there a less hacky way to implemented this cache idea?

How long does loading a .dsp script take without a cache?

the Faust compiler is used in an embedded way, that is using it as a library

Then why is something executing which faust? Why does the plugin care to know where a faust binary is in my PATH?

sletz commented 3 years ago

How long does loading a .dsp script take without a cache?

It can take several seconds, multiplied by the number of VCV Prototypes instances that may be used.

Then why is something executing which faust? Why does the plugin care to know where a faust binary is in my PATH?

I don't see that, but I've fixed several issues related to Faust libraries handling that could explain incorrect behaviour. Can you test again if you can load and execute the provided DSP examples.

sletz commented 3 years ago
  • It would be nice to port some of the examples like gain, rainbow, and vco to Faust. It's also required to have a template.dsp example that is copied when the user selects "New script".

Done.

jatinchowdhury18 commented 3 years ago

Hi @sletz,

Thanks for all your great work on this! I've been following for a while, and just now had a chance to do some testing.

On my Windows machine, I had to add the following to FaustEngine.cpp, otherwise GetTempPath() was undefined.

#if defined ARCH_WIN
    #include <windows.h>
#endif

After that, the plugin compiled, but when I tried loading an example file, the LED display read "No engine for .dsp extension", but I wasn't able to find any more information either from the log files, or stdout. I'll try to investigate this a bit more...

On my Macintosh, everything worked as expected!

Thanks, Jatin

sletz commented 3 years ago

On my Windows machine, I had to add the following to FaustEngine.cpp, otherwise GetTempPath() was undefined.

#if defined ARCH_WIN
    #include <windows.h>
#endif

Committed thanks.

After that, the plugin compiled, but when I tried loading an example file, the LED display read "No engine for .dsp extension", but I wasn't able to find any more information either from the log files, or stdout. I'll try to investigate this a bit more...

Does the libfaust dependancy correctly compiles ?

(make dee && make && make install)

On my Macintosh, everything worked as expected!

Thanks for reporting.

sletz commented 3 years ago

After that, the plugin compiled, but when I tried loading an example file, the LED display read "No engine for .dsp extension",

Each scripting engine is registering itself with something like: https://github.com/VCVRack/VCV-Prototype/blob/faust/src/FaustEngine.cpp#L369

Then the generic code instantiates the needed one here: https://github.com/VCVRack/VCV-Prototype/blob/v1/src/Prototype.cpp#L334

So you'll have to debug this code, see if the registration step correctly works, then check the loading part.

sletz commented 3 years ago

@AndrewBelt Any chance to have the Faust branch merged at some point ? Or do you need me to still improve something ?

sletz commented 3 years ago

Branch merged by Andrew and README updated in https://github.com/VCVRack/VCV-Prototype/commit/5899bd77be376f6c2a6427857f7614cae171f906