Artifact issue in my project


#1

I wrote a small project to recreate an issue I am having with my plugin. It is a sequencer that can perform FFT processing. The issue is that I hear an artifact under a certain condition and I am out of ideas on how to get rid of it. I am attaching the source files and the wav sample I use so if anyone has the time and is looking for a small debugging challenge I will be happy to learn what is the reason for my problem (my project is call TestProject and the wav file is in Source directory).

Full description:

AudioOutEngine object is a polyphonic audio channel. It holds an array of FileToPlay objects (called fileQue) where each FileToPlay object in this array has a pointer to the same audio source but has its own startSample value. fileQue size is equal to the number of active voices and is dynamically changing accordingly when new voices enter and old voices exit. A voice is added when an external sequencer hits a note-on step. It than calls AddAutioToQue function in AudioOutEngine and this will make fileQue grow by 1 and set the newly created object to have a startSample = 0 value.

The actual processing happens in AudioOutEngine::sendToOutput() which is being called by pluginProcessor::processBlock() to fill its buffer. At the end of each call the plugin checks if any voice has reached its endSample value and if so, it is being removed from fileQue.

AudioOutEngine also has one FTT object to perform FFT and iFFT before sending the audio to the main output (note that this is not a JUCE object, but it still works…). This is optional so sound can also flow directly without passing through FFT.
FFT is not performed on each voice separately. If FFT processing is enabled, AudioOutEngine will first calculate the summation of all active voices (FileToPlay objects in fileQue) at the current sample of the buffer before passing the total result to the FFT object. The FFT object receives this data sample-by-sample and each 512 samples performs a transform and an inverse transform.

My problem is when FFT is enabled and there are 2 or more active voices, there might be an artifact right when a voice ends, like this:

I created 3 buttons in the project to show that:

  1. There is no problem with playing just one sound with FFT processing.
  2. There is no problem playing several voices without FFT processing. But –
  3. Playing several voices with FFT enabled produces noticeable clicks. Sometimes loud and sometimes barely noticeable.

I wonder if this is just a perforamce issue. The length of the FFT calculation is determined by a variable called FFT_LEN and if I decrease it from 1024 to 256 it does seem to help a bit, but not completly. The fact that the clicking occurs at the exact time when an object is being removed from the que might suggest something else.

Any input on this would be appreciated.

Project files here:
Source.zip (163.8 KB)


#2

On reading it would seem that you need a ramp on the FFT when the sample reading ends. But I’m not a pro.


#3

Haven‘t looked at your code yet, but what kind of FFT processing is it? When you do filtering in the frequency domain, you have to take care about the circular convolution, which produces artifacts at the end of a block.
Another thing what comes to mind, especially as you hear artifacts only at the end: do you do zeropadding when you don’t have enough samples for your FFT?


#4

Thanks Daniel. I found the reason and turns out it was a programming error. At first, I didn’t use zero padding and that completely destroyed the output window. I didn’t understand why and tried many things, one of them was to reset the output window circular buffer index after each sound. Adding zero padding fixed the real problem but I forgot to remove that reset mechanism which was just an experiment and not really needed. Once I removed it the clicks were gone.

FFT is hard :man_facepalming: