Browse Source

Expand Migrate1 document

pull/29/head
Andrew Belt 6 years ago
parent
commit
9104ab97fe
2 changed files with 95 additions and 52 deletions
  1. +92
    -50
      Migrate1.md
  2. +3
    -2
      VoltageStandards.md

+ 92
- 50
Migrate1.md View File

@@ -1,14 +1,18 @@
# Migrating 0.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 stabilized.**
**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.**

## The easy way: using the `rack0.hpp` compatibility header

Change `#include "rack.hpp"` to `#include "rack0.hpp"`

Create a `plugin.json` manifest file for your plugin and all modules based on the [Template manifest](https://github.com/VCVRack/Template/blob/v1/plugin.json) (TODO add actual manifest template/guide).
Create a `plugin.json` manifest file for your plugin using the `helper.py` script included in the Rack SDK.
When prompted, don't overwrite the module .cpp file.
```bash
python <Rack SDK>/helper.py createmodule <slug>
```

Remove `SLUG` and `VERSION` from the `Makefile` and ` p->slug = ...` and `p->version = ...` from your plugin's main `.cpp` file, since they are now defined in `plugin.json`.
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
```cpp
@@ -18,63 +22,101 @@ to
```cpp
Model *modelMyModule = Model::create<MyModule, MyModuleWidget>("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.

Make the following string replacements (requires Perl).
Rename the `plugin` variable to avoid a name collision with the `plugin::` namespace.
```bash
perl -pi -e 's/\bplugin\b/pluginInstance/g' src/*
```
# Rename `plugin` variable to avoid a name collision with the `plugin::` namespace
perl -pi -e "s/\bplugin\b/pluginInstance/g" src/*

# Change `X::create()` functions to `createX()`
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/*

# Change `to/fromJson()` to `dataTo/FromJson()`
perl -pi -e "s/toJson/dataToJson/g" src/*
perl -pi -e "s/fromJson/dataFromJson/g" src/*
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/*
```
Rename `to/fromJson()` methods to `dataTo/FromJson()`.
```bash
perl -pi -e 's/toJson/dataToJson/g' src/*
perl -pi -e 's/fromJson/dataFromJson/g' src/*
```

If your plugin uses any of Rack's `dsp/*.hpp` headers, remove the `#include` statements since they are now automatically included.
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`.

For most plugins, this should do it.
Compiling should generate hundreds of deprecation warnings, but it might succeed.
If not, read the compile error, and don't hesitate to ask questions in the VCV community forum or GitHub issue tracker.
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.

## The right way: using the Rack v1 API

First complete the above section using the compatibility header as a first step.

Once it is able to compile, change `#include "rack0.hpp"` back to `#include "rack.hpp"`
Once it is able to compile, change `#include "rack0.hpp"` back to `#include "rack.hpp"`.

Add new arguments to the `step()` (now called `process()`) and `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/*
```
Use the `APP` macro for accessing global state.
```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/*
```
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/*
```
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/*
```
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/*
```
# Use `APP` macro for accessing global state
perl -pi -e "s/engineGetSampleRate/APP->engine->getSampleRate/g" src/*
perl -pi -e "s/engineGetSampleTime/APP->engine->getSampleTime/g" src/*
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/*

# Use `createInput/Output()` functions instead of `createPort()`
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/*

# Add namespaces to global functions
perl -pi -e "s/randomUniform/random::uniform/g" src/*
perl -pi -e "s/randomNormal/random::normal/g" src/*

# Change `void draw(NVGcontext *vg)` to `void draw(const DrawContext &ctx)`
perl -pi -e "s/draw\(NVGcontext \*vg\)/draw\(const DrawContext &ctx\)/g" src/*
perl -pi -e "s/\(vg/(ctx.vg/g" src/*
perl -pi -e "s/draw\(vg\)/draw\(ctx\)/g" src/*

# Add the `dsp::` namespace to dsp classes
# TODO
Add the `dsp::` namespace to dsp classes.
TODO
```bash
```
Add `config()` to the `Module` constructor, and add `setModule` to the `ModuleWidget` constructor.
```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/*
```

Now make sure your plugin compiles.

### 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");
```

+ 3
- 2
VoltageStandards.md View File

@@ -5,9 +5,10 @@ You can measure absolute voltage levels using modules like Fundamental Scope.

Rack attempts to model Eurorack standards as accurately as possible, but this is a problem for two reasons: there are very few actual "standards" in Eurorack (The only rule is that you can always find a module which breaks the rule), and there are a few differences between digital (finite sample rate) and analog (infinite sample rate).

## Audio and Modulation
## Levels

Audio outputs are typically **±5V** (before bandlimiting is applied), and CV modulation sources are typically **0 to 10V** (unipolar CV) or **±5V** (bipolar CV).
Signals should typically be \\(10V_{pp}\\) (peak-to-peak).
This means that audio outputs should typically be **±5V** (before bandlimiting is applied), and CV modulation sources should typically be **0 to 10V** (unipolar CV) or **±5V** (bipolar CV).

## Output Saturation



Loading…
Cancel
Save