Debugging audio pops and clicks

On windows, with small buffer sizes (<256 samples), under windows (working perfectly on mac, even with a 64 samples buffer) , I've got pops, cracks and other glitches in the sound output. If I increase the buffer size, they disapear, so I assumed that my audio processing is too slow and can't keep up with the sound card. 

I decided to validate this hypothesis by addding the following code to my main' s process block : 


if(sampleBuffer.getNumSamples()!=mEstimatedSamplesPerBlock)
            {
                DBG("buffer size")
            }
    

double start=juce::Time::getMillisecondCounterHiRes ();

            if(!isSuspended())
            {
               // normal process block
            }
            double end=juce::Time::getMillisecondCounterHiRes ();
            
            float cpuUsage=(end-start)/(sampleBuffer.getNumSamples()*1000/mSampleRate);
            if(cpuUsage>1)
            {
                DBG("Overrun");
            }
            


I have a few overruns (when loading an heavy VST for example) but not much. The cpu usage value is often under 0.25 . Most importantly, I have much more audio glitches than overruns.
 

To make a long story short, this code doesn't help. I've tried to switch the driver (native driver -> asio4all) . Same problem. 

As you can see, I also check the buffer size is always the same by comparing it to the one set in prepareToPlay.

 

Is that because my "overrun detection code" is wrong ? Could there be another reason ? 

Also, there's a weird thing : if I increase the load on the audio thread (more plugins, and samples etc ...) I don't have more glitches...

 

 

 

You can get away DBG in the process thread, but IMHO not for the issues you are troubleshooting (it introduces quite some delays writing to a console).

I would use a bunch of (falsy) booleans that you set to true in processBlock and watch from a timercallback in the GUI thread.

Are you sure your audio interface works ok with short buffers? If you test your plugin in a DAW like Reaper (which allows for debugging tools - Cubase Afaik does not) you can also watch the CPU load of your plugin).

Success!

Thanks for your advice. I should have mention that my application is a standalone which contains plugins, not a plugin itself ! :) . You're right about the DBG but I also have the problem in release mode, where JUCE turns DBG into a no-op I think. I will try the boolean tip, thanks. I might get a better understanding of what is happening :)

What audio device type are you using? DSound/ASIO/WASAPI are all very different, and some are crappier than others when it comes to performance.

I'm using ASIO. Is it possible that it comes from that or from the hardware ? I didn't experience problems in other apps though :/

If it's ASIO then most likely it's your own code that's at fault, I'm afraid!

What hardware? What ASIO driver are you using?

I use ASIO4All [ http://www.asio4all.com/ ], I've tried it on many platforms, and it's been fine.  {Not to say it'll definitly work, but it is unusual if it doesn't.}

 

Must be my own code's fault probably yeah. I tried with ASIO4ALL and got the same results : it depends on the buffer size but I need really large buffers ( ~= 512 samples0 to avoid the occasional click

The amount of issues with audio on Windows is ridiculous. My system has a problem to do with the motherboard/network components such that all audio glitches from time to time. It's to do with DPC latency in various device drivers (not necessarily audio).

Two laptops I have running Windows 7/8 I have don't glitch at all.

Yeah DPC is a tough one. You can't do much about it ...

 

For those interested in the solution of this particular problem

The problem was due to the use of an AsyncUpdater . The audio thread would call triggerAsyncUpdate and that caused occasional pops. I solved this by removing the triggerAsyncUpdate and replacing with a Timer and a timerCallback. Now everything works like a charm. I guess we should avoid using AsyncUpdaters in the audio thread...

Yeah, you want to avoid those mallocs!

Sorry to necro this old thread … But I don’t understand this.
As far as I can tell the AsyncUpdater won’t actually allocate any memory on triggerAsyncUpdate - right? Because it has just that one update message that it keeps a reference to so that it doesn’t get deleted and doesn’t have to be reallocated when a new update is triggered.

Did this change or am I misunderstanding it?

As told here on the forum in multiple threads, posting messages (this is what the AsyncUpdater does behind the scenes) can trigger allocations under some circumstances, so you are best of to avoid them in the audio callback.

1 Like

What are those circumstances? I can’t see any in the code. How else would I transfer audio from the audio thread to the message thread? Polling?