Code Monkey home page Code Monkey logo

jsfx-vcv's Introduction

JSFX plugins for VCV Rack

Caution: Extremely experimental. This plugin will probably kick your dog.

This plugin allows you to use JSFX scripts from the Reaper DAW as VCV Rack modules.

JSFX is Reaper's embedded programming language, reference here: https://www.reaper.fm/sdk/js/js.php This plugin uses JsusFX as its engine to interpret the langauge and do the real work: https://github.com/asb2m10/jsusfx If a script isn't supported by JsusFX, it won't be supported in this plugin.

The plugin will create a module menu entry for every JSFX script it finds in the jsfx directory, which you'll find directly next to your plugins directory. The plugin will auto-generate a UI with all the knobs, inputs and outputs defined in the script. Every knob also has a tunable CV input.

If a script supports graphics, a second module entry will be made which will include all the knobs, inputs, outputs, and a screen to display the graphics. All support is very basic at the moment, graphics support is doubly so.

Installing JSFX scripts

Scripts are loaded from the jsfx folder. The location of this folder will depend on your platform:

  • Documents/Rack/jsfx on Mac
  • My Documents/Rack/jsfx on Windows
  • ~/.Rack/jsfx on Linux

Scripts are compiled when VCV Rack starts up in order to determine if they can be run. Scripts are then compiled again when a module is created - this is necessary to create a new engine. The side effect of this is that you can edit the file, delete a module and re-insert it to see if your edits worked as expected.

You can reload the script without re-patching all the cables by saving your patch as a whole and then pressing the "Revert patch" button.

Getting JSFX scripts

JsusFX is distributed with some example Liteon scripts. https://github.com/asb2m10/jsusfx/tree/master/scripts/liteon. I've included these scripts in the res folder of this plugin.

If you've got a copy of Reaper, you can copy the scripts supplied with Reaper from its data directory.

  • ~/.config/REAPER/Effects/ on Linux

You can modify these scripts. This is necessary in some cases. For example, some scripts don't request a large enough screen to show all their graphics. If this is the case, find the line starting with @gfx in the script and increase the numbers there to get a bigger screen.

Uses of this plugin

This plugin can be used to port your favourite Reaper effect into VCV, and to massively increase the effects available to VCV. You can also use JSFX to prototype an effect you want to create before you create a fully customized UI for your module. We can also share and distribute our own JSFX scripts just as we share and distribute patches.

Tempo

Some plugins use the Tempo to do some calculation. To support this, every module has a "BPM" input in the top left. This takes a BPM as output by the Clocked module. Other formats may be added in the future.

Example BPM Values:

  • 30 BPM = -2V
  • 60 BPM = -1V
  • 120 BPM = 0V
  • 130 BPM = 0.115V
  • 140 BPM = 0.222V
  • 240 BPM = 1V

Conversions:

  • V = log(BPM/120, 2)
  • BPM = pow(2,V) * 120

Inputs & CV Control

Inputs are divided by 5 before being sent to the JsusFX engine and outputs are multiplied by 5 before being given back to VCV Rack. This was done to make the VU meters show approximately the same audio values in the Scripts and native VCV modules. I assume that JSFX treats audio as a stream of values between -1 & 1, whereas VCV treats it more normally as between -5 & 5 (although there are no standards here).

Every parameter can be CV controlled. CV is expected to be a value between -5 & 5. A value at either end of this range will always be enough to take a parameter from its lowest value to its highest or vice-versa. For example, if a parameter knob can be between 0Hz and 5000Hz and it's manually set to 0Hz, a CV value of +5 (unattenuated) will modify the parameter to 5000Hz. If the control is manually set to 5000Hz, -5V of CV will bring it back to 0Hz. Values are clamped to the range of the parameters, CV cannot drive the parameters outside that range. Manually setting the control to 5000Hz and driving it with +5V of CV, will keep the setting at 5000Hz.

All CV inputs have an attenuverter associated with them. By default, the attenuverter is set to 0, meaning that the CV input will have no value. As is convention, the attenuverter can multiply the CV input between -1 & -1.

Values entered through turning the knobs and switches are always quantized to the nearest step value for the paramter. CV offsets are not quantized this way and allow smooth control. If a particular script doesn't support this, you'll have to constrain your CV values carefully.

Performance

Although the scripts are written in a high level language, the engine that runs them is c++ and seems to work reasonably well, that said, depending on the script, they can get pretty heavy.

JSFX is different to VCV Rack in that it expects to work on a block of samples at a time wherease VCV always works on a single sample at a time. Because of this, samples are buffered up and then given to the engine in blocks of 64 - so there's a 64 sample latency through a JSFX module rather than the usual 1 sample latency. This is easily changed in code and most scripts will work just fine on blocks of 1 sample, however, Reaper says the minimum block size is 64, so I would expect some scripts to rely on that. Also, operating on blocks of 1 sample can significantly increase the CPU usage of the module, so for now, it's left as a block of 64. This may become configurable.

Limitations

The strongest limitation comes from the JsusFX implementation. Not all JSFX instructions are available and some that are available are just there to let the script compile without actually doing anything. An example of this is slider_next_chg. It's available, the script will run but it won't do anything.

The next strongest limitation is graphics support. I've implemented a basic rendering engine that does some basic and text into SVG, but not everything is supported. There are some behavioural differences as well as outright bugs in how graphics are rendered. I've been through Reapers default plugins and done my best to support all of those. Don't expect great things from the graphics.

Finally, JSFX supports MIDI, file access, serialisation, etc. None of those things are supported in VCV Rack as yet, and probably never will be. (this is code for "I've no idea how to do it and it sounds hard").

jsfx-vcv's People

Contributors

rcomian avatar

Stargazers

Fotis and Stuff avatar Alessandro Aresta avatar Andrew Prentice avatar RCJacH avatar Vincent Cusson avatar Steve Russell avatar Adrian Likins avatar Daniel Kahlenberg avatar

Watchers

 avatar James Cloos avatar

Forkers

steverussell33

jsfx-vcv's Issues

build fail on Linux

Fedora 23 Linux
Rack 0.6.2b (from source)
GCC 5.3.1

Greetings ! I love the idea for this module, but alas, my build attempt fails here:

make dep
...
/home/dlphilp/src/Rack-062/plugins/jsfx-vcv/dep/jsusfx-0.4.0b1b/src/jsusfx.cpp: In member function ‘void JsusFxPathLibrary_Basic::addSearchPath(const string&)’:
/home/dlphilp/src/Rack-062/plugins/jsfx-vcv/dep/jsusfx-0.4.0b1b/src/jsusfx.cpp:351:12: error: ‘const string {aka const class std::__cxx11::basic_string}’ has no member named ‘back’
if ( path.back() == '/' || path.back() == '\' )
^
/home/dlphilp/src/Rack-062/plugins/jsfx-vcv/dep/jsusfx-0.4.0b1b/src/jsusfx.cpp:351:34: error: ‘const string {aka const class std::__cxx11::basic_string}’ has no member named ‘back’
if ( path.back() == '/' || path.back() == '\' )
^
/home/dlphilp/src/Rack-062/plugins/jsfx-vcv/dep/jsusfx-0.4.0b1b/src/jsusfx.cpp: In static member function ‘static bool JsusFxPathLibrary_Basic::fileExists(const string&)’:
/home/dlphilp/src/Rack-062/plugins/jsfx-vcv/dep/jsusfx-0.4.0b1b/src/jsusfx.cpp:358:27: error: no matching function for call to ‘std::basic_ifstream::basic_ifstream(const string&)’
std::ifstream is(filename);
^
In file included from /home/dlphilp/src/Rack-062/plugins/jsfx-vcv/dep/jsusfx-0.4.0b1b/src/jsusfx.cpp:47:0:
/usr/include/c++/5.3.1/fstream:495:7: note: candidate: std::basic_ifstream<_CharT, _Traits>::basic_ifstream(const char*, std::ios_base::openmode) [with _CharT = char; _Traits = std::char_traits; std::ios_base::openmode = std::_Ios_Openmode]
basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in)
^
/usr/include/c++/5.3.1/fstream:495:7: note: no known conversion for argument 1 from ‘const string {aka const std::__cxx11::basic_string}’ to ‘const char*’
In file included from /home/dlphilp/src/Rack-062/plugins/jsfx-vcv/dep/jsusfx-0.4.0b1b/src/jsusfx.cpp:47:0:
/usr/include/c++/5.3.1/fstream:481:7: note: candidate: std::basic_ifstream<_CharT, _Traits>::basic_ifstream() [with _CharT = char; _Traits = std::char_traits]
basic_ifstream() : __istream_type(), _M_filebuf()
^
/usr/include/c++/5.3.1/fstream:481:7: note: candidate expects 0 arguments, 1 provided
In file included from /home/dlphilp/src/Rack-062/plugins/jsfx-vcv/dep/jsusfx-0.4.0b1b/src/jsusfx.cpp:47:0:
/usr/include/c++/5.3.1/fstream:455:11: note: candidate: std::basic_ifstream::basic_ifstream(const std::basic_ifstream&)
class basic_ifstream : public basic_istream<_CharT, _Traits>
^
/usr/include/c++/5.3.1/fstream:455:11: note: no known conversion for argument 1 from ‘const string {aka const std::__cxx11::basic_string}’ to ‘const std::basic_ifstream&’
/home/dlphilp/src/Rack-062/plugins/jsfx-vcv/dep/jsusfx-0.4.0b1b/src/jsusfx.cpp: In member function ‘virtual bool JsusFxPathLibrary_Basic::resolveImportPath(const string&, const string&, std::__cxx11::string&)’:
/home/dlphilp/src/Rack-062/plugins/jsfx-vcv/dep/jsusfx-0.4.0b1b/src/jsusfx.cpp:372:35: warning: range-based ‘for’ loops only available with -std=c++11 or -std=gnu++11
for ( std::string & searchPath : searchPaths ) {
^
/home/dlphilp/src/Rack-062/plugins/jsfx-vcv/dep/jsusfx-0.4.0b1b/src/jsusfx.cpp: In member function ‘virtual std::istream* JsusFxPathLibrary_Basic::open(const string&)’:
/home/dlphilp/src/Rack-062/plugins/jsfx-vcv/dep/jsusfx-0.4.0b1b/src/jsusfx.cpp:391:48: error: no matching function for call to ‘std::basic_ifstream::basic_ifstream(const string&)’
std::ifstream stream = new std::ifstream(path);
^
In file included from /home/dlphilp/src/Rack-062/plugins/jsfx-vcv/dep/jsusfx-0.4.0b1b/src/jsusfx.cpp:47:0:
/usr/include/c++/5.3.1/fstream:495:7: note: candidate: std::basic_ifstream<_CharT, _Traits>::basic_ifstream(const char
, std::ios_base::openmode) [with _CharT = char; _Traits = std::char_traits; std::ios_base::openmode = std::_Ios_Openmode]
basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in)
^
/usr/include/c++/5.3.1/fstream:495:7: note: no known conversion for argument 1 from ‘const string {aka const std::__cxx11::basic_string}’ to ‘const char*’
In file included from /home/dlphilp/src/Rack-062/plugins/jsfx-vcv/dep/jsusfx-0.4.0b1b/src/jsusfx.cpp:47:0:
/usr/include/c++/5.3.1/fstream:481:7: note: candidate: std::basic_ifstream<_CharT, _Traits>::basic_ifstream() [with _CharT = char; _Traits = std::char_traits]
basic_ifstream() : __istream_type(), _M_filebuf()
^
/usr/include/c++/5.3.1/fstream:481:7: note: candidate expects 0 arguments, 1 provided
In file included from /home/dlphilp/src/Rack-062/plugins/jsfx-vcv/dep/jsusfx-0.4.0b1b/src/jsusfx.cpp:47:0:
/usr/include/c++/5.3.1/fstream:455:11: note: candidate: std::basic_ifstream::basic_ifstream(const std::basic_ifstream&)
class basic_ifstream : public basic_istream<_CharT, _Traits>
^
/usr/include/c++/5.3.1/fstream:455:11: note: no known conversion for argument 1 from ‘const string {aka const std::__cxx11::basic_string}’ to ‘const std::basic_ifstream&’
CMakeFiles/jsusfx.dir/build.make:66: recipe for target 'CMakeFiles/jsusfx.dir/jsusfx.cpp.o' failed
make[3]: *** [CMakeFiles/jsusfx.dir/jsusfx.cpp.o] Error 1
make[3]: Leaving directory '/home/dlphilp/src/Rack-062/plugins/jsfx-vcv/dep/jsusfx-0.4.0b1b'
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/jsusfx.dir/all' failed
make[2]: *** [CMakeFiles/jsusfx.dir/all] Error 2
make[2]: Leaving directory '/home/dlphilp/src/Rack-062/plugins/jsfx-vcv/dep/jsusfx-0.4.0b1b'
Makefile:83: recipe for target 'all' failed
make[1]: *** [all] Error 2
make[1]: Leaving directory '/home/dlphilp/src/Rack-062/plugins/jsfx-vcv/dep/jsusfx-0.4.0b1b'
Makefile:30: recipe for target 'lib/jsusfx.a' failed
make: *** [lib/jsusfx.a] Error 2

It seems that it wants -std=cxx11 somewhere but I'm not sure where that will go in a cmake system. Any suggestions are vastly appreciated. :)

Compile issue Win 10

g++ -Wsuggest-override -std=c++11 -DSLUG=jsfx -fPIC -I../../include -I../../dep/include -DVERSION=0.6.0 -MMD -MP -g -O3 -march=nocona -ffast-math -fno-finite-math-only -Wall -Wextra -Wno-unused-parameter -DARCH_WIN -D_USE_MATH_DEFINES -c -o build/src/JSFXModule.cpp.o src/JSFXModule.cpp
src/JSFXModule.cpp: In member function 'virtual void JSFXModule::onSampleRateChange()':
src/JSFXModule.cpp:30:3: error: 'uint' was not declared in this scope
uint sliderid = 0;
^~~~
src/JSFXModule.cpp:30:3: note: suggested alternative: 'u_int'
uint sliderid = 0;
^~~~
u_int
src/JSFXModule.cpp:37:29: error: 'sliderid' was not declared in this scope
_jsusfx->moveSlider(sliderid, slider.max);
^~~~~~~~
src/JSFXModule.cpp:37:29: note: suggested alternative: 'slider'
_jsusfx->moveSlider(sliderid, slider.max);
^~~~~~~~
slider
src/JSFXModule.cpp:39:29: error: 'sliderid' was not declared in this scope
_jsusfx->moveSlider(sliderid, slider.min);
^~~~~~~~
src/JSFXModule.cpp:39:29: note: suggested alternative: 'slider'
_jsusfx->moveSlider(sliderid, slider.min);
^~~~~~~~
slider
src/JSFXModule.cpp:41:27: error: 'sliderid' was not declared in this scope
_jsusfx->moveSlider(sliderid, current);
^~~~~~~~
src/JSFXModule.cpp:41:27: note: suggested alternative: 'slider'
_jsusfx->moveSlider(sliderid, current);
^~~~~~~~
slider
src/JSFXModule.cpp:43:5: error: 'sliderid' was not declared in this scope
sliderid += 1;
^~~~~~~~
src/JSFXModule.cpp:43:5: note: suggested alternative: 'slider'
sliderid += 1;
^~~~~~~~
slider
src/JSFXModule.cpp: In member function 'virtual void JSFXModule::step()':
src/JSFXModule.cpp:78:5: error: 'uint' was not declared in this scope
uint sliderid = 0;
^~~~
src/JSFXModule.cpp:78:5: note: suggested alternative: 'u_int'
uint sliderid = 0;
^~~~
u_int
src/JSFXModule.cpp:79:9: error: expected ';' before 'paramid'
uint paramid = 0;
^~~~~~~~
;
src/JSFXModule.cpp:82:34: error: 'paramid' was not declared in this scope
auto paramvalue = params[paramid].value * slider.inc;
^~~~~~~
src/JSFXModule.cpp:82:34: note: suggested alternative: 'params'
auto paramvalue = params[paramid].value * slider.inc;
^~~~~~~
params
src/JSFXModule.cpp:94:29: error: 'sliderid' was not declared in this scope
_jsusfx->moveSlider(sliderid, paramvalue);
^~~~~~~~
src/JSFXModule.cpp:94:29: note: suggested alternative: 'slider'
_jsusfx->moveSlider(sliderid, paramvalue);
^~~~~~~~
slider
src/JSFXModule.cpp:97:7: error: 'sliderid' was not declared in this scope
sliderid += 1;
^~~~~~~~
src/JSFXModule.cpp:97:7: note: suggested alternative: 'slider'
sliderid += 1;
^~~~~~~~
slider
make: *** [../../compile.mk:65: build/src/JSFXModule.cpp.o] Error 1

Building with Rack SDK 0.6.2 Win 10
jsusfx-0.4.0b1b is added in dep/

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.