diff --git a/About.md b/About.md index 6c25fbe..c98974c 100644 --- a/About.md +++ b/About.md @@ -6,7 +6,7 @@ It was based on an unreleased C++ modular audio engine written by Andrew in 2012 VCV collaborates with [Grayscale](http://grayscale.info/) to design the [Fundamental](https://vcvrack.com/Fundamental.html) plugin, commercial VCV modules, and the UI design of Rack. -## Mission +## Mission Statement We believe that no human should be excluded from learning any musical instrument, and the [modular synthesizer](https://en.wikipedia.org/wiki/Modular_synthesizer) is possibly the most excluding instrument on the planet---even more so than the harp or the marimba---due to its cost. Yet, it is possible to emulate synthesizer modules in software, in both sound and interaction behavior, providing a similar platform for creation that can be equally gratifying as hardware. diff --git a/Building.md b/Building.md index d2e9060..a121176 100644 --- a/Building.md +++ b/Building.md @@ -8,8 +8,7 @@ However, you need proper tools to build Rack and these dependencies. ### Mac -Install [Xcode](https://developer.apple.com/xcode/). -Using [Homebrew](https://brew.sh/), install the build dependencies. +Install [Homebrew](https://brew.sh/), and install the build dependencies. ```bash brew install git wget cmake autoconf automake libtool jq ``` diff --git a/Communities.md b/Communities.md index 9fdf431..6d66b28 100644 --- a/Communities.md +++ b/Communities.md @@ -2,7 +2,7 @@ # Communities - [Website](https://vcvrack.com/) -- [Community forum](https://community.vcvrack.com/) +- [Forum](https://community.vcvrack.com/) - [Facebook page](https://www.facebook.com/vcvrack/) - [Twitter](https://twitter.com/vcvrack) - [Github issue tracker](https://github.com/VCVRack/Rack/issues) diff --git a/FAQ.md b/FAQ.md index 00c0ddb..2ad47c8 100644 --- a/FAQ.md +++ b/FAQ.md @@ -1,28 +1,5 @@ # FAQ -## When will Rack 1.0 be ready? - -Rack is currently in Beta (thus the version 0.x), so by using it, you are an "early tester". -Don't worry, Rack 1.0 will also be free open-source software. - -In order for Rack to earn its "1.0" designation, it must improve in the following three fronts. - -### Compatibility -Since I am an "indie developer", I cannot yet afford to test Rack on every combination of hardware on the market. -With the introduction of commercial VCV plugin sales, I will soon be able to invest in hardware that is known to have compatibility problems with Rack. -If you are willing to lend me hardware to test, email contact@vcvrack.com for details. - -### Stability -Rack is not ready to be trusted for live use, although some musicians have used it successfully in live performances. -In order for Rack to be considered "stable", it must produce audio with no clicks or pops on modern hardware for several minutes and must crash less than once per several days of continuous use. -Currently, stability in Rack is the most developed among these three fronts. - -### Performance -Depending on your CPU and graphics card, Rack may consume high CPU/GPU resources and therefore increase your laptop's fan speed. -I am aware of this, so there is no need to inform me. - -To answer the original question, there is currently no time estimate for 1.0. - ## My audio interface / MIDI device doesn't work. Make sure the device drivers are up to date for your operating system. @@ -95,7 +72,21 @@ It is not planned. There are many issues with such a project. ## Why does the Audio module from Core consume so much CPU? -The CPU meter measures the time spent processing each module. +The CPU meter measures the time spent processing each module, not the limited "resource" of CPU power. In order for playback timing to be consistent, your audio device, and thus the Audio module, waits until all samples in the current audio buffer are played before moving onto the next audio buffer. Otherwise, your device's DAC and ADC would play and record at very inconsistent and incorrect sample rates. While waiting, the engine thread is put to sleep, so no energy is consumed by the thread. + +## Is VCV Rack available as a VST/AU/AAX plugin for DAWs? + +Not at this time. +Shortly after Rack 2.0 releases, Rack will also be available as a 64-bit VST2 plugin for around $99. +VST3/AU/AAX versions might be released afterwards. +All Rack v2 plugins will be compatible with the plugin version of Rack. +The primary "standalone" version of Rack v2 will continue to be free/open-source. + +## Does VCV Rack work with touch screens? + +Rack's window library GLFW does not support [touch input](https://github.com/glfw/glfw/issues/42), so Rack relies on the operating system to control the mouse cursor using the touch screen. +This means that multi-touch gestures do not work. +However, you can set `"allowCursorLock"` to `false` in the `settings.json` file in Rack's local directory to improve knob moving gestures. diff --git a/Installing.md b/Installing.md index 4a269a8..01da4cd 100644 --- a/Installing.md +++ b/Installing.md @@ -1,5 +1,15 @@ # Installing & Running +## System Requirements + +VCV Rack is free software, so you may simply install it to check if it works. +However, if you are experiencing performance issues, make sure you have the following. +- Operating system: MacOS 10.7+, Windows 7+, or Linux (Ubuntu 16.04+, etc) +- CPU: Intel/AMD 64-bit processor from \~2011 or later +- Graphics: Dedicated Nvidia/AMD graphics card from \~2013 or later. Integrated (non-dedicated) graphics such as Intel HD/Iris are not recommended and cause significantly increased CPU usage. +- RAM: 1GB+ +- Disk space: 1GB+ + ## Installing Rack Download Rack on the [VCV Rack website](https://vcvrack.com/). diff --git a/Migrate1.md b/Migrate1.md index 7af858e..3d0002c 100644 --- a/Migrate1.md +++ b/Migrate1.md @@ -1,53 +1,71 @@ -# Migrating 0.6 plugins to Rack v1 +# Migrating v0.6 Plugins to Rack v1 -**This document is a draft. It is not recommended to migrate plugins at this time. If you begin now, you will likely need to follow this guide again when the Rack v1 API is stable.** +This is a step-by-step guide for migrating plugins using the Rack v0.6 API to Rack v1. +There are three phases of porting. +- **Phase 1**: Quickly produces a valid Rack v1 plugin. +- **Phase 2**: Modernizes your plugin by replacing deprecated v0.6 function calls with new v1 functions. +- **Phase 3**: Takes advantage of new Rack v1 features such as parameter labels and polyphony. ## Prerequisites Install new build dependencies. +- [jq](https://stedolan.github.io/jq/) for parsing JSON when building plugins +- Python 3.6+ for running Rack's `helper.py` script +- Perl for replacing text with regex. ### Mac ```bash -brew install python jq +brew install jq python ``` ### Windows ```bash -pacman -S python mingw-w64-x86_64-jq +pacman -S mingw-w64-x86_64-jq python3 ``` ### Linux -On Ubuntu 16.04: +On Ubuntu 18.04: ```bash -sudo apt install jq +sudo apt install jq python3 ``` On Arch Linux: ```bash -pacman -S python jq +pacman -S jq python perl ``` -## The easy way: using the `rack0.hpp` compatibility header +## Phase 1: Using the `rack0.hpp` compatibility header -Change `#include "rack.hpp"` to `#include "rack0.hpp"` +### 1.1 -Create a `plugin.json` manifest file for your plugin using the `helper.py` script included in the Rack SDK. +`cd` to your plugin's root directory. +Create a `plugin.json` manifest file for your plugin using the helper script included in the Rack SDK. ```bash -python /helper.py createmanifest +python3 /helper.py createmanifest ``` -Add a module entry to `plugin.json` for each module in your plugin. -When prompted, don't overwrite the module .cpp file. +### 1.2 + +For each module in your plugin, add an entry to `plugin.json` using the helper script. ```bash -python /helper.py createmodule +python3 /helper.py createmodule ``` +### 1.3 + Remove `SLUG` and `VERSION` from the `Makefile`, and remove ` p->slug = ...` and `p->version = ...` from your plugin's main `.cpp` file, since they are now defined in `plugin.json`. -For each module, change the `Model::create` call +### 1.4 + +Change `#include "rack.hpp"` to `#include "rack0.hpp"` to access deprecated functions. + +### 1.5 + +For each module, remove the author, module name, and tags from the `Model::create` call, since they are now defined in `plugin.json`. +For example, change ```cpp Model *modelMyModule = Model::create("Template", "MyModule", "My Module", OSCILLATOR_TAG); ``` @@ -55,101 +73,182 @@ to ```cpp Model *modelMyModule = Model::create("MyModule"); ``` -since the plugin name, module name, and module tags are now defined in `plugin.json`. -For the following replacements, make sure you have perl installed (`perl -v`), and paste these lines into your terminal in the root of your plugin directory to automatically make replacements. -It might even be a good idea to review the changes and `git commit` between each step. +### 1.6 + +Make the following [regex](https://en.wikipedia.org/wiki/Regular_expression) replacements by pasting these lines into your terminal in the root of your plugin directory. +It is a good idea to review the changes and `git commit` between each step, in case an automatic replacement goes wrong. + +#### 1.6.1 Rename the `plugin` variable to avoid a name collision with the `plugin::` namespace. ```bash -perl -pi -e 's/\bplugin\b/pluginInstance/g' src/* +perl -i -pe 's/\bplugin\b/pluginInstance/g' src/* ``` + +#### 1.6.2 + Rename `X::create()` functions to `createX()`. ```bash -perl -pi -e 's/Model::create/createModel/g' src/* -perl -pi -e 's/ParamWidget::create/createParam/g' src/* -perl -pi -e 's/ModuleLightWidget::create/createLight/g' src/* -perl -pi -e 's/Port::create/createPort/g' src/* -perl -pi -e 's/Port::OUTPUT/PortWidget::OUTPUT/g' src/* -perl -pi -e 's/Port::INPUT/PortWidget::INPUT/g' src/* -perl -pi -e 's/Widget::create/createWidget/g' src/* -perl -pi -e 's/MenuLabel::create/createMenuLabel/g' src/* -perl -pi -e 's/MenuItem::create/createMenuItem/g' src/* +perl -i -pe 's/Model::create/createModel/g' src/* +perl -i -pe 's/ParamWidget::create/createParam/g' src/* +perl -i -pe 's/ModuleLightWidget::create/createLight/g' src/* +perl -i -pe 's/Port::create/createPort/g' src/* +perl -i -pe 's/Port::OUTPUT/PortWidget::OUTPUT/g' src/* +perl -i -pe 's/Port::INPUT/PortWidget::INPUT/g' src/* +perl -i -pe 's/Widget::create/createWidget/g' src/* +perl -i -pe 's/MenuLabel::create/createMenuLabel/g' src/* +perl -i -pe 's/MenuItem::create/createMenuItem/g' src/* ``` + +#### 1.6.3 + Rename `to/fromJson()` methods to `dataTo/FromJson()`. ```bash -perl -pi -e 's/toJson/dataToJson/g' src/* -perl -pi -e 's/fromJson/dataFromJson/g' src/* +perl -i -pe 's/toJson/dataToJson/g' src/* +perl -i -pe 's/fromJson/dataFromJson/g' src/* ``` +### 1.7 + If your plugin uses any of Rack's `dsp/*.hpp` headers, remove the `#include "dsp/..."` lines since they are now automatically included by `rack.hpp`. -Now compile your plugin. -Hundreds of deprecation warnings should appear, but it might succeed. -If so, your plugin can now be distributed as a Rack v1 plugin. -If not, read the compile errors, and don't hesitate to ask questions in the [Development category of the VCV Community](https://community.vcvrack.com/c/development) or [Rack GitHub issue tracker](https://github.com/VCVRack/Rack/issues). -If your plugin is open-source, you may even ask the [VCV Repair Team](https://github.com/VCVRack/library/issues/269) to create a pull request in your repository. +### 1.8 + +The event API has been overhauled in v1. +If you use `on*()` event handler methods in your custom widgets, see [event.hpp](https://github.com/VCVRack/Rack/blob/v1/include/event.hpp) and [widget/Widget.hpp](https://github.com/VCVRack/Rack/blob/v1/include/widget/Widget.hpp) for new methods and event classes. + +Once completed, your plugin may compile, although many deprecation warnings may appear. -## The right way: using the Rack v1 API +### 1.9 -First complete the above section using the compatibility header as a first step. +Your `ModuleWidget`s must gracefully handle a NULL `module` argument, otherwise Rack will crash when the Module Browser attempts to display your module. +`createParam()` etc. gracefully handle NULL, but if you've written custom widgets with a `module` pointer, make sure you check `if (module) ...` before accessing the pointer. -Once it is able to compile, change `#include "rack0.hpp"` back to `#include "rack.hpp"`. +### 1.10 -Add new arguments to the `step()` (now called `process()`) and `draw()` methods. +Test your plugin in Rack by adding your modules, moving parameters, clicking custom widgets, and searching your plugin in the Module Browser. + +If your plugin still does not build, read the compile errors, and don't hesitate to ask questions in the [Development board of the VCV Community](https://community.vcvrack.com/c/development) or [Rack's GitHub issue tracker](https://github.com/VCVRack/Rack/issues) about the v1 API. +If your plugin is open-source, you may even ask the [VCV Repair Team](https://github.com/VCVRack/library/issues/269) to create a pull request for you. + +## Phase 2: Updating your code to the Rack v1 API + +### 2.1 + +Once your plugin can be compiled, change `#include "rack0.hpp"` back to `#include "rack.hpp"`. + +### 2.2 + +Add new arguments to the `Module::step()` (now called `process()`) and `Widget::draw()` methods. ```bash -perl -pi -e 's/void (\w+::)?step\(\)/void $1process(const ProcessArgs &args)/g' src/* -perl -pi -e 's/void draw\(NVGcontext \*vg\)/void draw(const DrawArgs &args)/g' src/* -perl -pi -e 's/\bvg\b/args.vg/g' src/* -perl -pi -e 's/engineGetSampleRate\(\)/args.sampleRate/g' src/* -perl -pi -e 's/engineGetSampleTime\(\)/args.sampleTime/g' src/* +perl -i -pe 's/void (\w+::)?step\(\)/void $1process(const ProcessArgs &args)/g' src/* +perl -i -pe 's/void draw\(NVGcontext \*vg\)/void draw(const DrawArgs &args)/g' src/* +perl -i -pe 's/\bvg\b/args.vg/g' src/* ``` -Use the `APP` macro for accessing global state. +Note: `Widget::step()` has not been renamed, but this replacement will incorrectly rename it. + +### 2.3 + +Use the `Module::process()` argument struct to access the sample rate/time. +```bash +perl -i -pe 's/engineGetSampleRate\(\)/args.sampleRate/g' src/* +perl -i -pe 's/engineGetSampleTime\(\)/args.sampleTime/g' src/* +``` +Note: This only works inside `Module::process()` methods. +You can call `APP->engine->getSampleRate()` and `APP->engine->getSampleTime()` anywhere in your code, although this is slightly slower than the above. + +### 2.4 + +Use the `APP` macro for accessing global state instead of calling global functions. ```bash -perl -pi -e 's/Font::load/APP->window->loadFont/g' src/* -perl -pi -e 's/Image::load/APP->window->loadImage/g' src/* -perl -pi -e 's/SVG::load/APP->window->loadSvg/g' src/* +perl -i -pe 's/Font::load/APP->window->loadFont/g' src/* +perl -i -pe 's/Image::load/APP->window->loadImage/g' src/* +perl -i -pe 's/SVG::load/APP->window->loadSvg/g' src/* ``` + +### 2.5 + Use `createInput/Output()` functions instead of `createPort()`. ```bash -perl -pi -e 's/, PortWidget::INPUT//g' src/* -perl -pi -e 's/addInput\(createPort/addInput(createInput/g' src/* -perl -pi -e 's/, PortWidget::OUTPUT//g' src/* -perl -pi -e 's/addOutput\(createPort/addOutput(createOutput/g' src/* +perl -i -pe 's/, PortWidget::INPUT//g' src/* +perl -i -pe 's/addInput\(createPort/addInput(createInput/g' src/* +perl -i -pe 's/, PortWidget::OUTPUT//g' src/* +perl -i -pe 's/addOutput\(createPort/addOutput(createOutput/g' src/* ``` + +### 2.6 + Add namespaces to global functions. ```bash -perl -pi -e 's/\bassetPlugin\b/asset::plugin/g' src/* -perl -pi -e 's/\brandomUniform\b/random::uniform/g' src/* -perl -pi -e 's/\brandomNormal\b/random::normal/g' src/* -perl -pi -e 's/\brandomu32\b/random::u32/g' src/* +perl -i -pe 's/\bassetGlobal\b/asset::system/g' src/* +perl -i -pe 's/\bassetLocal\b/asset::user/g' src/* +perl -i -pe 's/\bassetPlugin\b/asset::plugin/g' src/* +perl -i -pe 's/\brandomUniform\b/random::uniform/g' src/* +perl -i -pe 's/\brandomNormal\b/random::normal/g' src/* +perl -i -pe 's/\brandomu32\b/random::u32/g' src/* ``` + +### 2.7 + Change `.value` to getters and setters, and change `.active` to `isConnected()`. ```bash -perl -pi -e 's/(params\[.*?\])\.value/$1.getValue()/g' src/* -perl -pi -e 's/(inputs\[.*?\])\.value/$1.getVoltage()/g' src/* -perl -pi -e 's/(outputs\[.*?\])\.value = (.*?);/$1.setVoltage($2);/g' src/* -perl -pi -e 's/(inputs\[.*?\])\.active/$1.isConnected()/g' src/* -perl -pi -e 's/(outputs\[.*?\])\.active/$1.isConnected()/g' src/* +perl -i -pe 's/(params\[.*?\])\.value/$1.getValue()/g' src/* +perl -i -pe 's/(inputs\[.*?\])\.value/$1.getVoltage()/g' src/* +perl -i -pe 's/(outputs\[.*?\])\.value = (.*?);/$1.setVoltage($2);/g' src/* +perl -i -pe 's/(inputs\[.*?\])\.active/$1.isConnected()/g' src/* +perl -i -pe 's/(outputs\[.*?\])\.active/$1.isConnected()/g' src/* ``` + +### 2.8 + Add the `dsp::` namespace to dsp classes. -TODO ```bash +perl -i -pe 's/\b(quadraticBipolar|cubic|quarticBipolar|quintic|sqrtBipolar|exponentialBipolar|BooleanTrigger|SchmittTrigger|PulseGenerator|RealFFT|ComplexFFT|RCFilter|PeakFilter|SlewLimiter|ExponentialSlewLimiter|ExponentialFilter|RealTimeConvolver|MinBlepGenerator|stepEuler|stepRK2|stepRK4|SampleRateConverter|Decimator|Upsampler|RingBuffer|DoubleRingBuffer|AppleRingBuffer|VuMeter|hann|hannWindow|blackman|blackmanWindow|blackmanNuttall|blackmanNuttallWindow|blackmanHarris|blackmanHarrisWindow)\b/dsp::$1/g' src/* +``` + +### 2.9 + +Add `config()` to the `Module` constructor, and add `setModule()` to the `ModuleWidget` constructor. +```bash +perl -i -pe 's/: Module\(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS\) \{/{\n\t\tconfig(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);/g' src/* +perl -i -pe 's/: ModuleWidget\(module\) \{/{\n\t\tsetModule(module);/g' src/* +``` + +### 2.10 + +For each param in each module, copy `minValue, maxValue, defaultValue` from `createParam(pos, module, paramId, minValue, maxValue, defaultValue)` to a new `configParam(paramId, minValue, maxValue, defaultValue)` call in your `Module` constructor. +Then remove the values from `createParam`. + +For example, if you have the line +```cpp + addParam(createParam(Vec(10, 20), module, MyModule::LEVEL_PARAM, 0.f, 10.f, 5.f)); +``` +create a new line +```cpp + configParam(LEVEL_PARAM, 0.f, 10.f, 5.f); +``` +in the `MyModule` constructor, and change the original line to +```cpp + addParam(createParam(Vec(10, 20), module, MyModule::LEVEL_PARAM)); +``` + +You can automate this process by running +```bash +perl -nle 'print "configParam($1);" while /createParam.*?module, (.*?)\)/g' src/* ``` -Add `config()` to the `Module` constructor, and add `setModule` to the `ModuleWidget` constructor. +and copying the respective groups of lines into each module's `Module` constructor. +Then remove the arguments with ```bash -perl -pi -e 's/: Module\(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS\) \{/{\n\t\tconfig(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);/g' src/* -perl -pi -e 's/: ModuleWidget\(module\) \{/{\n\t\tsetModule(module);/g' src/* +perl -i -pe 's/(createParam.*?module, .*?)(,.*?)\)/$1)/g' src/* ``` Now make sure your plugin compiles. -### Adding new Rack v1 features +## Phase 3: Adding new Rack v1 features You are now ready to add optional Rack v1 features to your plugin. -Parameters now have optional labels. -Add `Param::config()` to the `Module` constructor. -```cpp -params[X_PARAM].config(0.0, 1.0, 0.0, "Label"); -``` +You may add parameters labels, units, and nonlinear scaling to be displayed when users right-click on a parameter or enable *View > Parameter tooltips*. See [Module::configParam()](https://github.com/VCVRack/Rack/blob/v1-gpl/include/engine/Module.hpp#L94-L95). + +If you with to add support for polyphonic cables, see [How polyphonic cables will work in Rack v1](https://community.vcvrack.com/t/how-polyphonic-cables-will-work-in-rack-v1/1464) and [engine/Port.hpp](https://github.com/VCVRack/Rack/blob/v1-gpl/include/engine/Port.hpp). diff --git a/PanelTutorial.md b/PanelTutorial.md index be7d6f6..edffa88 100644 --- a/PanelTutorial.md +++ b/PanelTutorial.md @@ -1,5 +1,7 @@ # Panel Tutorial +**Note: This tutorial is for designing Rack v1 panels. For Rack v0.6 panels, see the [Plugin Development Tutorial](PluginDevelopmentTutorial.html#panel).** + ## Setup Install [Inkscape](https://inkscape.org/), a cross-platform open-source vector graphics editor, to create SVG panels for Rack modules. @@ -30,6 +32,14 @@ Plugins which use other people's work unfairly will not be accepted into the [VC Don't hesitate to ask the [VCV community](https://community.vcvrack.com/c/development) for design help. You may find several graphic designers seeking programmers for collaboration. +## SVG limitations + +The [SVG standard](https://en.wikipedia.org/wiki/Scalable_Vector_Graphics) is so broad, no renderer fully supports the entire format. +Rack's SVG renderer does not support the following features. +- **Text and fonts.** All text objects must be converted to paths. This can be achieved in Inkscape with *Path > Object to Path*. As a benefit, this avoids license issues with embedding proprietary fonts. +- **Gradients.** Simple two-color linear gradients may work, but more advanced features are not a priority since VCV recommends to avoid gradients altogether. +- **CSS.** Although, most `fill-*` and `stroke-*` properties are supported in inline style attributes. + ## Adding components A *component* is a graphical element that can be manipulated in C++. diff --git a/PluginLicensing.md b/PluginLicensing.md new file mode 100644 index 0000000..c3e3d32 --- /dev/null +++ b/PluginLicensing.md @@ -0,0 +1,43 @@ +# Plugin Licensing + +**This document is a draft. It is currently not in effect, so everything here is bogus now, but it may eventually become the guide for plugin licensing in the future.** + +VCV Rack is open-source software, but you should still familiarize yourself with the [VCV Rack licenses](https://github.com/VCVRack/Rack/blob/v1-gpl/LICENSE.md) before releasing your plugin, to avoid misuse of intellectual property. If in doubt, send any licensing questions to contact@vcvrack.com. + + +### I want to release my plugin under the [GNU General Public License v3.0](https://www.gnu.org/licenses/gpl-3.0.en.html) (GPLv3). + +Since Rack is licensed under GPLv3, you may license your plugin under GPLv3 as well. +You may do anything with your plugin that the GPLv3 allows, including selling it without a commercial license (below) as long as you release the source code under GPLv3. + +### I want to release my plugin non-commercially under non-GPLv3 terms. + +This is the most common choice among plugin developers. +Rack offers a [VCV Rack Non-Commercial Plugin License Exception](https://github.com/VCVRack/Rack/blob/v1-gpl/LICENSE.md) which allows you to license your plugin under any terms you want, as long as it is offered free of charge. +You may choose: +- **Open-source**. [BSD 3-clause](https://opensource.org/licenses/BSD-3-Clause), [MIT](https://opensource.org/licenses/MIT), and [CC0](https://creativecommons.org/publicdomain/zero/1.0/) are popular licenses. +- **Closed-source freeware**. +- **Donationware**, as long as a donation is not required for use. + +Note that if you copy significant portions of Rack's code into your own plugin, you must license it under GPLv3. + +If someone makes a fork of your non-GPLv3 open-source plugin that is not a Rack plugin (e.g. a port to VST or a digital hardware module), their source code becomes no longer linked to VCV Rack and is thus no longer a "derived work" of Rack, so Rack's license does not apply to their source code. + +### I want to sell my plugin commercially under non-GPLv3 terms. + +VCV offers commercial royalty licensing for Rack plugins by emailing [contact@vcvrack.com](mailto:contact@vcvrack.com). +This license also includes permission to use the [Component Library](https://github.com/VCVRack/Rack/blob/v1/include/componentlibrary.hpp) graphics by [Grayscale](https://grayscale.info/), which are normally licensed for non-commercial use only. + +It is recommended to contact VCV as early as possible in your development process to make sure the license agreement is ready well before you release your plugin. +You can expedite the licensing processing by sending concepts and design mockups along with your license request. + +You may also wish to sell your plugin on the [VCV Store](https://vcvrack.com/plugins.html). +Some benefits of distributing your plugin on the VCV Store: +- Most Rack users are already familiar with the VCV Store checkout system. +- Plugin updates are automatically synchronized to users' Rack installations. +- VCV offers advanced technical support with the Rack SDK and DSP library. +- You may supply VCV with either binary packages for Mac/Windows/Linux, or a source package which we will build for you. +- Access to dashboard for managing customers' purchases and viewing real-time statistics. + +You must follow the **VCV Rack Plugin Ethics Guidelines** in order to obtain a commercial plugin license: +- You may not clone the brand name, model name, logo, or layout of components (knobs, ports, switches, etc) of an existing hardware or software module without permission from its owner, regardless of whether these are covered under trademark/copyright law. diff --git a/Version.md b/Version.md index 8702846..891d2b0 100644 --- a/Version.md +++ b/Version.md @@ -1,7 +1,7 @@ # ABI/API Version -An ABI (Application Binary Interface) is a machine-readable list of symbols (functions, globals, and classes) that can only be called, accessed, and used in specific ways. -An API (Application Programming Interface) consists of C and C++ headers (`.h` and `.hpp` files) that define how the ABI can be used. +An **ABI** (Application Binary Interface) is a machine-readable list of symbols (functions, globals, and classes) that can only be called, accessed, and used in specific ways. +An **API** (Application Programming Interface) consists of C and C++ headers (`.h` and `.hpp` files) that define how the ABI can be used. Rack plugins must be compiled against a particular *major version* of Rack to match its ABI, so that when Rack loads them, they link to Rack's symbols correctly. The major version is `X` in the version name `vX.Y` (or `v0.X.Y` for beta versions). diff --git a/VoltageStandards.md b/VoltageStandards.md index 9c2f6fa..94938f6 100644 --- a/VoltageStandards.md +++ b/VoltageStandards.md @@ -48,7 +48,7 @@ Therefore, modules with a CLOCK and RESET input, or similar variants, should ign Modules should use the **1V/oct** (volt per octave) standard for CV control of frequency information. In this standard, the relationship between frequency \\(f\\) and voltage \\(V\\) is \\(f = f_0 \cdot 2^{V}\\), where \\(f_0\\) is the baseline frequency. Your module might have a frequency knob which may offset \\(V\\). -At its default position, audio-rate oscillators should use a baseline of the note C4 ("middle C", MIDI note 60, \\(f_0\\) = 261.6256 Hz = `dsp::FREQ_C4`). +At its default position, audio-rate oscillators should use a baseline of the note C4 defined by [International Pitch Notation](https://en.wikipedia.org/wiki/Scientific_pitch_notation) ("middle C", MIDI note 60, \\(f_0\\) = 261.6256 Hz = `dsp::FREQ_C4`). Low-frequency oscillators and clock generators should use 120 BPM (\\(f_0\\) = 2 Hz). ## NaNs and Infinity diff --git a/index.rst b/index.rst index 28da5c3..2c019b6 100644 --- a/index.rst +++ b/index.rst @@ -27,6 +27,8 @@ Rack PanelTutorial.md VoltageStandards.md DSP.md + Migrate1.md + PluginLicensing.md .. toctree:: :maxdepth: 1