Rack development blog

Added dsp/approx.hpp, which only has one function for computing 2^x but will later contain several approximations of common math functions for faster DSP.


Rack 1.1.4 has been released.


Added libsamplerate to Rack, so plugins no longer need to build their own copy. (Fundamental, FrozenWasteland, maybe more)
Of course, it would be a good idea to wait a month or two after the next Rack version is released before releasing a plugin that takes advantage of the included libsamplerate.

If you build Rack from source, note that you need to make dep the next time you pull and rebuild.


Added “Hardware” tag for hardware module clones. https://github.com/VCVRack/Rack/blob/v1/src/tag.cpp#L35


Developers may now use "manualUrl" for each module in your plugin manifest. However, they will not be used until Rack v2 or the upcoming VCV Library website.


Rack v2 Plan Overview

Major features that will define Rack v2:

  • Add scaffolding for Rack for DAWs, so that the proprietary fork is as minimal as possible, containing only plugin API wrappers.
  • Integration with future VCV Library website at https://library.vcvrack.com/, which will allow individual modules to be added to your VCV account, and possibly individually purchased modules.

Very rough development timeline:

  • 2019 Q2 - Q4: Lots and lots of new Eurorack and VCV plugins.
  • 2019 Q3 - Q4: VCV Library website, minor Rack v2 features.
  • 2019 Q4 - 2020 Q1: Rack v2. Rack for DAWs.

Expected API changes:

  • No stable symbols are planned to be changed. The plan for the Rack v2 API is for at least 90% of plugins to be recompiled for Rack v2 with 0 lines of source changes.
  • All plugins will need to change the "version" property of their plugin.json manifest to begin with "2." instead of "1." to signify that they are built with the Rack v2 SDK. However, all open-source plugins in the VCV Library will be rebuilt by us by automatically changing the old version 1.2.3 to 2.p.1.2.3 or similar. If you wish to make further updates after v2 is released, you will then need to set a “real” version such as 2.2.3.

Beta builds of VCV Rack 1.1.5:

Changelog: https://github.com/VCVRack/Rack/blob/v1/CHANGELOG.md
As always, see https://vcvrack.com/manual/FAQ.html#i-found-a-bug for reporting bugs.


Added LEDLightSlider to componentlibrary.hpp. Example:

	mm2px(Vec(40.0, 40.0), module,

Also note my use of C++ CRTP for adding appearance traits and behavioral properties to widgets.

Also added segment light. Example:

// In `Module`:
enum LightIds {
// In `ModuleWidget()`:
SegmentDisplay* segmentDisplay = createWidget<SegmentDisplay>(mm2px(Vec(2.424, 15.564)));
segmentDisplay->box.size = mm2px(Vec(25.984, 4.524));
segmentDisplay->setLights<WhiteLight>(module, Permutation6::SEGMENT_LIGHTS, 10);



Proposal for port metadata struct to be added to Rack v2.


Proposal for a buffered process() function.


Someone brought up a point of confusion of how the rules of polyphonic modules are defined, so I’d like to clarify the motivation behind the polyphony standard.

If a monophonic signal is patched into a polyphonic module currently running with N engines (each representing a polyphonic channel), the monophonic signal is copied to all engines.

If you’re familiar with programming, you can think of monophonic signals as “scalars” that implicitly cast to polyphonic signals (vectors) when incompatible types interact. For example, the expression a + [b1, b2, b3] should reduce to [a + b1, a + b2, a + b3].

If you’re familiar with mathematics, a monophonic signal is a rank-0 tensor (over time) while a polyphonic signal is a rank-1 tensor (over time). An operation like summing would look like (a + \vec{b})_i := a + b_i. (Note that in this analogy, rank-1 tensors with dimension 1 cannot be represented in Rack.)

The user-benefiting motivation is to be able to use the same input port (e.g. FM input) rather than two different ports (e.g. mono FM and poly FM inputs) in order to either modulate each polyphonic engine (e.g. VCO) with a same-channel polyphonic signal or to modulate all polyphonic engines with a 1-channel monophonic signal.

The standard says

The number of active engines N should be defined by the number of channels of the “primary” input

However, it is purposefully vague in specifying what a “primary” input is. In some cases, there is no primary input at all because all inputs must be treated with equal respect. Martin Lueders and I discussed that when polyphon-izing Befaco A*B+C (where neither A, B, nor C are the “primary” input), the number of engines should be computed by max(#A, #B, #C) where #x is the number of channels of input x. This allows you to mix-and-match mono and poly cables in the A, B, and C inputs, so the result is a polyphonic signal that correctly controls the rest of your polyphonic patch.

Just some thoughts if you’re developing a module that supports polyphony.


A few plugin developers have asked me about the difficulty of preparing your plugin for Rack v2. Will we have another Rack v0.6 -> v1 transition that requires minutes to hours of porting? No. The goal for the Rack v2 API is for at least 90% of plugins to require zero changes to code. Developers of closed-source plugins will need to send me builds of their plugins before the Rack v2 launch. The Rack v2 SDK will be released at least two weeks before Rack v2.

Of course, to take advantage of new features such as Port labels, you’ll need to add code.


Proposal for adding many new Module events.

1 Like

Rack v2 is being worked on, but it’ll be a while before I get around to publishing the source code.

Coming in Rack v2: Port tooltips with voltage readings of all polyphonic channels. 2019-10-27-162411_1600x900_scrot


Coming in Rack v2: There is no more “engine thread”. The engine can only be stepped (i.e. advanced in time) by other threads, such as the audio driver thread managed by VCV Audio or the encoder thread in VCV Recorder. This restructuring has a number of massive benefits.

  • Support for multiple audio drivers. You can use your laptop’s headphone jack, your USB audio interface, Expert Sleepers Eurorack audio interface, etc. all at the same time. No more crashes or deadlocks. Of course, only one audio driver can “drive” the engine clock rate. Other audio drivers might drop samples if their clock rates don’t match exactly. This is selectable by enabling “Primary audio module” in the module’s context menu.


  • In order for each audio buffer to be delivered to your audio device, the audio thread no longer has to lock itself (telling the OS to put it to sleep), wait on the engine thread, and unlock itself (waiting for the OS to schedule the thread again). This saves 1-10 microseconds per audio buffer on average, but more importantly, it saves 100-1000 microseconds when the CPU has an unusually high workload, which could result in audio glitches.
  • The new “Host” audio driver used in Rack for DAWs will run all module code (in Module::process()) directly in the “DAW thread”. Locking the DAW thread to wait on another thread is somewhat unacceptable.
  • Modules like VCV Recorder that can run much faster than real-time can render minutes of audio in only seconds, if they are chosen as the “Primary audio module”.
  • Stability (i.e. probability of crashing) is improved, simply because there are fewer threads dancing around complicated mutexes/shared data.
  • The “Real-time priority” menu item is removed, since the thread priority is now managed elsewhere (RtAudio, etc.)

Proposal for a module whitelist:

By the way, after I approve a proposal, potential changes will typically not be reconsidered until the next Rack major version. So if you have objections or alternative proposals, get them in now before you miss the boat.


Various minor features for Rack 2.0:

  • Red clip lights on VCV Audio when signal goes beyond ±10V.


  • Add module bypass routing API, which replaces module disabling, so developers can specify direct routes from inputs to outputs when users “bypass” the module.

  • Add infinity and NaN protection to cables, so they won’t propagate non-finite values from badly behaving modules. (Performance not fully tested, could be removed.)

  • Duplicating modules also duplicates their input cables.

  • Add the following menus:
void appendAudioMenu(ui::Menu* menu, audio::Port* port);
void appendMidiMenu(ui::Menu* menu, midi::Port* port);

so plugin developers can develop custom audio/MIDI interfaces without adding an AudioWidget/MidiWidget to their panel like VCV Audio-8, MIDI-CV, etc.


  • Full support for numpad keys, such as Enter to open the Module Browser and Ctrl-0/Minus/Plus for zooming the rack.

  • Evaluate mathematical expressions in parameter context menu fields.


  • And most importantly :joy:, use MenuSeparator instead of MenuEntry for separating menu items.



Recent features and fixes in Rack v2:

  • Add basic headless support with the -h flag. It simply loads the given patch or autosave without a window.

  • Add multiple knob modes: scaled linear, absolute rotary, and relative rotary.

  • Add “knobLinearSensitivity” property to settings.

  • Add timestamps to MIDI messages, and use them in Core MIDI modules to improve timing and drastically reduce clock jitter.

  • Allow SysEx messages through MIDI drivers.


This is the first public screenshot of VCV Rack for DAWs, specifically VCV Rack for VST2 Linux. Not pictured, the sine output of VCV VCO-1 is patched into VCV Audio-8, which is using the new “Host” audio/MIDI driver that communicates with the DAW instead of your sound card. VST parameters (soon including labels, units, and actual values) control the parameters of Rack modules. Audio is as stable as can be, since there is no thread-switching overhead as with Rack v1.

The actual VST2 plugin is a ~100KB binary, which dynamically links to a lib-ized version of Rack. This allows for many plugin variations, such as effect/instrument, 2/8/16-channel, and potential VST3/AU/AAX/LV2 plugins, without having N copies of the entire Rack binary.

The source code is maintained in a private git branch and is rebased for every new v2 commit. This means that features and bug fixes added to Rack v2 will immediately be available for Rack for DAWs, so they will follow the same version numbers and will usually be released same-day.

After testing on the other OS’s and DAWs, I’ll focus on windowing, graphics, and improving mouse/keyboard interaction.


Added “MPE mode” to MIDI-CC and MIDI-Gate in Rack v2 which generates 16-voice signals with CC values and gates. Along with MIDI-CV, which already supports MPE in Rack v1, this allows you to take advantage of all features with polyphony on MPE-enabled devices, such as the LinnStrument, ROLI Seaboard, Haken Continuum, Eigenharp, Soundplane, and others.