Skip to main content

a cython-based loader for VST audio plugins providing a clean python object-oriented interface

Project description

cython-vst-loader

a cython-based loader for VST audio plugins providing a clean python object-oriented interface

Motivation

The purpose is to create a stable and simple wrapper for VST plugins to be used in higher-level projects, such as https://github.com/hq9000/py_headless_daw

Installation

Through pip

pip install cython_vst_loader

please note that there are requirements to be satisfied by your system in order for the above to succeed:

  • a compiler is present (gcc in case of linux)
  • make is installed
  • header files for your python versions are installed (apt install python3.7-dev in case of Ubuntu)

As a submodule

You can add this project as a git submodule to yours.

Usage example

Loading a plugin

The example below does the following:

  • instantiates a plugin object by reading a .so vst plugin file.
  • checks some plugin attributes
from cython_vst_loader.vst_host import VstHost
from cython_vst_loader.vst_plugin import VstPlugin
from cython_vst_loader.vst_loader_wrapper import allocate_float_buffer, get_float_buffer_as_list, free_buffer, \
     allocate_double_buffer, get_double_buffer_as_list
from cython_vst_loader.vst_event import VstNoteOnMidiEvent


sample_rate = 44100
buffer_size = 512

host = VstHost(sample_rate, buffer_size)

# Audio will be rendered into these buffers:
right_output = allocate_float_buffer(buffer_size, 1)
left_output = allocate_float_buffer(buffer_size, 1)

# `right_output` and `left_output` are integers which are, in fact, 
# just pointers to float32 arrays cast to `int`
 
# These buffers are not managed by Python, and, therefore, are not garbage collected.
# use free_buffer to free up the memory

plugin_path = "/usr/bin/vst/amsynth-vst.x86_64-linux.so"
plugin = VstPlugin(plugin_path.encode('utf-8'), host)


# now we can work with this object representing a plugin instance:
assert(41 == plugin.get_num_parameters())
assert (b'amp_attack' == plugin.get_parameter_name(0))
assert (0.0 == plugin.get_parameter_value(0))

Doing something useful with the plugin

The following example performs one cycle of rendering, involving both sending events and requesting to render audio.

# 3: delta frames, at which frame(sample) in the current buffer the event occurs
# 85: the note number (85 = C# in the 7th octave)
# 100: velocity (0..128)
# 1: midi channel
event = VstNoteOnMidiEvent(3, 85, 100, 1)

plugin.process_events([event])
plugin.process_replacing([], [right_output, left_output], buffer_size)
# at this point, the buffers are expected to have some sound of the C# playing

Freeing up buffers

# when we are done, we free up the buffers
free_buffer(left_output)
free_buffer(right_output)

Using numpy arrays as buffers

Although this library does not depend on numpy, you can use numpy arrays as buffers like so:

import numpy as np

def numpy_array_to_pointer(numpy_array: np.ndarray) -> int:
        if numpy_array.ndim != 1:
            raise Exception('expected a 1d numpy array here')
        pointer, _ = numpy_array.__array_interface__['data']
        return pointer

the resulting value can be supplied to VstPlugin.process_replacing as a buffer

note: if buffers are created this way, they are managed by numpy and, therefore, should not be freed manually

Plugins used for testing

The following open source vst plugins were compiled for linux x86_64 and put into tests/test_plugins directory:

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cython_vst_loader-0.0.1.tar.gz (1.4 MB view hashes)

Uploaded Source

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page