Architecture
In this section, we will discuss the architecture of VENOM. We will start with the high-level overview of the project and then we will dive into the details of each component.
Why C++ to Python binding isn't enough?
A VST3 plugin is a shared library compliant with the VST3 standard. It is loaded by a DAW and it communicates with it in a way defined by the standard.
While it is possible to compile a Python script into a shared library (using Cython) it would require a lot of work to make it compliant with the VST3 standard - redeveloping the whole VST3 SDK in Cython.
Then JUCE offers building not only VST3 plugins but also AU plugins, standalone apps, and more. It would take a lot of time to make it all available in Python.
So if the JUCE build system already exists in C++ and it is a standard in the industry, why not use it? We can just extend it with Python.
This is the main idea behind VENOM. It is a Python module that extends a C++ JUCE project. It allows you to write the critical part of your plugin in Python, while still having all the build options available in JUCE.
Binding
Extending
We will dive deeper into the details of extending in the Extending Chapter.
High-level overview
To make this process simple for the end user VENOM is divided into 4 main components (and 3 Python modules):
JUCE bindings (venom.juce) - a set of bindings for the JUCE framework.
Pythonic API (venom.wrapper) - a wrapper around the JUCE bindings that makes it easier to use.
CLI tool (venom.builder) - a command-line interface tool that allows you to create a new project, build it, and run it.
Boilerplate JUCE project (part of venom.builder)- a template for a new JUCE project extended with Python.
Architecture diagram
The architecture is shown in 2 connected diagrams for better readability (* is a reference to the other diagram).
JUCE bindings
JUCE bindings are a set of pybind11 bindings for the JUCE framework. They are located in the venom.juce
module. A detailed description of that module and a tutorial on how to contribute to it can be found in the JUCE bindings chapter.
Pythonic API
The Pythonic API is a wrapper around the JUCE bindings that makes it easier to use. It is located in the venom.wrapper
module. A detailed description of that module and a tutorial on how to contribute to it can be found in the Pythonic API chapter.
CLI tool and Boilerplate JUCE project
These two components are responsible for the whole building process. They are explained in detail in the CLI tool chapter and the Boilerplate JUCE project chapter.
This is a high-level overview of the building process:
The user creates a new project using the CLI tool (init). Read: VENOM project structure.
The user writes Python scripts that use the Pythonic API.
The user runs the CLI tool (build) to build the project.
venom.builder
generates a Python package from the Python scripts and installs it in the local Python site-packages.
venom.builder
sets up a new JUCE project using configurations fromvenom.yaml
and the boilerplate JUCE project.venom.builder
builds the JUCE project. During this step all local Pythonsite-packages
are copied to the build bundle so they are available when you ship the binaries. A copy of the Python interpreter is also included in the bundle.
The user can run the standalone app or install the plugin.