@@ -11,7 +11,7 @@ Before writing a single line of code, most features and bug fixes require | |||
Instead, there are many other areas where contributions are much appreciated. | |||
- Dependencies of Rack. Especially [nanovg](https://github.com/memononen/nanovg)'s performance, [rtaudio](https://github.com/thestk/rtaudio)/[rtmidi](https://github.com/thestk/rtmidi)'s stability and compatibility, and maybe even touch support in [GLFW](https://github.com/glfw/glfw). You would be helping many more projects than just Rack. | |||
- Your own Rack [plugin](PluginDevelopmentTutorial.md) | |||
- Your own Rack [plugin](PluginDevelopmentTutorial.html) | |||
- Maintaining the Rack plugin ecosystem by [curating](https://github.com/VCVRack/community/issues/352), [updating](https://github.com/VCVRack/community/issues/269), and [reviewing](https://github.com/VCVRack/community/issues/354) plugins | |||
- Edits to the [VCV Rack manual](https://github.com/VCVRack/manual). | |||
@@ -26,13 +26,13 @@ The **INPUT** section sends up to 8 Rack signals to a hardware audio device for | |||
- ASIO on Windows | |||
- ALSA on Linux | |||
- JACK on Linux | |||
- [VCV Bridge](Bridge.md) | |||
- [VCV Bridge](Bridge.html) | |||
After a driver is selected, a particular **device** can be chosen for the driver. | |||
If the device has more than 8 inputs or outputs, you can select the desired range of outputs, offset by a factor of 8. | |||
The **sample rate** is the number of audio samples per second for the audio device to process. | |||
Note that this rate is different than Rack's internal sample rate set from the [toolbar](Toolbar.md), which determines the number of samples per second for virtual Rack modules to process. | |||
Note that this rate is different than Rack's internal sample rate set from the [toolbar](Toolbar.html), which determines the number of samples per second for virtual Rack modules to process. | |||
If set to different rates, sample rate conversion will occur, resulting in slightly higher CPU usage, slightly less audio fidelity, and slightly more latency. | |||
The **block size** sets the number of samples to store in the audio buffer before releasing to the audio device. | |||
@@ -50,7 +50,7 @@ Each MIDI interface module (described below) supports the following drivers. | |||
- Windows MIDI on Windows | |||
- ALSA on Linux | |||
- JACK on Linux | |||
- [VCV Bridge](Bridge.md) | |||
- [VCV Bridge](Bridge.html) | |||
- Gamepad | |||
- Computer keyboard | |||
@@ -68,9 +68,9 @@ FFT algorithms exist in many libraries, like [pffft](https://bitbucket.org/jpomm | |||
### Sampling | |||
The [Nyquist–Shannon sampling theorem](https://en.wikipedia.org/wiki/Nyquist%E2%80%93Shannon_sampling_theorem) states that a signal with no frequency components higher than half the sample rate \\(f_{sr}\\) can be sampled and reconstructed without losing information. | |||
In other words, if you bandlimit a signal (with a brickwall lowpass filter at \\(f_{sr}/2\\)) and sample points at \\(f_{sr}\\), you can reconstruct the bandlimited signal by finding the unique signal which passes through all points and has no frequency components higher than \\(f_{sr}/2\\). | |||
In other words, if you bandlimit a signal (with a brick-wall lowpass filter at \\(f_{sr}/2\\)) and sample points at \\(f_{sr}\\), you can reconstruct the bandlimited signal by finding the unique signal which passes through all points and has no frequency components higher than \\(f_{sr}/2\\). | |||
In practice, digital-to-analog converters (DACs) apply an approximation of a brickwall lowpass filter to remove frequencies higher than \\(f_{sr}/2\\) from the signal. | |||
In practice, digital-to-analog converters (DACs) apply an approximation of a brick-wall lowpass filter to remove frequencies higher than \\(f_{sr}/2\\) from the signal. | |||
The signal is integrated for a small fraction of the sample time \\(1/f_{sr}\\) to obtain an approximation of the amplitude at a point in time, and this measurement is quantized to the nearest digital value. | |||
Analog-to-digital converters (ADCs) convert a digital value to an amplitude and hold it for a fraction of the sample time. | |||
@@ -179,7 +179,7 @@ A disadvantage of the FFT FIR method is that the signal must be delayed by \\(N\ | |||
You can combine the naive and FFT methods into a hybrid approach with the [overlap-add](https://en.wikipedia.org/wiki/Overlap%E2%80%93add_method) or [overlap-save](https://en.wikipedia.org/wiki/Overlap%E2%80%93save_method) methods, allowing you to process smaller blocks of size \\(M < N\\) at a slightly worse \\(O((N/M) \log M)\\) average computations per sample. | |||
### Impulse responses | |||
#### Impulse responses | |||
Sometimes we need to simulate non-rational transfer functions. | |||
Consider a general transfer function \\(H(f)\\), written in terms of \\(f\\) rather than \\(s\\) for simplicity. | |||
@@ -196,25 +196,24 @@ Repeating this process in the digital realm gives us the discrete convolution. | |||
\\[ y_k = \sum_{n=-\infty}^\infty h_n x_{k-n} \\] | |||
#### Brickwall filter | |||
#### Brick-wall filter | |||
An example of a non-rational transfer function is the ideal lowpass filter that fully attenuates all frequencies higher than \\(f_c\\) and passes all frequencies below \\(f_c\\). | |||
Including [negative frequencies](https://en.wikipedia.org/wiki/Negative_frequency), its transfer function is | |||
$$ | |||
\\[ | |||
H(f) = \begin{cases} | |||
1 & \text{if } -f_c \leq f \leq f_c \\ | |||
1 & \text{if } -f_c \leq f \leq f_c \\\\ | |||
0 & \text{otherwise} | |||
\end{cases} | |||
$$ | |||
\\] | |||
The inverse Fourier transform of \\(H(f)\\) is | |||
\\[ h(t) = 2 f_c \operatorname{sinc}(2 f_c t) \\] | |||
where \\(\operatorname{sinc}(x) = \sin(\pi x) / (\pi x)\\) is the [normalized sinc function](https://en.wikipedia.org/wiki/Sinc_function). | |||
Although the impulse response is infinitely long, restricting it to a finite range \\([-T, T]\\) and shifting it forward by \\(T\\) produces a finite causal impulse response that can be solved by a fast FIR algorithm to produce a close approximation of an ideal brickwall filter. | |||
### Windows | |||
#### Windows | |||
The impulse response \\(h_n\\) is defined for all integers \\(n\\), so it is both non-causal (requires future knowledge of \\(x(t)\\) to compute \\(y(t)\\)) and infinitely long. | |||
Like the brick-wall filter above, many impulse responses \\(h_n\\) are defined for all integers \\(n\\), so they are both non-causal (requires future knowledge of \\(x(t)\\) to compute \\(y(t)\\)) and infinitely long. | |||
*TODO* | |||
@@ -73,4 +73,4 @@ Save a patch to `<Rack local directory>/template.vcv`, and it will be loaded aft | |||
- Windows: `My Documents/Rack/` | |||
- Linux: `~/.Rack/` | |||
In development builds of Rack, it is your current working directory instead. | |||
When running Rack in development mode, it is your current working directory instead. |
@@ -35,11 +35,11 @@ My word of advice: *mind the aliasing*. | |||
### Panel | |||
Design your module's panel with a vector graphics editor and save it to the `res/` directory as an SVG file. | |||
[Inkscape](https://inkscape.org/en/) is recommended, but [Adobe Illustrator](https://www.adobe.com/products/illustrator.html), [Affinity Designer](https://affinity.serif.com/en-gb/designer/), [Gravit Designer](https://www.designer.io/), etc. may also work. | |||
[Inkscape](https://inkscape.org/en/) is recommended, but [Adobe Illustrator](https://www.adobe.com/products/illustrator.html), [Affinity Designer](https://affinity.serif.com/en-gb/designer/), [Gravit Designer](https://www.designer.io/), etc. may also work with certain SVG export settings. | |||
Make sure the path to the .svg file is correctly specified in the `setPanel(SVG::Load(...))` function in your `ModuleWidget` constructor. | |||
Rack renders SVGs at 75 DPI, and the standard Eurorack 1HP module size is 128.5mm x 5.08mm, 5.06" x 0.2", or 380px x 15px. | |||
Note: The Rack renderer is currently only capable of rendering path and group objects with solid fill and stroke. Gradients are experimental and might not work correctly. Text must be converted to paths. Clipping masks, clones, symbols, CSS outside style attributes, etc. are not supported. | |||
Note: The Rack renderer is currently only capable of rendering path and group objects with solid fill and stroke. Gradients are experimental and might not work correctly. Text must be converted to paths. Clipping masks, clones, symbols, CSS other than a few style attributes, etc. are not supported. | |||
### Component Widgets | |||
@@ -48,7 +48,7 @@ Helper functions `createParam()`, `createInput()`, and `createOutput()` are used | |||
Rack Widgets are defined in `include/widgets.hpp` and `include/app.hpp`, and helpers are found in `include/rack.hpp`. | |||
Note: Widgets from `include/components.hpp` using Component Library SVG graphics are licensed under CC BY-NC 4.0 and are free to use for noncommercial purposes. | |||
Contact contact@grayscale.info for information about licensing for commercial use. | |||
Contact contact@vcvrack.com for information about licensing for commercial use. | |||
### Naming | |||
@@ -33,10 +33,12 @@ An easy way to hold a trigger for this duration is to use `PulseGenerator` from | |||
Gates should produce **10V** when active. | |||
### Pitch | |||
### Pitch and frequencies | |||
Most Eurorack manufacturers use the **1V/octave** standard. | |||
The relationship between frequency \\(f\\) and voltage \\(V\\) is \\(f = f_0 \cdot 2^{V}\\), where \\(f_0\\) is an arbitrary baseline set by a pitch knob or the note C4 (MIDI note 60, \\(f_0 =\\) 261.626 Hz). | |||
Modules should use the **1V/oct** (volt per octave) standard for CV control of frequency information. | |||
The relationship between frequency \\(f\\) and voltage \\(V\\) is \\(f = f_0 \cdot 2^{V}\\), where \\(f_0\\) is an arbitrary baseline specified by a frequency parameter. | |||
With the frequency knob at its default position, audio-rate oscillators should have a baseline of the note C4 (MIDI note 60, \\(f_0 =\\) 261.626 Hz). | |||
Low-frequency oscillators and clock generators should use 120 BPM (\\(f_0 =\\) 2 Hz). | |||
### NaNs and Infinity | |||
@@ -43,11 +43,11 @@ html_theme_options = { | |||
} | |||
html_context = { | |||
"display_github": True, # Integrate GitHub | |||
"github_user": "VCVRack", # Username | |||
"github_repo": "manual", # Repo name | |||
"github_version": "master", # Version | |||
"conf_py_path": "/", # Path in the checkout to the docs root | |||
"display_github": True, | |||
"github_user": "VCVRack", | |||
"github_repo": "manual", | |||
"github_version": "master", | |||
"conf_py_path": "/", | |||
} | |||
html_logo = 'images/logo.png' | |||
@@ -6,8 +6,8 @@ The VCV Rack manual is under active development. | |||
Edit this manual at https://github.com/VCVRack/manual. | |||
Table of Contents | |||
---------------------- | |||
Rack | |||
---- | |||
.. toctree:: | |||
:maxdepth: 1 | |||
@@ -36,7 +36,7 @@ Table of Contents | |||
.. toctree:: | |||
:maxdepth: 1 | |||
:caption: Index | |||
:caption: Appendix | |||
Communities.md | |||
Glossary.md |