【问题标题】:Downsampling 96 to 44.1 kHz audio fast (realtime) in a VST instrument在 VST 乐器中快速(实时)下采样 96 至 44.1 kHz 音频
【发布时间】:2013-09-18 14:35:50
【问题描述】:

我正在尝试在我的 VSTi (c++) 中创建一个快速的下采样功能,但我很难让它工作。这就是我所拥有的,也是我正在尝试做的。首先是低通滤波器..

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;
}

使用上述低通滤波器后,我通过步进 96000/44100=2,1769 播放缓冲区。 截断这意味着我将通过 pp->cOffset[o] 2, 4, 6, 8, 10, 13, 15, 17, 19, 21, 23, 26, 28, 30 获得索引(int)系列。 . 来自 96kHZ 缓冲器。 我可以听到滤波器在高频上取得了成功,但由于我从缓冲区中读取我的系列的方式,所以有更深的金属声音。

然后我尝试添加以下内容来处理它(请不要笑):

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..

这使一些金属声音消失了,但不是全部,我迷路了,不知道该怎么做。 我现在头上的头发比昨天少了!

outputs 是主机的输出缓冲区,主机设置为 44.1kHz 采样率,而我的波形采样为 96kHz。

请让我想办法继续前进。

【问题讨论】:

    标签: c++ audio vst downsampling lowpass-filter


    【解决方案1】:

    我找到了,所有更深沉的金属声音都消失了。

    我像以前一样使用低通滤波器,但现在从过滤后的声音缓冲区读取时,我使用以下方法而不是我的问题中的方法..

    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);
    

    这是有效的,如果有人有更好的方法,我会很高兴看到它。如果其他人在工作中需要它,希望分享它。

    问候,摩根

    【讨论】:

    • 准确地说,这被称为“移动平均”,而不是我所追求的,我只是不能让它听起来很棒!这使得播放时奇怪的采样率在音高上上下波动..:/
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多