crackling noise with delay

Topics: 64 bit, Audio, Getting Started, Newbie, Performance, Plugin Development
Aug 28, 2013 at 9:25 AM
Hi there,
I am trying to use vst.net in order to practise on .net UIs. But I was also curious about how a vst works, so I tried to make a simple one, following the delay example I found in the sample codes.

I am programming using visual studio 2010 on a 64 bit machine and I am testing the plugin on a win 7 professional 32 bit machine. the daw is an old version of cubase (cubase 2).

The vst works, but it gives me a distorted and cracking sound. If I use only the dry part of the signal, the sound is ok, while if I mix it with the wet delayed part, the sound is not so clean.

I am compiling using dot net framework 2.0 (on the test machine I have dot net 4) and I am building for any cpu (also the Jacobi files I use are anycpu for dot net 2.0)

As I said in the introduction, I am new to vst programming and I wanted to know if it this behaviour is normal or there is something wrong in the configuration.
I found that if I use a filter to reduce the noise, the sound is pretty decent.. Should I have to add a filter in the algorithm? (a low pass one?)

Thank you for any help you can give me.
Coordinator
Aug 28, 2013 at 12:34 PM
Crackling and cutouts usually indicate that the plugin is not processing the audio fast enough. Distortion can be caused by clipping.

Perhaps if you lower the volume at the input of the plugin? Also testing in another host can give you some idea on where to look for the problem.

If you have created a custom UI you may also want to look at if you block the audio thread in any way - that will definitely cause problems in the sound.
A typical host will use several Threads to call into the plugin. One thread is dedicated to producing the audio (what I called the Audio Thread). Typically there is also one (main) thread for calling into the UI. So think of your UI as seperate from the rest of the plugin.

Does the original Delay Sample plugin also distort the sound? If not so it's something you did.

Let us know what you've tried and what results that produced.

Hope it helps,
Marc
Aug 28, 2013 at 9:02 PM
Crackling and cutouts can also be a symptom of not completely filling the output buffer.

Often the output buffer is cleared in ProcessReplacing :

Then you fill it but leave a part of it empty :
|--------|__

This creates more of a stutter sound and is very harsh because of the sharp drop of amplitude in the gaps:
|--------|____|--------|____|--------|____|--------|____|--------|____|--------|__
Sep 6, 2013 at 1:27 PM
Thank you for the replies. I think I found the problem. I used the default Process function from AudioProcessor.cs file of the automatically created project in visual studio. the code for this funcion is what follows.
     public override void Process(VstAudioBuffer[] inChannels, VstAudioBuffer[] outChannels)
        {
            // by resetting the time info each cycle, accessing the TimeInfo property will fetch new info.
            _timeInfo = null;

            if (!Bypass)
            {
                // TODO: Implement your audio (effect) processing here.

                int outCount = outChannels.Length;

                for (int n = 0; n < outCount; n++)
                {
                    for (int i = 0; i < inChannels.Length && n < outCount; i++, n++)
                    {
                        Process(inChannels[i], outChannels[n]);
                    }
                }
            }
            else
            {
                // calling the base class transfers input samples to the output channels unchanged (bypass).
                base.Process(inChannels, outChannels);
            }
        }

        // process a single audio channel
        private void Process(VstAudioBuffer input, VstAudioBuffer output)
        {
            for (int i = 0; i < input.SampleCount; i++)
            {
                output[i] = Delay.ProcessSample(input[i]);
            }
        }
it's not very clear to me the behavior of this function (the annidated for cycle), but I found that if I used a stereo input (and output) the program used just one buffer, which was periodically written for both left and right channel. this created a cracling noise, which was sort of panning throught both channels (I didn't noticed it before).

Now I rewroted it in a simler way, using two buffer, one per channel:
public override void Process(VstAudioBuffer[] inChannels, VstAudioBuffer[] outChannels)
        {
            if (outChannels.Length > 0 && inChannels.Length > 0)
            {
                if (outChannels.Length == 1)
                {
                    for (int k = 0; k < outChannels[0].SampleCount; k++)
                    {
                        outChannels[0][k] = Delay.ProcessSample(inChannels[0][k], "L");
                    }
                }
                else
                {
                    VstAudioBuffer inChannelL;
                    VstAudioBuffer inChannelR;
                    if (inChannels.Length == 1)
                    {
                        inChannelL = inChannels[0];
                        inChannelR = inChannels[0];
                    }
                    else
                    {
                        inChannelL = inChannels[0];
                        inChannelR = inChannels[1];
                    }
                    for (int k = 0; k < outChannels[0].SampleCount; k++)
                    {
                        outChannels[0][k] = Delay.ProcessSample(inChannelL[k], "L");
                    }
                    for (int k = 0; k < outChannels[1].SampleCount; k++)
                    {
                        outChannels[1][k] = Delay.ProcessSample(inChannelR[k], "R");
                    }
                }
            }
        }
I know it is not very elegant and has a lot of repetitions, but in this way it is easier for me to explain the process and see if you find it correct. using this code I have no more cracling.

have a nice day!
Sep 6, 2013 at 9:53 PM
It seems like your problem was failing to completely fill the ouput buffer.

If the number of channels for your use case isn't fixed you should consider doing nested loops like the first code block instead of hardcoding to a maximum of 2 channels.