GSoC: Final Submission

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 for libfaust's type headers, necessary because of namespace issues.
  • hi_faust_lib: Syntactic wrapper for libfaust code (depends on libfaust)
  • hi_faust: Static wrapper code to instantiate generated code (depends on hi_faust_types)
  • hi_faust_jit: Wrapper for the just-in-time compiler (JIT), interpreter and static code generator (depends on hi_faust_lib and hi_faust)
  • hi_backend, hi_snex: Faust-specific additions to the code export functionality were made
  • projects: 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


1

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.


2022-10-07