Rack v1 development blog

Okay, added a required argument after -p to set the screenshot zoom, e.g. -p 2 or -p 0.5


After the public launch of v1, will it be possible for 0.6.2c to exist on the same workstation and for each version of Rack to have their own plugin database?

The reason I ask is that I’m sure it will take a while for all 3rd party developers to compile their add-ons for v1. Plus there are a number of plugins that appear to be no longer in development (things like the excellent Animated Circuits stuff springs to mind).

Apologies for bothering you so close to launch, I’m sure you have enough on your plate already. But whilst I have your attention I recently noticed that the tuning of Audible Instruments Resonator is out by 30 semitones (compared to the tuning of Rings in Softube Modular) when it’s being accessed via Bridge (tested with Ableton Live 10). It’s easily fixable with a Pitch device set to +30 but it seems an unusual tuning difference when compared to e.g. Macro Oscillator (here the tuning between Softube Modular and Rack is identical). With it being a 2.5 octave difference, sequences are half an octave out compared to the piano roll regardless of octave range, so it might catch some newcomers out.

1 Like

Well yes that is all very obvious, but thanks.


Issue Tracker: https://github.com/VCVRack/AudibleInstruments/issues

VCV Pitch/Frequency standards: https://vcvrack.com/manual/VoltageStandards.html#pitch-and-frequencies

Added Core AUDIO-16 for accessing up to 16/16 input/output channels of your audio interface.

Design not finalized.


I just realized that, while great for developers, sadly for users this is only per-module (unless the pain meds are kicking in and I can’t read).

Is there anything in the works to be able to screencap an entire patch in one shot?

The feature is mainly for me and @cschol to make our lives 99.9% easier when screenshots are needed for the Plugin Manager.


I read “takes screenshots of all modules” as - when you call it, it takes a screenshot of every single module in every single plugin you have installed, and dumps them to disk.


140 files changed, 24014 insertions(+), 18176 deletions(-)

:sunglasses: :stuck_out_tongue_winking_eye:

(20190323 -> 20190509)


Wow, that’s a lot… I think Rack’s .hpp/.cpp files are only 24,600 lines, not including Makefiles, licenses, and documentation, but Rack v1 is pretty much a rewrite so it makes sense.

1 Like

Trying ./Rack -d -p 0.5 (and 2 and 1 and nothing), same results. crashes Rack on various modules. Latest was SEQ3. Never has made it through whole list. Running win10, msys2… latest V1 - gpl…
All show up properly on preview, and work on rack just fine.

This was fixed in a new commit. Have you pulled and recompiled?
If so, I need a stack trace with gdb.

missed the commit 12 hours ago… Works fine now! Thanks

Rack now saves patches to mypatch.vcv.tmp and upon success, moves it to mypatch.vcv. This guarantees that no patch file corruption is possible when writing patch files, since renaming is an atomic operation on all relevant filesystems.


Added HybridBarrier which might be interesting to anyone who writes threaded code. This is a spin barrier that turns into a mutex barrier when APP->engine->yieldWorkers() is called during a Module::step() method.

Here’s how engine workers functioned before.

  • Every sample, all workers race to grab modules in the rack and call their step() method until no modules are left.
  • When a worker is finished with that task, it spins in a while (!allWorkersAreFinished) {} loop.
  • The main engine thread (which is also worker #0) runs some serial code, like copying voltages from outputs to inputs along cables, and param smoothing.
  • Repeat.

Suppose you have 100 modules taking roughly 1 μs each to step one sample. Then the time between when the first worker finishes and the last worker finishes is roughly 1 μs. (Imagine you have a stack of 100 rocks of various sizes and you naively try to divide them evenly into 3 groups. The weight difference between the heaviest and lightest group will be around the average weight of 1 rock.) This isn’t a lot of time to be spinning, so not much CPU is wasted between each sample.

Now suppose that Core AUDIO now needs to block until the audio driver thread is ready to receive a new buffer. This might be 128 samples * 44100 Hz = 2900 μs of wait time, so meanwhile other worker threads will be spinning for a very long time, waiting on Core AUDIO to return. This pegs the CPU core at 100%. Here’s a solution.

  • Before Core AUDIO begins waiting, tell the engine to tell all workers to stop spinning and lock on a mutex instead.
  • This (usually) causes all workers to yield to the OS and let other application threads do their thing or allow the core to idle.

It takes 10-100 ns for a spinlock to “wake up” and 1,000-10,000 ns for a mutex to wake up, so calling yieldWorkers() has a massive cost, so it should only be used when you know your DSP kernel needs to block for much longer than 1,000 ns.


I think it’s best to close this thread now to prevent non-official posts, since this is how a blog normally functions.

If you have a question about a blog post, click the post’s timestamp in the top-right and click “New Topic”.


32 posts were merged into an existing topic: Rack development blog