Learn Intro to Sample Accurate Patching

Getting Started

Welcome to RNBO

Quickstart

RNBO Basics

Key Differences

Why We Made RNBO

Fundamentals

Audio IO

Messages to rnbo~

Using Parameters

MIDI in RNBO

Messages and Ports

Polyphony and Voice Control

Audio Files in RNBO

Using Buffers

Using the FFT

Export Targets

Export Targets Overview

VST/AudioUnit
Max External Target
Raspberry Pi Target
The Web Export Target
The C++ Source Code Target

Code Export

Working with JavaScript
Working with C++

Special Topics

Sample Accurate Patching

Intro to Sample Accurate Patching

Sample Accurate Patching Reference

Scala and Custom Tuning

RNBO and Max for Live

RNBO Raspberry Pi OSCQuery Runner

Raspberry Pi Debug Interface

Metadata

Export Description

Raspberry Pi GPIO

Updating the RNBO Package

Intro to Sample Accurate Patching

Sample Accurate Patching in RNBO. What sample accurate patching means, what objects support it, and why it matters.

This tutorial introduces the concept of sample accuracy, and discusses some common ways to take advantage of it in RNBO. If you just want to skip to the details, try the reference for Sample Accurate Patching.

As you spend more time working with digital signal processing, you may hear some events described as being "sample accurate." You may, for example, read that the sig~ object can process number messages with sample accuracy. What does this mean? Does it mean that other objects process messages in a sample-inaccurate way? Does that mean that using other objects will cause you to make inaccurate music?

Signal Audio Vectors

RNBO processes audio in chunks, sometimes called vectors. Max does the same thing—this is what's called "Signal Vector Size" in the Audio Status window, letting you specify how many samples Max should process at a time. In Max, RNBO, and all other audio processing applications, there's a trade-off here, where a smaller signal vector size means lower latency at the cost of increased CPU usage. Generally, you set the signal vector size as small as you can get away with.

RNBO Event Model

This brings us back to sample accuracy. RNBO can process both events as well as audio signals. Generally, the event model looks something like this:

  • The host application (Max in the case of rnbo~, perhaps a DAW like Ableton Live if you've exported an audio plug-in) calls into RNBO, asking for the next signal vector's worth of samples.
  • First, RNBO checks to see if there are any events to process. Say an adsr~ receives a nonzero number message, indicating that it should activate its ramp. In this case, RNBO will call into adsr~ with the appropriate number message.
  • Finally, each object in the DSP chain processes its audio.

When we're talking about "sample accuracy," we're talking about how the event model handles message events that happen to occur somewhere in the middle of a signal vector. Consider a patch that looks like this:

sample-accurate-demo.png

What happens if you send the message 0, followed by 0.3, and finally 0.6, all within a single signal vector? What will the output of this patch be?

events-with-audio.png

Remember, message events are processed first, followed by audio. So the *~ object receives a 0.0, followed by a 0.3, followed by a 0.6. It sets its internal state to 0.0, then 0.3, then 0.6, and then it processes the entire audio block. The internal state is 0.6 after handling all the messages, so the output is simply 0.6.

Sample Accuracy

Much of the time, this is totally fine, and in general this allows audio processing objects to be more efficient, since they may only need to do one internal calculation per signal vector. However, there may be situations where you want to be sure that every message is accounted for. For example, maybe you're implementing a very aggressive tremolo, using something like this:

Screen Shot 2022-11-05 at 12.53.06 PM.png

If you try to listen to this (warning, it's a harsh sound) and change the signal vector size in the Audio Status window, you'll find that the quality of sound changes with the signal vector size. That's because the actual value of the multiplier is only changing at the start of each signal vector. However, if you hover over the right inlet to *~, you'll notice that it has the label auto. This means that the type of that inlet is automatically determined based on what's connected to it. In other words, it can accept messages or an audio signal. This is the key: when an audio signal is connected to an object like *~, with an input labeled auto, that object will process every sample of the incoming signal vector. So the input could potentially change several times per signal vector and the object (*~ in this case) will handle the changes.

audio-compared-to-events.png

Since all events in RNBO are timestamped, certain objects can perform a sample-accurate conversion to an audio signal. This what we mean when we say that RNBO is sample accurate, that it's possible to convert events to an audio signal that respects the timing of the event down to the precise sample. The objects that can do this conversion are sig~, click~, line~, and curve~. By putting one of these objects into our patch, we can make any auto inlet into a sample accurate input.

Screen Shot 2022-11-05 at 12.54.47 PM.png

If you try listening to this patch, it will still sound somewhat harsh, but you'll notice that the sound no longer changes if you change the signal vector size. That's because sig~ is turning events into an audio signal while preserving event timing.

sig-output.png

Performance Considerations

So why not just add a sig~ everywhere ?

Screen Shot 2022-11-05 at 12.59.07 PM.png

You could, but processing a signal is much more expensive than processing a single number that changes occasionally—remember, signals are something like 44100 numbers per second.

In general, do you really need to have the release value be set sample accurately to get the full sonic experience that you aim for? Or is it enough that it can be set once per sample vector? This is still very very often—once every 128 samples is still ~300 times a second. Being sensible with where to use sig~ can save a lot of CPU cycles and improve your RNBO device's performance.