From d07d3ae317ec8f23b1501efc05a228b60a8d0941 Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Sat, 16 Feb 2019 13:23:12 -0500 Subject: [PATCH] Add jq to build deps. Reorganize community list. --- About.md | 2 +- Building.md | 22 +++++++++++------ Communities.md | 16 ++++++------- FAQ.md | 18 +++++++------- Migrate1.md | 64 +++++++++++++++++++++++++++++++------------------ favicon.png | Bin 10288 -> 5783 bytes 6 files changed, 75 insertions(+), 47 deletions(-) diff --git a/About.md b/About.md index 1ab2048..6c25fbe 100644 --- a/About.md +++ b/About.md @@ -4,7 +4,7 @@ VCV was founded by Andrew Belt in 2016 and is based in Tennessee, USA. Its flagship product VCV Rack was released on September 10, 2017 at [Knobcon](https://knobcon.com/) after two years of development. 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 and commercial VCV modules. +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 diff --git a/Building.md b/Building.md index fa7effc..b0aaefc 100644 --- a/Building.md +++ b/Building.md @@ -11,26 +11,32 @@ However, you need proper tools to build Rack and these dependencies. Install [Xcode](https://developer.apple.com/xcode/). Using [Homebrew](https://brew.sh/), install the build dependencies. ``` -brew install git wget cmake autoconf automake libtool +brew install git wget cmake autoconf automake libtool jq ``` ### Windows -Install [MSYS2](http://www.msys2.org/) and launch the MinGW 64-bit shell (not the default MSYS shell). +If you have an anti-virus program running, disable it. + +Install [MSYS2](http://www.msys2.org/) and launch the MinGW 64-bit shell from the Start menu, *not the default MSYS shell*. +``` +pacman -Syu +``` +Then restart the shell. ``` -pacman -S git wget make tar unzip zip mingw-w64-x86_64-gcc mingw-w64-x86_64-cmake autoconf automake mingw-w64-x86_64-libtool +pacman -Su git wget make tar unzip zip mingw-w64-x86_64-gcc mingw-w64-x86_64-cmake autoconf automake mingw-w64-x86_64-libtool mingw-w64-x86_64-jq ``` ### Linux On Ubuntu 16.04: ``` -sudo apt install git curl cmake libx11-dev libglu1-mesa-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev zlib1g-dev libasound2-dev libgtk2.0-dev libjack-jackd2-dev +sudo apt install git curl cmake libx11-dev libglu1-mesa-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev zlib1g-dev libasound2-dev libgtk2.0-dev libjack-jackd2-dev jq ``` On Arch Linux: ``` -pacman -S git wget gcc make cmake tar unzip zip curl +pacman -S git wget gcc make cmake tar unzip zip curl jq ``` ## Building Rack @@ -38,18 +44,20 @@ pacman -S git wget gcc make cmake tar unzip zip curl *If the build fails for you, please report the issue with a detailed error message to help the portability of Rack.* Clone this repository with `git clone https://github.com/VCVRack/Rack.git` and `cd Rack`. -Make sure there are no spaces in your absolute path, as this breaks the Makefile-based build system. +Make sure there are no spaces in your absolute path, since this breaks the Makefile-based build system. Clone submodules. git submodule update --init --recursive Build dependencies locally. -You may add `-j$(nproc)` to your make commands to parallelize builds across all CPU cores. +You may add `-j4` (or your number of logical cores) to your `make` commands to parallelize builds. +This may take 15-60 minutes. make dep Build Rack. +This may take 1-5 minutes. make diff --git a/Communities.md b/Communities.md index 008829c..9fdf431 100644 --- a/Communities.md +++ b/Communities.md @@ -1,23 +1,23 @@ # Communities -- [VCVRack.com](https://vcvrack.com/) -- [Forum](https://community.vcvrack.com/) +- [Website](https://vcvrack.com/) +- [Community 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) -- [Youtube](https://www.youtube.com/c/VCVRack) -- [Instagram](https://www.instagram.com/vcvrack/) - [Facebook user group](https://www.facebook.com/groups/vcvrack/) - [Facebook developer group](https://www.facebook.com/groups/2035785263299933/) - [Facebook French user group](https://www.facebook.com/groups/2069785583250645/) - [Facebook Italian user group](https://www.facebook.com/groups/vcvitalia/) -- [Switched On Rack blog](http://www.switchedonrack.com/) +- [Youtube](https://www.youtube.com/c/VCVRack) +- [Instagram](https://www.instagram.com/vcvrack/) - [Discord](https://discord.gg/wxa89Mh) +- [Reddit](https://www.reddit.com/r/vcvrack/) +- [IRC](http://webchat.freenode.net?channels=%23VCVRack) +- [Patchstorage](https://patchstorage.com/platform/vcv-rack/) +- [Switched On Rack unofficial blog](http://www.switchedonrack.com/) - [MuffWiggler thread](https://www.muffwiggler.com/forum/viewtopic.php?t=186899) - [KVR Audio thread](https://www.kvraudio.com/forum/viewtopic.php?f=23&t=489230) - [Hispasonic thread (Spanish)](https://www.hispasonic.com/foros/foro-vcv-rack/516252) -- [Patchstorage](https://patchstorage.com/platform/vcv-rack/) - [Switched On Rack collaboration albums](https://switchedonrack.bandcamp.com/) -- [Reddit](https://www.reddit.com/r/vcvrack/) -- [IRC](http://webchat.freenode.net?channels=%23VCVRack) diff --git a/FAQ.md b/FAQ.md index ac433c2..081a9e3 100644 --- a/FAQ.md +++ b/FAQ.md @@ -80,11 +80,13 @@ When running Rack in development mode, it is your current working directory inst ## Will Rack be ported to iOS or Android? -It is not planned. Many issues would need to be addressed. -- Tablet and phone users don't normally use mice, so a touch driver would need to be written. If GLFW is still used, [touch support](https://github.com/glfw/glfw/issues/42) would need to be added to the library. -- There is no user-managed filesystem on iOS, and forcing users to mess with the filesystem is bad UX on Android, so plugin folders and patch files would need to be managed entirely by Rack itself. -- There is no OpenGL on mobile devices, so the OpenGL ES driver would need to be used and tested. -- RtAudio and RtMidi don't have iOS Core Audio/MIDI or Android HAL/OpenSL ES backends, so they would need to be added and tested. -- Apple does not allow apps distributed through the store to download and execute code, so either all plugins would need to be included in the distributable, or it could only be distributed on jailbroken iOS devices, which is an absurd user requirement. -- Such a port would be very expensive to develop, so it would need to be sold commercially. Some plugins (proprietary, GPL, etc) would need special licensing agreements in order to be included in the package. Some plugins would increase the cost of the product if included in the package. Others would simply be omitted from the third-party plugin collection. -- The friction for a developer to build and test their plugins on iOS/Android is significantly higher than the three desktop OS's, which may decrease their willingness to develop Rack plugins. +It is not planned. There are many issues with such a project. +- Technical: + - Tablet and phone users don't normally use mice, so a touch driver would need to be written. If GLFW is still used, [touch support](https://github.com/glfw/glfw/issues/42) would need to be added to the library. + - There is no user-managed filesystem on iOS, and forcing users to mess with the filesystem is bad UX on Android, so plugin folders and patch files would need to be managed entirely by Rack itself. + - RtAudio and RtMidi don't have iOS Core Audio/MIDI or Android HAL/OpenSL ES backends, so they would need to be added and tested. + - Apple does not allow apps distributed through the store to download and execute code, so either all plugins would need to be included in the distributable, or it could only be distributed on jailbroken iOS devices, which is an absurd user requirement. +- Business: + - Such a port would be expensive to develop, so it would need to be sold commercially. Some plugins (proprietary, GPL, etc) would need special licensing agreements in order to be included in the package. Some plugins would increase the cost of the product if included in the package. Others would simply be omitted from the third-party plugin collection. + - The friction for a developer to build and test their plugins on iOS/Android is significantly higher than the three desktop OS's, which may decrease their willingness to develop Rack plugins. + - When serving an app on the App Store or Google Play, Apple or Google are typically not obligated to continue serving an app and may remove it at will or change policies that can disrupt VCV's business model. This would place VCV's risk in a small number of baskets. diff --git a/Migrate1.md b/Migrate1.md index d38024b..d491f7c 100644 --- a/Migrate1.md +++ b/Migrate1.md @@ -1,6 +1,6 @@ # 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 stabilized.** ## The easy way: using the `rack0.hpp` compatibility header @@ -21,17 +21,23 @@ Model *modelMyModule = Model::create("MyModule"); Make the following string replacements (requires Perl). ``` -perl -pi -e "s/Model::create/createModel/g" src/*.cpp -perl -pi -e "s/ParamWidget::create/createParam/g" src/*.cpp -perl -pi -e "s/ModuleLightWidget::create/createLight/g" src/*.cpp -perl -pi -e "s/Port::create/createPort/g" src/*.cpp -perl -pi -e "s/Port::OUTPUT/PortWidget::OUTPUT/g" src/*.cpp -perl -pi -e "s/Port::INPUT/PortWidget::INPUT/g" src/*.cpp -perl -pi -e "s/Widget::create/createWidget/g" src/*.cpp -perl -pi -e "s/MenuLabel::create/createMenuLabel/g" src/*.cpp -perl -pi -e "s/MenuItem::create/createMenuItem/g" src/*.cpp -perl -pi -e "s/toJson/dataToJson/g" src/*.cpp -perl -pi -e "s/fromJson/dataFromJson/g" src/*.cpp +# 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/* ``` If your plugin uses any of Rack's `dsp/*.hpp` headers, remove the `#include` statements since they are now automatically included. @@ -47,16 +53,28 @@ 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"` ``` -perl -pi -e "s/engineGetSampleRate/app()->engine->getSampleRate/g" src/*.cpp -perl -pi -e "s/engineGetSampleTime/app()->engine->getSampleTime/g" src/*.cpp -perl -pi -e "s/, PortWidget::INPUT//g" src/*.cpp -perl -pi -e "s/addInput\(createPort/addInput(createInput/g" src/*.cpp -perl -pi -e "s/, PortWidget::OUTPUT//g" src/*.cpp -perl -pi -e "s/addOutput\(createPort/addOutput(createOutput/g" src/*.cpp -perl -pi -e "s/randomUniform/random::uniform/g" src/*.cpp -perl -pi -e "s/randomNormal/random::normal/g" src/*.cpp -``` +# 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/* -Add the `dsp::` prefix. +# 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/* -TODO +# 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 +``` diff --git a/favicon.png b/favicon.png index 893a7f252b08724643b09206b27f9048527625eb..caf0fa75dd6cf76729ef6c618556a46575830ab1 100644 GIT binary patch delta 5635 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 Wft`b?mAU8tFDP#-m`yUrWB(t6J;gTw