Downsampling 96 to 44.1 kHz audio fast (realtime) in a VST instrument

1.2k views Asked by At

I'm trying to make a fast downsampling function in my VSTi (c++), but I'm having some hard time to get it to work. This is what I have and what I'm trying to do. First off is the low-pass filter..

void resetFilter()
{
     c = 1.0 / tan(3.14159265359 * 22050 / 96000.0); // 1.0 / tan(PI * filter_freq / samplerate)
     r = 2.2; // resonance factor

     a1 = 1.0 / ( 1.0 + r * c + c * c);
     a2 = 2* a1;
     a3 =a1;
     b1=2.0 * ( 1.0 - c*c) * a1;
     b2 =( 1.0 - r * c + c * c) * a1;
     in1 = 0;
     in2 = 0;
     in3 = 0;
     out1 = 0;
     out2 = 0;

}
float lowpass(float NewSample)
{
        float output = (a1 * NewSample) + (a2 * in1) + (a3 * in2) - (b1 * out1) - (b2 * out2);
        in2 = in1;
        in1 = NewSample;
        out2 = out1;
        out1 = output;

return output;
}

After using the above low-pass filter I play the buffer by stepping 96000/44100=2,1769. Truncating which means that I will get index (int) series by the pp->cOffset[o] 2, 4, 6, 8, 10, 13, 15, 17, 19, 21, 23, 26, 28, 30 ... from the 96kHZ buffer. I can hear that the filter made success on the high frequencies but there is a deeper metallic sound because of the way I read my series from the buffer.

Then I tried to add the following to deal with it (don't laugh please):

if ((pp->cOffset[o]-(int)pp->cOffset[o])>=.5 && (pp->cOffset[o]-(int)pp->cOffset[o])<1)
{
 float sum1 = (readPreBuffers[0][0][pI][(VstInt32)pp->cOffset[o]]); // the pp->cOffset[o] is a float
 float sum2 = (readPreBuffers[0][0][pI][(VstInt32)pp->cOffset[o]+1]);
 float sum = ((sum1*0.8) + (sum2*1.2))/2.0;
 outputs[0][i] += (sum / 32768.0)*(pp->cVelocity[o]/127.0);
 outputs[1][i] += (sum / 32768.0)*(pp->cVelocity[o]/127.0);
}
else
read as normal..

This made some of the metallic sound disappear but not all, I'm lost and don't know how to do it. I have less hair on my head now than yesterday!

outputs is the output buffers to the host, and the host is set to 44.1kHz samplerate while my wave sample is 96kHz.

Please let me find a way to move on.

1

There are 1 answers

1
Magnus On

I've found it, all of the deeper metallic sound is gone.

I'm using the low-pass filter as before but now when reading from the filtered sound buffer I'm using the following method instead of the one in my question..

float deciI2 = (pp->cOffset[o]-(int)pp->cOffset[o]);
float deciI1 = 1 - deciI2;

float sum1 = (readPreBuffers[0][0][pI][(VstInt32)pp->cOffset[o]]);
float sum2 = (readPreBuffers[0][0][pI][(VstInt32)pp->cOffset[o]+1]);
float sum = ((sum1*deciI1) + (sum2*deciI2))/2.0;
outputs[0][i] += (sum / 32768.0)*(pp->cVelocity[o]/127.0);
outputs[1][i] += (sum / 32768.0)*(pp->cVelocity[o]/127.0);

This is working, if someone has a better method I'll be glad to see it. Wanned to share this if someone else would need it in their work.

Regards, Morgan