DBraun / DawDreamer

Digital Audio Workstation with Python; VST instruments/effects, parameter automation, FAUST, JAX, Warp Markers, and JUCE processors
GNU General Public License v3.0
850 stars 67 forks source link

RFE: Programmatic routing of modular synthesizers #16

Open DBraun opened 3 years ago

DBraun commented 3 years ago

Can we build complex modular synthesizer routings with Python code? Controlling a synthesizer's filter cutoff with an ADSR?

Mockup code:


synth = engine.make_synth_processor()

adsr1 = synth.make_adsr()  # for controlling volume
adsr2 = synth.make_adsr()  # for controlling filter cutoff

wavetable = synth.make_wavetable()  # default sine wave based on MIDI key.

filter = synth.make_filter(mode='low')  # low-pass filter
filter.freq = 7000.  # baseline cutoff in Hz.

# connect wavetable to filter and then filter to synth output
wavetable.output.connect(filter.input)  # ugly?
filter.output.connect(synth.output)

routing1 = adsr1.output.connect(wavetable.level, mode='unipolar', amount=1.)  # control volume
routing2 = adsr2.output.connect(filter.freq, mode='unipolar', amount=2000.)  # control cutoff

# finally, make graph
graph = [
    (synth, [])  # no inputs necessary to this synth
]

engine.load_graph(graph)
engine.render(10.)

# change parameters or routing and render again
filter.mode = 'bandpass'  # switch to bandpass filter.
routing2.amount = 3000.

engine.render(10)

synth.remove_routing(routing2)  # remove the filter routing

engine.render(10)

Another cool audio project is signalflow which has similarities to TensorFlow. You create nodes and use built-in operators on them such as +, -, /, *, %.

shakfu commented 3 years ago

Check out my py2max project, which is an library to read and generate max patches offline. It basically a think python wrapper around the Max JSON-based .maxpat file format which basically describes a directed graph where nodes or 'boxes' in Max parlance can contain graphs of other node to represent the max abtraction, bpatcher, sub patchers, poly object, gen~ object...

DBraun commented 3 years ago

Wow nice job on that. I will tell my Max friends about it. I also appreciate your notes on graph traversal.

shakfu commented 3 years ago

Thanks. If you like the graph traversal side of it, there's a deep rabbit hole which is easy to fall into in the related field of graph-drawing which addresses graph-layout algorithms.

Some brief intros:

I personally like the aesthetics of bend minimized orthogonal drawings of graphs (i.e. graph layouts with the least number of bends and where the bends of the edges are 90 degrees). After some research I found a very nice algorithm along these lines, which I ended up wrapping using pybind11 because the swig interface was just a pain.

I've just created a separate repo for it with the intent of possibly using it in py2max. It's called pyhola.