Awesome
______ _ ___ ___
| ___ \ | | | \/ |
| |_/ /___ _ __ __| | ___ _ __| . . | __ _ _ __
| // _ \ '_ \ / _` |/ _ \ '__| |\/| |/ _` | '_ \
| |\ \ __/ | | | (_| | __/ | | | | | (_| | | | |
\_| \_\___|_| |_|\__,_|\___|_| \_| |_/\__,_|_| |_|
* * Command Line VSTi Audio, Features and Parameter Renderer * *
build |
---|
RenderMan
Renderman is a command line VSTi host written in C++ with Python bindings using JUCE and Maximilian libraries for the backend. It is designed with ease of use in mind to extract audio and features from VSTi plugins. It has a fast growing list of features, including setting, getting parameters from synthesiers, setting whole patches, getting random patches, obtaining MFCCS, FFT, audio data and much more.
A usage example in the form of an IPython notebook can be found here.
Here are some quick gifs demonstrating a miniscule amount of the availble features, go towards the bottom of the README to see the full API:
Loading Plugins
Here we load a plugin. On Linux it's an .so file, for MacOS it will be a .vst or .au.
Getting Parameter Descriptions
We can obtain the available parameters that are used and that can be modified by doing the following.
Getting a Randomised Patch For a Synthesiser
We can easily get a randomised for a given synth by using the PatchGenerator class.
Plotting Rendered Audio Frames
We can plot the output audio frames easily by using matplotlib.
Building / Installation
MacOS
If you haven't already, get brew. The last time I checked the command to install was simply this:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Next, get the boost headers.
brew install boost-python3
You can also install boost manually if for some reason you don't want to use brew, see here.
Now just open the Xcode project in the Builds directory and build it! There is a bug in the JUCE projucer app which means the generated shared object will be suffixed with a dylib. This means python wont be able to import the module. Until this bug is fixed, change directory into the Builds/MacOSX/build/<Debug/Release> (depending on your Xcode scheme,) and run:
mv librenderman.so.dylib librenderman.so
IMPORTANT: The project is linked with libpython3.8 and libboost_python38 and the appropriate include directories. If you have a different version of python installed, run python3-config --includes --ldflags
to obtain the library and include paths, and update the XCode project to point to the correct locations
Linux
Firstly, you will need the boost library (specifically the python headers) for this code to compile.
Ubuntu:
sudo apt-get install libboost-all-dev
Arch:
sudo pacman -Ss boost
Fedora:
sudo yum install boost-devel
If your distribution's package manager doesn't have boost, you can get the headers from here.
Juce itself has a list of dependancies for Linux; it's a very big library - if you don't know it you should definitely take some time out to check it out! Depending on your distribution and setup you may already have some / all of the following libraries. If you are on Ubuntu, the following commands will install your dependancies. Find the respective packages for other distros using google please!
sudo apt-get -y install llvm
sudo apt-get -y install clang
sudo apt-get -y install libfreetype6-dev
sudo apt-get -y install libx11-dev
sudo apt-get -y install libxinerama-dev
sudo apt-get -y install libxrandr-dev
sudo apt-get -y install libxcursor-dev
sudo apt-get -y install mesa-common-dev
sudo apt-get -y install libasound2-dev
sudo apt-get -y install freeglut3-dev
sudo apt-get -y install libxcomposite-dev
sudo apt-get -y install libcurl4-gnutls-dev
Well done! You've made it this far! Should you still have problems, which is always a possibility with Linux, a good place to start is the JUCE forums, particularly here and here. Feel free to drop me a note with an error and I'll happily scratch my head over it but you may get better results in the forums!
So to now build the library for Linux, change to the right directory and run make:
cd Builds/LinuxMakefile/
make
Windows - VisualStudio2019
Download and Install boost
Download from https://www.boost.org/users/download/ extract to c:\boost_1_74_0
cd c:\boost_1_74_0
bootstrap.bat
.\b2 --toolset=msvc-14.0 --build-type=complete --prefix=C:\Boost install
Download and Install python 3.7.9
Download from https://www.python.org/downloads/release/python-379/
Open RenderMan.sln in VisualStudios2019
When prompt to retarget projects
select Windows SDK Version: 8.1 platform toolset: No Upgrade
add Includes to search path Project > Properties > C/C++ > General
Additional Include Directories
C:\Boost\include\boost-1_74
C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\include
add Libs to search path
Project > Properties > Configuration Properties > VC++ Directories
Library Directories
add
C:\Boost\lib
C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\libs
build
after build rename
RenderMan\Builds\VisualStudio2019\x64\Debug\Dynamic Library\renderman.dll
to
librenderman.pyd
*put the pyd file in the root of the python program
Does It Work?
Change directory to where the .so file is and run:
python
Once in interactive mode, run:
import librenderman as rm
If this doesn't spit out errors, congratulations! Enjoy RenderMan. :)
Note you'll need to have the .so binary in the same directory as the Python project or where you call the interative Python shell from. To use it system wide it will need to be added to the PYTHONPATH environment variable. Soon I'll get distutils sorted so there is an easier installation method.
API
class RenderEngine
The constructor takes three arguments, the sample rate, the buffer size and fft size. Good defualt values if you don't really care that much are 44100, 512, 512 repsectively.
__init__(int sample_rate,
int buffer_size,
int fft_size)
Supply a full path to the plugin to this function to load the vst. It will return true if there is a successful loading.
bool load_plugin(string plugin_path)
We can set a synth's patch by taking a list of tuples and set the parameters at the int index to the float value. The PatchGenerator class can generate random patches with ease for a given synth.
void set_patch(list_of_tuples(int, float) patch)
Get the current patch.
list_of_tuples(int, float) get_patch()
Take a midi note (middle C is 40,) a velocity (0 - 127,) and the note length and recording / rendering length and create the features to be extracted!
void render_patch(int midi_note_pitch,
int midi_note_velocity,
float note_length_seconds,
float render_length_seconds)
Get MFCC features as a list of lists. The first length will be dictated by fft size divided by four, and the second length with be 13, which is the amount of coefficients.
list_of_lists get_mfcc_frames()
Get the int amount of parameters for the loaded plugin.
int get_plugin_parameter_size()
Get a description of each parameter.
string get_plugin_parameters_description()
Override a parameter to always be the supplied value. The float is normalised (0 - 1).
override_plugin_parameter(int index,
float value)
Remove an overriden plugin parameter.
remove_overriden_plugin_parameter(int index)
Get a list of floats which is the audio from the rendering session.
list get_audio_frames()
Write the current patch to a wav file at the specified relative or absolute path. This will overwrite existing files and is only a preview; it is mono and currently not quite loud enough.
void write_to_wav(string path)
Get a list of root mean squared frames derived from the audio samples. Each frame is a root mean squared of an amount of samples equal to the fft size divided by four.
list_of_floats get_rms_frames()
class PatchGenerator
This class is used to generate patches for a given engine.
The constructor takes an argument of a RenderEngine that has succesfully loaded a plugin.
__init__(RenderEngine engine)
We can obtain a random value (from a real uniform distribution) that for a parameter at a specified index.
tuple(int, float) get_random_parameter(int index)
We can get a completely random patch sampled from PRNG in the same way above.
list_of_tuples(int, float) get_random_patch()
Contributors
I want to express my deep gratitude to jgefele. It is very touching that people want to use this code let alone contribute to it - thanks!
Context and Contact
This library is a work in progress for my final year project where I am using Neural Networks to generate synth patches to create desired sounds. For example, I wrote a toy VSTi and learnt synthesiser using a neural network to sound match target sounds here. Everything this library has facilitates that but I recognise there may be more applications so if there are any feature requests please drop me a line on here or leonfedden (at) gmail.com :)
Finally, doing something cool with this library? Let me know what you are up to! And if this code was useful for you then please kindly drop me a GitHub star so more developers will trust and use this code.
If you use this code for academic works, feel free to reference this code through the DOI here:
Thanks for reading this far, you rock!