Control rate

boonier
Posts: 30
Joined: Thu Apr 21, 2022 1:23 pm

Control rate

Post by boonier »

hello,

is there any notion of control rate in VM, or does everything run at audio rate?

I see there are timers but probably not optimal (or sample accurate)?

cheers
UrbanCyborg
Posts: 585
Joined: Mon Nov 15, 2021 9:23 pm

Re: Control rate

Post by UrbanCyborg »

I'm not sure what you mean by "control rate." If you literally mean "the rate the controls are sampled at," then no, no module worth anything is running most of its controls at 48 kHz (maybe some special oddball controls, but that would be it). The controls are generally handled by timer-based routines; about the only thing affecting control rates within that restriction is a bit of slew modification via SmoothValue objects.

If you meant something else, then you'll have to be more specific.
Cyberwerks Heavy Industries -- viewforum.php?f=76
boonier
Posts: 30
Joined: Thu Apr 21, 2022 1:23 pm

Re: Control rate

Post by boonier »

Sorry, I mean control rate; Pure Data/Csound/Max etc have a control rate tick running at every 64 samples, which reduces the cpu load for certain things that don't need to run at sample rate.

For example, some envelopes don't need to run at sample rate if doing slow a modulation of another thing (pitch/amp/whatever), so therefore you can shave off a bit of cpu usage by running at control rate.
User avatar
utdgrant
Posts: 530
Joined: Wed Apr 07, 2021 8:58 am
Location: Scotland
Contact:

Re: Control rate

Post by utdgrant »

The most obvious way to do this would be to have a global (or local static) counter variable for use inside the ProcessSample() method.

Set it to your 'divider' value (say, 64) initially.

Decrement it every pass through ProcessSample().

When it reaches 0, process your 'Control Rate' code segment, then reset the counter back to your 'divider' value.


You could even spread the load further by arranging for different 'phases' of control data processing, by executing:

Phase 1 when counter reaches 48
Phase 2 when counter reaches 32
Phase 3 when counter reaches 16
Phase 4 when counter reaches 0

However, this may be a false economy, as ProcessSample is executed in 'batches' depending on buffer settings, latency, etc. So you might end up executing all phases within one buffer's worth of audio data anyway! :)
______________________
Dome Music Technologies
User avatar
utdgrant
Posts: 530
Joined: Wed Apr 07, 2021 8:58 am
Location: Scotland
Contact:

Re: Control rate

Post by utdgrant »

The Nord Modular system runs in a similar fashion.

The overall system sample rate is 96kHz. However, 'control' modules are often designed to be executed at a quarter of that rate, i.e. 24kHz.

It was a good compromise, which allowed you to use multiple 'control' modules with a much lower impact on overall DSP load.
______________________
Dome Music Technologies
UrbanCyborg
Posts: 585
Joined: Mon Nov 15, 2021 9:23 pm

Re: Control rate

Post by UrbanCyborg »

The easiest way to get something running at other than the sample rate is to create a timer, either a named one, or the GUI Update Timer. By default they notify every 50ms, but you can set another value when you create them.

Reid
Cyberwerks Heavy Industries -- viewforum.php?f=76
User avatar
utdgrant
Posts: 530
Joined: Wed Apr 07, 2021 8:58 am
Location: Scotland
Contact:

Re: Control rate

Post by utdgrant »

UrbanCyborg wrote: Thu May 12, 2022 11:19 am The easiest way to get something running at other than the sample rate is to create a timer, either a named one, or the GUI Update Timer. By default they notify every 50ms, but you can set another value when you create them.

Reid
The trouble with this approach is that you end up creating two virtual 'threads', which can lead to race conditions.

For example, I've noticed odd behaviour when trying to make LED switching efficient. I wanted to ensure that I only called SetValue() whenever an LED's state had actually changed from its previous one. This is in contrast to setting them all to their respective on/off states unconditionally, every time Notify (GUI_Update_Timer) was called. I don't know if the VoltageLED class is clever enough to only redraw when a state changes, but I wanted to make sure it was as efficient as possible under my control. I started noticing that sometimes LEDs would 'hang' in the on or off state, irrespective of the underlying condition they were displaying.

It appears to be the case that the Notify() process can be interrupted by ProcessSample(). Again, I don't know enough about how the Voltage Modular infrastructure works under the hood to say this for sure. If interrupting is possible, this would mean that a variable which is modified during SampleProcess() cannot be relied upon to hold the same value throughout the duration of Notify().

OTOH, it might simply be the case that I was just being stupid and not using global variables in a 'thread safe' way. :)
______________________
Dome Music Technologies
ColinP
Posts: 935
Joined: Mon Aug 03, 2020 7:46 pm

Re: Control rate

Post by ColinP »

ProcessSample() definitely interrupts Notify() otherwise any blocking code such as a menu call in Notify() would cause the audio to stall.

A very long time ago I think I tested the efficiency of calling SetValue() on various controls and if I remember correctly CA's code doesn't optimize, so it's wise to do a test yourself. Also beware of triggering notifications on some components. Although thankfully CA eventually added a SetValueNoNotification() method to make it easier to avoid strangling yourself.

GetValue() seems to just be a wrapper though so seems efficient enough to call from inside ProcessSample().

My assumption is always that the CA code is minimalistic and totally without any optimizations or error checking but I always assume that when using a closed API anyway.

I also assume that there is nothing clever going on in the way threads are handled so it's incredibly easy to trip up. The any thread can interrupt any thread notion appears to be true in VM so code safely folks!

I've had multiple weird bugs that only occurred once in a blue moon that were thread safety problems when I eventually tracked them down.

On timers I've seen strange behaviour too. I've not managed to figure it out but it might be that timer thread overrun causes problems - i.e. when another timer event happens before your timer handler has finished executing. Just a hunch BTW.

Although VM seems to be built on JUCE which is open-source C++ code the actual details of how events are dealt with are sufficiently opaque that us developers are left having to devise diagnostic code to try to figure out what the hell is happening.

On a lighter note for anyone just starting coding in VM, simple modules won't encounter many problems so don't worry too much!
ColinP
Posts: 935
Joined: Mon Aug 03, 2020 7:46 pm

Re: Control rate

Post by ColinP »

BTW when I say ProcessSample() interrupts Notify() it is as utgrant pointed out slightly more complicated as the ProcessSample() calls are grouped in blocks corresponding to the buffer size. So Notify might be interrupted by 128 calls to ProcessSample() (or whatever the buffer size is) before being revived.

Although I suspect the thread running the block of ProcessSample() calls doesn't create a critical zone (temporarily disabling interrupts) so I assume a timer thread can actually interrupt a call to ProcessSample() too, just to add to the fun.
User avatar
utdgrant
Posts: 530
Joined: Wed Apr 07, 2021 8:58 am
Location: Scotland
Contact:

Re: Control rate

Post by utdgrant »

Great insights, Colin!

Much appreciated,
Grant
______________________
Dome Music Technologies
Post Reply

Return to “Module Designer”