Code Monkey home page Code Monkey logo

td-faust's Introduction

TD-Faust

TD-Faust is an integration of FAUST (Functional AUdio STream) and TouchDesigner. The latest builds are for TouchDesigner 2023.11290 and newer. Older TD-Faust builds can be found in the Releases.

Overview

  • FAUST code can be compiled "just-in-time" and run inside TouchDesigner.
  • Tested on Windows and macOS.
  • Automatically generated user interfaces of TouchDesigner widgets based on the FAUST code.
  • Up to 16384 channels of input and 16384 channels of output.
  • Pick your own sample rate.
  • Support for all of the standard FAUST libraries including
    • High-order ambisonics
    • WAV-file playback
    • Oscillators, noises, filters, and more
  • MIDI data can be passed to FAUST via TouchDesigner CHOPs or hardware.
  • Support for polyphonic MIDI.
    • You can address parameters of individual voices (like MPE) or group them together.

Demo / Tutorial:

Demo Video Screenshot

Examples of projects made with TD-Faust can be found here. Contributions are welcome!

New to FAUST?

Quick Install

Windows

Pre-compiled

Visit TD-Faust's Releases page. Download and unzip the latest Windows version. Copy TD-Faust.dll and the faustlibraries folder to this repository's Plugins folder. Open TD-Faust.toe and compile a few examples.

Compiling locally

If you need to compile TD-Faust.dll yourself, you should first install Python 3.11 to C:/Python311/ and confirm it's in your system PATH. You'll also need Visual Studio 2022 and CMake. Then open a "x64 Native Tools for Visual Studio" command prompt with Administrator privileges to this repo's root directory and run python build_tdfaust.py.

macOS

Pre-compiled

Visit TD-Faust's Releases page. Download and unzip the latest macOS version. Users with "Apple Silicon" computers should download "arm64". Copy TD-Faust.plugin and Reverb.plugin to this repository's Plugins folder.

Open TD-Faust.toe and compile a few examples.

Compiling locally

  1. Clone this repository with git. Then update all submodules in the root of the repository with git submodule update --init --recursive
  2. Install Xcode.
  3. Install CMake and confirm that it's installed by running cmake --version in Terminal. You may need to run export PATH="/Applications/CMake.app/Contents/bin":"$PATH"
  4. Install requirements with brew: brew install autoconf autogen automake flac libogg libtool libvorbis opus mpg123 pkg-config
  5. In the same Terminal window, navigate to the root of this repository and run python3 build_tdfaust.py --pythonver=3.11
  6. Open TD-Faust.toe

Building a Custom Operator

We have previously described a multi-purpose CHOP that dynamically compiles Faust code inside TouchDesigner. Although it's powerful, you have to specify the DSP code, press the compile parameter, and only then do the CHOP's parameters appear. In contrast, ordinary CHOPs can be created from the OP Create Dialog and already have parameters, but they are narrower in purpose. What if you want to use Faust to create a more single-purpose Reverb CHOP with these advantages? In this case, you should use the faust2touchdesigner.py script.

These are the requirements:

  • Pick a Faust DSP file such as reverb.dsp that defines a process = ...;.
  • Python should be installed.
  • CMake should be installed.

If on Windows, you should open an "x64 Native Tools for Visual Studio" command prompt. On macOS, you can use Terminal. Then run a variation of the following script:

python faust2td.py --dsp reverb.dsp --type "Reverb" --label "Reverb" --icon "Rev" --author "David Braun" --email "github.com/DBraun" --drop-prefix

Limitations and Gotchas:

  • Use python3 on macOS.
  • The example script above overwrites Faust_Reverb_CHOP.h, Faust_Reverb_CHOP.cpp, and Reverb.h, so avoid changing those files later.
  • Polyphonic instruments have not been implemented.
  • MIDI has not been implemented.
  • The soundfile primitive has not been implemented (waveform is ok!)
  • CHOP Parameters are not "smoothed" automatically, so you may want to put si.smoo after each hslider/vslider.
  • File a GitHub issue with any other problems or requests. Pull requests are welcome too!

Tutorial

Writing Code

You don't need to import("stdfaust.lib"); in the FAUST dsp code. This line is automatically added for convenience.

Custom Parameters in TouchDesigner

  • Sample Rate: Audio sample rate (such as 44100 or 48000).
  • Polyphony: Toggle whether polyphony is enabled. Refer to the Faust guide to polyphony and use the keywords such as gate, gain, and freq when writing the DSP code.
  • N Voices: The number of polyphony voices.
  • Group Voices: Toggle group voices (see below).
  • Dynamic Voices: Toggle dynamic voices (see below).
  • MIDI: Toggle whether hardware MIDI input is enabled.
  • MIDI In Virtual: Toggle whether virtual MIDI input is enabled (macOS support only)
  • MIDI In Virtual Name: The name of the virtual MIDI input device (macOS support only)
  • Code: The DAT containing the Faust code to use.
  • Faust Libraries Path: The directory containing your custom faust libraries (.lib files)
  • Assets Path: The directory containing your assets such as .wav files.
  • Compile: Compile the Faust code.
  • Reset: Clear the compiled code, if there is any.
  • Clear MIDI: Clear the MIDI notes (in case notes are stuck on).
  • Viewer COMP: The Container COMP which will be used when Compile is pulsed.

Python API

The Faust CHOP's Python interface is similar to the Audio VST CHOP.

  • sendNoteOn(channel: int, note: int, velocity: int, noteOffDelay: float=None, noteOffVelocity: int=None) -> None (noteOffDelay and noteOffVelocity aren't used yet)
  • sendNoteOff(channel: int, note: int, velocity: int) -> None
  • panic() -> None
  • sendAllNotesOff(channel: int) -> None
  • sendControl(channel: int, ctrl: int, value: int) -> None
  • sendPitchBend(channel: int, wheel: int) -> None
  • sendProgram(channel: int, pgm: int) -> None

Automatic Custom Parameters and UI

One great feature of TD-Faust is that user interfaces that appear in the Faust code become Custom Parameters on the Faust Base. If a Viewer COMP is set, then it can be automatically filled in with widgets with binding. Look at the simple Faust code below:

import("stdfaust.lib");
freq = hslider("Freq", 440, 0, 20000, 0) : si.smoo;
gain = hslider("Volume[unit:dB]", -12, -80, 20, 0) : si.smoo : ba.db2linear;
process = freq : os.osc : _*gain <: si.bus(2);

If you compile this with a Faust Base, the Base will create a "Control" page of custom parameters. Because of the code we've written, there will be two Float parameters named "Freq" and "Volume". In order to automatically create a UI, pressing compile will save a JSON file inside a directory called dsp_output. These files are meant to be temporary and are deleted each time TD-Faust.toe opens.

Group Voices and Dynamic Voices

The Group Voices and Dynamic Voices toggles matter when using polyphony.

If you enable Group Voices, one set of parameters will control all voices at once. Otherwise, you will need to address a set of parameters for each voice.

If you enable Dynamic Voices, then voices whose notes have been released will be dynamically turned off in order to save computation. Dynamic Voices should be on in most cases such as when you're wiring a MIDI buffer as the third input to the Faust CHOP. There is a special case in which you might want Dynamic Voices off:

  • You are not wiring a MIDI buffer as the third input.
  • Group Voices is off.
  • You are individually addressing the frequencies, gates and/or gains of the polyphonic voices. This step works as a replacement for the lack of the wired MIDI buffer.

Control Rate and Sample Rate

The sample rate is typically a high number such as 44100 Hz, and the control rate of UI parameters might be only 60 Hz. This can lead to artifacts. Suppose we are listening to a 44.1 kHz signal, but we are multiplying it by a 60 Hz "control" signal such as a TouchDesigner parameter meant to control the volume.

import("stdfaust.lib");
volume = hslider("Volume", 1., 0., 1., 0);
process = os.osc(440.)*volume <: si.bus(2);

In TouchDesigner, we can press "Compile" to get a "Volume" custom parameter on the "Control" page of the Faust base. You can look inside the base to see how the custom parameter is wired into the Faust CHOP. By default, this "Volume" signal will only be the project cook rate (60 Hz). Therefore, as you change the volume, you will hear artifacts in the output. To reduce artifacts, there are three solutions:

  1. Use si.smoo or si.smooth to smooth the control signal: volume = hslider("Volume", 1., 0., 1., 0) : si.smoo;

  2. Create a higher sample-rate control signal, possibly as high as the Faust CHOP, and connect it as the second input to the Faust base.

  3. Re-design your code so that high-rate custom parameters are actually input signals.

import("stdfaust.lib");
// "volume" is now an input signal
process = _ * os.osc(440.) <: si.bus(2);

You could then connect a high-rate single-channel "volume" CHOP to the first input of the Faust Base.

Using TD-Faust in New Projects

From this repository, copy the toxes/FAUST structure into your new project. You should have:

  • MyProject/MyProject.toe
  • MyProject/toxes/FAUST/FAUST.tox

and any other files which are sibling to FAUST.tox

Now drag FAUST.tox into your new TouchDesigner project, probably near the root. FAUST.tox acts as a Global OP Shortcut. Next, copy toxes/FAUST/main_faust_base.tox into the project and use it in a way similar to how it's used in TD-Faust.toe.

Licenses / Thank You

TD-Faust (GPL-Licensed) relies on these projects/softwares:

td-faust's People

Contributors

dbraun avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

td-faust's Issues

Build issue

Ran into this error when running "python download_libfaust.py " Anyone seen this before/ know how to fix this?

(base) me@my-MacBook-Pro-2 libfaust % python download_libfaust.py
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 141M 100 141M 0 0 2423k 0 0:00:59 0:00:59 --:--:-- 2551k
Checksumming Protective Master Boot Record (MBR : 0)…
Protective Master Boot Record (MBR :: verified CRC32 $1F22BD08
Checksumming GPT Header (Primary GPT Header : 1)…
GPT Header (Primary GPT Header : 1): verified CRC32 $BDFECAC7
Checksumming GPT Partition Data (Primary GPT Table : 2)…
GPT Partition Data (Primary GPT Tabl: verified CRC32 $5FD1D292
Checksumming (Apple_Free : 3)…
(Apple_Free : 3): verified CRC32 $00000000
Checksumming disk image (Apple_HFS : 4)…
...............................................................................
disk image (Apple_HFS : 4): verified CRC32 $9E5C0C1A
Checksumming (Apple_Free : 5)…
(Apple_Free : 5): verified CRC32 $00000000
Checksumming GPT Partition Data (Backup GPT Table : 6)…
GPT Partition Data (Backup GPT Table: verified CRC32 $5FD1D292
Checksumming GPT Header (Backup GPT Header : 7)…
GPT Header (Backup GPT Header : 7): verified CRC32 $72804D70
verified CRC32 $E9E44F69
/dev/disk9 GUID_partition_scheme
/dev/disk9s1 Apple_HFS /Volumes/Faust-2.70.3
cp: /Volumes/Faust-2.70.3/Faust-2.70.3/: No such file or directory
Traceback (most recent call last):
File "/Users/me/Desktop/TD-Faust/thirdparty/libfaust/download_libfaust.py", line 55, in
main(args.version)
File "/Users/me/Desktop/TD-Faust/thirdparty/libfaust/download_libfaust.py", line 42, in main
install_macos(version)
File "/Users/me/Desktop/TD-Faust/thirdparty/libfaust/download_libfaust.py", line 27, in install_macos
subprocess.run(["cp", "-R", f"/Volumes/Faust-{version}/Faust-{version}/
", dir_path], check=True)
File "/Users/me/anaconda3/lib/python3.11/subprocess.py", line 571, in run
raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['cp', '-R', '/Volumes/Faust-2.70.3/Faust-2.70.3/*', 'darwin-arm64/Release']' returned non-zero exit status 1.

Shouldn't need to Setup UI after every Compile

Right now, if you press "Compile" the dsp name will change ("my_dsp_5"), and so you'll need to hit "Setup UI" again. This can be avoided if we revise the whole setup UI pipeline with JSON.

Use Text COMP as code editor

The latest official builds of TouchDesigner introducted the Text COMP. This could be used as a fully featured code editor inside TouchDesigner. The default TD-Faust project should demonstrate a better looking live coding environment, a lot more like the online Faust IDE. The main Faust base tox might be improved too.

nentry items need to be rescaled

If you use an nentry primitive, then it takes an initial value, a min, a max, and a step size. However, TouchDesigner menu parameters are all integers and have no notion of "step size". So for these nentry parameters, the automatically generated UI right now is creating a CHOP holding integers when it should be doing stuff with step size.

Setup UI misses effects on polyphonic instruments

Example dsp:

declare options "[nvoices:6]";
//declare nvoices "6";

import("stdfaust.lib");
// polyphonic control parameters:
freq = hslider("freq", 440., 0., 18000., 0.);
gain = hslider("gain", 0., 0., 1., 0.);
gate = button("gate");
// other controls:
cutoff0 = hslider("Cutoff 0", 40., 30., 20000., .0) : si.smoo;
cutoff1 = hslider("Cutoff 1", 15000., 30., 20000., .0) : si.smoo;
cutoff2 = hslider("Cutoff High", 15000., 30., 20000., .0) : si.smoo;

env1 = gate : en.adsr(0.001, 0.2, 0., .1);
cutoff = cutoff0, cutoff1 : it.interpolate_linear(env1);
myOsc = os.sawtooth(freq) * env1 * gain;
filter = fi.lowpass(2, cutoff);

process = myOsc : filter <: _, _;
effect = sp.stereoize(fi.highpass(2, cutoff2));

In this example, the "Setup UI" button in TouchDesinger will create a UI that doesn't have "Cutoff High" because it's on the effect. If we transition from relying on XML to relying on JSON we should be able to more easily build a UI with all the necessary components. In the short term, you can usually just put the effect code in a separate Faust Audio CHOP.

theDsp->buildUserInterface(&m_jsonui);  // assume JSONUI m_jsonui; is in header
std::cerr << m_jsonui.JSON(false) << std::endl;  // need to give this back to TouchDesigner via Python

Hardware MIDI Polyphony requires twice as many voices as necessary

I'm using a MIDI controller. If I use faust code for 6 voices and select 6 voices for the Nvoices custom parameter, it only yields 3 effective voices.

declare options "[midi:on]";
declare options "[nvoices:6]";
import("stdfaust.lib");

freq = hslider("freq",60,36,96,1) +24 : ba.midikey2hz;
gain = hslider("gain",1,0,1,0.01);
gate = button("gate");
envelope = en.adsr(0.1,0.2,0.9,0.3,gate)*gain;

panVal = hslider("pan[midi:ctrl 41]", 0,0,1,.01) : si.smoo;

process = os.osc(freq)*envelope : sp.panner(panVal) <: _,_;

effect = dm.zita_light ;

If I set the parameters and code to 8 voices, I get just 4.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.