Update [2022-10-11]
After some last changes we finished merging the Pull Request and you can try out Faust on HISE from HISE's develop
branch: https://github.com/christophhart/HISE/tree/develop
I updated the configuration and build instructions accordingly.
Final Submission
Over the last months I have been working on integrating the Faust DSP programming language into the HISE virtual instrument framework. With the result you can either add existing Faust DSP files to a HISE project for FX processing or use HISE as a development environment for Faust.
Code Change Summary
My efforts focused mainly on creating the 4 hi_faust*
modules, but there were other parts of the code base, I had to work on as well.
Here is a diffstat as an overview, with a description of the most important parts:
hi_faust_types
: Syntactic wrapper forlibfaust
's type headers, necessary because of namespace issues.hi_faust_lib
: Syntactic wrapper forlibfaust
code (depends onlibfaust
)hi_faust
: Static wrapper code to instantiate generated code (depends onhi_faust_types
)hi_faust_jit
: Wrapper for the just-in-time compiler (JIT), interpreter and static code generator (depends onhi_faust_lib
andhi_faust
)hi_backend
,hi_snex
: Faust-specific additions to the code export functionality were madeprojects
: Build instructions were modified to include and configure the new modules- All other changes are rather small and very specific
$ git diff upstream/develop --stat hi_backend/backend/ProjectDllTemplate.cpp | 12 +- hi_backend/hi_backend.h | 2 +- hi_backend/snex_workbench/WorkbenchProcessor.cpp | 59 ++++++- hi_core/hi_core/HiseSettings.cpp | 10 +- hi_core/hi_core/HiseSettings.h | 1 + hi_dsp_library/node_api/helpers/node_ids.h | 2 +- hi_faust/FaustStaticWrapper.h | 109 +++++++++++++ hi_faust/FaustUI.h | 296 +++++++++++++++++++++++++++++++++ hi_faust/FaustWrapper.h | 176 ++++++++++++++++++++ hi_faust/hi_faust.h | 72 +++++++++ hi_faust_jit/FaustJitNode.cpp | 277 +++++++++++++++++++++++++++++++ hi_faust_jit/FaustJitNode.h | 62 +++++++ hi_faust_jit/FaustMenuBar.h | 280 ++++++++++++++++++++++++++++++++ hi_faust_jit/FaustWrapper.h | 291 +++++++++++++++++++++++++++++++++ hi_faust_jit/hi_faust_jit.cpp | 4 + hi_faust_jit/hi_faust_jit.h | 74 +++++++++ hi_faust_lib/faust_wrap/dsp/interpreter-dsp-c-backend-placeholder.cpp | 111 +++++++++++++ hi_faust_lib/faust_wrap/dsp/interpreter-dsp-c-backend.cpp | 126 +++++++++++++++ hi_faust_lib/faust_wrap/dsp/interpreter-dsp.cpp | 111 +++++++++++++ hi_faust_lib/faust_wrap/dsp/interpreter-dsp.h | 344 +++++++++++++++++++++++++++++++++++++++ hi_faust_lib/faust_wrap/dsp/libfaust-c-backend-placeholder.cpp | 21 +++ hi_faust_lib/faust_wrap/dsp/libfaust-c-backend.cpp | 37 +++++ hi_faust_lib/faust_wrap/dsp/libfaust.cpp | 21 +++ hi_faust_lib/faust_wrap/dsp/libfaust.h | 124 ++++++++++++++ hi_faust_lib/faust_wrap/dsp/llvm-dsp-c-backend-placeholder.cpp | 137 ++++++++++++++++ hi_faust_lib/faust_wrap/dsp/llvm-dsp-c-backend.cpp | 152 +++++++++++++++++ hi_faust_lib/faust_wrap/dsp/llvm-dsp.cpp | 140 ++++++++++++++++ hi_faust_lib/faust_wrap/dsp/llvm-dsp.h | 512 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ hi_faust_lib/faust_wrap/export.h | 52 ++++++ hi_faust_lib/hi_faust_lib.cpp | 32 ++++ hi_faust_lib/hi_faust_lib.h | 78 +++++++++ hi_faust_lib/hi_faust_lib_02.cpp | 21 +++ hi_faust_types/faust_wrap/dsp/dsp.h | 301 ++++++++++++++++++++++++++++++++++ hi_faust_types/faust_wrap/export.h | 52 ++++++ hi_faust_types/faust_wrap/gui/UI.h | 90 +++++++++++ hi_faust_types/faust_wrap/gui/meta.h | 40 +++++ hi_faust_types/hi_faust_types.h | 55 +++++++ hi_modules/hi_modules.h | 3 +- hi_modules/hi_modules_02.cpp | 1 + hi_modules/nodes/HiseNodeFactory.cpp | 4 + hi_scripting/scripting/scriptnode/api/NodeBase.cpp | 12 ++ hi_scripting/scripting/scriptnode/api/NodeBase.h | 1 + hi_snex/hi_snex.h | 1 + hi_snex/snex_cpp_builder/snex_jit_ValueTreeBuilder.cpp | 19 ++- hi_snex/snex_cpp_builder/snex_jit_ValueTreeBuilder.h | 12 +- projects/standalone/HISE Standalone.jucer | 27 +++- projects/standalone/JuceLibraryCode/AppConfig.h | 25 +++ projects/standalone/JuceLibraryCode/JuceHeader.h | 4 + 48 files changed, 4381 insertions(+), 12 deletions(-)
How to Use
Configuration
In HISE under File->Preferences
set the HISE Path
and JUCE Path
for the export mechanism to work correctly.
If you use Windows or want to use a different library location than the Faust compiler expects, you also have to tell HISE where your installation of Faust is.
To do that set the Faust Path
according to the config help text.
Also (on Windows only) you need to copy the faust.dll
from your Faust installation into the directory of your HISE executable.
DSP Development Workflow
With Faust integrated into HISE, you can now add Faust nodes into a ScriptFX network.
At the time of writing Faust in HISE can only be used for (monophonic) effects.
Sound generator support (monophonic and polyphonic) is planned to be added not too far in the future, though.
In the Faust node you can add or import new Faust source files and libraries into the current HISE project.
Their file names must be valid C++ class identifiers, i.e., they may only contain alpha-numeric characters and the underscore _
and may not start with a digit.
After you added a file it will be copied to your project directory and appear as a choice in the node's drop-down menu for all Faust nodes in your current project.
Once you select a file from the drop-down menu, HISE will try to compile it on-the-fly and start processing audio right away.
It'll show an error in the log if there were any problems while compiling.
Parameters you define in your Faust code appear in the Faust node automatically if the compilation was successful. They can be modulated just like any other parameter in HISE.
While there is no integration into HISE's IDE features yet, there is a button to open the file in your text editor of choice and another one to recompile.
Export
When the faust code is ready and you want to release the project or when you need a slight performance boost over the just-in-time compiled code, you can also export the node and network and compile it statically.
HISE has had that feature already for SNEX code and I was able to extend it for Faust node as well.
Allow compilation for your ScriptFX network by right-clicking its title bar and enabling the corresponding option, then save the network.
Click Export->Compile DSP Networks as dll
and confirm that the network is present.
You can open the generated Projucer project file and compile the library with your native toolchain as usual.
When you start HISE afterwards, it'll find the dll and allow you to use the network and faust nodes in HardcodedFX
and as separate nodes in ScriptFX
without having to just-in-time compile the code again.
Get the Code
Clone the HISE repository and checkout the develop
branch or download a tarball.
How to Build on Linux
These are the manual build instructions. I intent to create a PKGBUILD for us Arch Linux folks out there in the near future - but don't hold your breath!
Prerequisites
The build process on Linux is quite straight-forward. You need GCC or Clang, the Projucer build tool, which comes with JUCE and Faust (Version 2.50.6 or later) installed. If available you should prefer the faust package that comes with your distributions package manager. You can also download it directly if you want to build it from source. If you want to use Intel's IPP library, that needs to be installed, too.
Projucer
Open the project file projects/HISE Standalone.jucer
with Projucer.
Under Modules
enable the config options HISE_INCLUDE_FAUST
and HISE_INCLUDE_FAUST_JIT
for the hi_faust
module.
It's also recommended to enable the LLVM backend for much better performance: HISE_FAUST_USE_LLVM_JIT
.
Depending on if you want to use Intel's IPP library, you can enable or disable its usage in HISE.
Select Exporters->Linux Makefile
on the left and check if USE_IPP
is set to the correct value, 0
is disabled, 1
is enabled.
If in doubt, disable it.
On the same page you also need to add faust
to External Link Libraries
.
Finally press CTRL-s
to save.1
Build
You can now go to projects/standalone/Builds/LinuxMakefile/
.
If you have nproc
installed run the following command to make a Release build if you just want to use HISE:
make CONFIG=Release -j$(nproc)
Otherwise just type in the number of cpu cores you have by hand, e.g., -j8
.
If you want to develop and/or debug HISE, a Debug build makes more sense:
make -j$(nproc)
Run
There should now be a binary build/HISE Standalone
.
Start Jack and then HISE and have fun!
How to Build on Windows
Prerequisites
To build HISE with Faust under Windows you need Visual Studio 2017 installed as well as Faust 2.50.6 or later.
JUCE already comes with HISE, so you don't need to download it separately.
If you don't want to download everything by hand, I recommend you use chocolatey
, a package manager for windows.
If you want a bit of UNIX and/or need git, you can also install
Faust is not yet available in chocolatey, so you have to download and install it manually.
Projucer
You need to add some paths to the "VisualStudio 2017" exporter in Projucer.
Open the project file projects/HISE Standalone.jucer
with Projucer.
Under Exporters->Visual Studio 2017
you need to add faust.lib
to External Link Libraries
.
Add the path to the include
directory inside your Faust installation (e.g., C:\Program Files\Faust\include
) to the Header Search Path
for both the Debug
and the Release
configuration for Visual Studio 2017
.
Similarly add the lib
directory (e.g., C:\Program Files\Faust\lib
) to the Extra Library Search Paths
.
Under Modules
enable the config options HISE_INCLUDE_FAUST
and HISE_INCLUDE_FAUST_JIT
for the hi_faust
module.
It's also recommended to enable the LLVM backend for much better performance: HISE_FAUST_USE_LLVM_JIT
.
Finally press CTRL-s
to save.
Build
In Projucer click the Visual Studio symbol near the top of the window to open the project in Visual Studio.
There you can make a Release build if you just want to use HISE or a Debug build if you want to debug and/or develop.
Afterwards you need to copy the faust.dll
from your Faust installation into the directory of your HISE executable.
How to Build on ARM macOS
Prerequisites
HISE isn't natively compatible with Apple's ARM processors, yet, but it runs well with the compatibility translation layer. In order to build HISE with Faust on macOS you need Xcode and Faust (Intel x86_64) installed. If you want to use Intel's IPP library, that needs to be installed, too.
Projucer
After downloading and extracting the Faust archive, open the Exporters
pane.
Under Exporters->Xcode
you need to add faust
to External Link Libraries
.
You need to add the paths to its include
and lib
directories to Projucer's Header Search Paths
and Extra Library Paths
respectively for both the Debug
and Release
configuration for Xcode
.
In addition you need to add the lib
path with the -rpath
option to the Extra Linker Flags
:
-rpath /adjust/this/to/your/path/to/faust/lib
Also check if USE_IPP
is set to the correct value, 0
is disabled, 1
is enabled.
If in doubt, disable it.
In the Modules
pane enable the config options HISE_INCLUDE_FAUST
and HISE_INCLUDE_FAUST_JIT
for the hi_faust
module.
It's also recommended to enable the LLVM backend for much better performance: HISE_FAUST_USE_LLVM_JIT
.
Finally press CTRL-s
to save.
Build
In Projucer click the Xcode symbol near the top of the window to open the project in Xcode. There you can make a Release build if you just want to use HISE or a Debug build if you want to debug and/or develop.
Remaining Issues and Missing Features
As mentioned in the workflow paragraph, there are some features missing which were initally planned. There currently are plans, to provide support for sound generator features and polyphony in the not-too-far future. HISE IDE integration is also likely to appear around the same time. There are also some missing features which weren't planned for the GSoC project, but will probably follow later, notably plugin support.
Footnotes
There seems to be a bug with Projucer under Archlinux, where Projucer crashes right after finishing the first export job. If that still happens to you and the Makefile wasn't exported correctly, disable/remove all other exporters before saving to ensure the Makefile is exported first.