Tips for Debugging

Lets say I’m writing an effects plugin and when I send audio through it in my DAW, I get glitches, drop outs, and what have you. What are some ways I can debug what’s going on inside my effect? Obviously, I can write to a log file (although as a side note, I’ve been unable to get the Logger to write to a file when I use my vst inside a DAW, while it works fine as a standalone). What do you or your team do?

i personally like to run my audio through signalizer while debugging in my daw.

it is a visualizer that was also written with juce a long time ago and it contains 2 different visualizations for stereo width (that i don’t like a lot tbh), but also an oscilloscope, a normal spectrum analyzer and a spectogram.

for example if you want to look at a single waveform’s behaviour you can set the oscilloscope to sync up with the waveform’s speed so it stays in place while you observe it. works for almost all signals. or you want to know if the frequency is correct and how much aliasing occurs, so you use the normal spectrum analyzer. or you want to find out what “texture” your pitchshifting algorithm has so you use the spectogram. or you need to look at the rhythm of something so you set the oscilloscope up to temposynced values etc.

however beware that it’s a little buggy. sometimes my host crashes when i run the oscilloscope while not playing back audio for some time.

edit: on top of that i think it makes sense to make yourself some little helper plugins. for example i made one that lets you turn on and off a dc offset signal of various amplitude when i wanted to inspect the behaviour of an envelope follower on it.

The best way I’ve found to debug those is logging/printing a part of the signal and deducing the patterns/problems behind. For instance, if you are getting glitches you’d probably see in the signal some numbers out of range (higher or lower than 1.0 and -1.0 respesctively) which would point to wrong operations/dsp code. Or you may see signal cuts (parts of signal followed by 0’s followed by more signal) which could point to a wrong block managing. Those were the most common ones I’ve encountered, specially the latter one when managing voices (I didn’t correctly use the start sample and the end sample, so I’d miss some samples every block).

One thing you should keep in mind with all this:
A common reason for dropouts is that a processBlock callback doesn’t return quick enough because you do something time consuming in it. As writing to a log file or printing to stdout can block for quite a while depending on your system you have to be extremely careful to not introduce further dropouts yourself through your logging :wink:

General rule: Never do any system call (e.g. file access, heap memory allocation, etc…) during your processing callback!

1 Like

Yeah, logging in the process callback is fatal.

If glitching because of CPU you can usually press pause on the debugger, and if you repeatedly get the same bit of code when you press pause, that’s where your problem is.

You use the logger in the callback only when you already have a problem which you are trying to iron out, so you don’t care about the sound itself while trying to fix the bug but only about the data you are outputting. Usually a single pass of a few hundred or thousands of samples is enough, depending on your block sizes. When you fix it you just remove the logger.

To discard the CPU overload, I just reused the CPU usage meter from the tutorials. May not be the most scientific thing but it actually matches the moment you hit 100% with audio glitches due to processing overload.

1 Like

I’m talking about a situation where my program is already glitching or using high CPU so I then use a Logger. I understand it will glitch if the program does disk I/O in the audio callback.

True. I’m only logging data after the drop outs. I would expect there to be drop outs if I write to the logger while in the audio callback. I’m just talking about an unrelated case where for no apparent reason, I can’t seem to get a file to write using the Logger class. That may be better to address in another thread though, just thought I’d mention it.

Then just use DBG to print in console

My VST is an effect running inside a DAW. I don’t think there’s a reasonable way to view std out in Windows in this case.

Additionally if anyone has any ideas about profiling VSTs, that’d be great too!

if you only DBG once per block it’s just fine in most cases. so you can just collect a bunch of stuff you wanna look at in a String and then DBG it at the end of all your loops once

I think you could also send your debug data to a buffer from your audio thread and write to disk in another thread. There are plenty of ways to print from a program with an audio thread. I’m mostly looking for non print debugging methods. Though I’m not sure how to see what you’re printing to std out if you’re running a VST in a DAW, at least on Windows.

Never found a way to do that, either. On Mac, you just run the DAW from the command line in Terminal, and the debug statements appear in the Terminal window. Doesn’t work on Windows.

That’s a good idea. I wonder if I can get this or something like it to work in WSL.

i’m also on windows and when i use DBG it just shows up in visual studio normally

Oh, that’s good. I still have old pre-JUCE code in my older plugin, which used fprintf( stderr, …), and that didn’t work. (Nor did using stdout.) Glad to see that DBG works on Windows! I’ll be changing my debug statements as I move forward. Thanks!

It shows up in Visual Studio for me when I run the stand alone plugin. When I run it from my plugin host I of course no longer see the console’s std out. I can run a plugin in the Visual Studio debugger but then I get no audio coming into it, which makes it impossible to profile performance reliably.

I remember watching this a couple of years ago and found it interesting:

I develop and test on two different systems, so I have the same challenge. I use the Logger and FileLogger classes and and try to keep the amount of logging to a minimum. Typically, I will log the first few and the last few samples in buffer, as that’s generally sufficient.

Whenever possible, I debug standalone from within Visual Studio. That is fine for UI and many non-realtime tasks, but not all.