0

我正在尝试创建一个简单的函数,该函数将在每次通过缓冲区迭代时降低缓冲区中的音频音量(如淡出)。这是我的简单功能。

double iterationSum = 1.0;

double iteration(double sample)
{
 iterationSum *= 0.9;

 //and then multiply that sum with the current sample.
 sample *= iterationSum;
 return sample;
}

当设置为 44100 kHz 采样率时,这可以正常工作,但我遇到的问题是,如果示例将采样率更改为 88200 kHz,它应该每次只将音量降低一半,因为采样率是两倍,并且会否则在中场休息时结束“淡出”,我尝试使用像 44100 / 88200 = 0.5 这样的因子,但这不会以任何方式使它成为一半。

我被这个简单的问题困住了,需要一个指南来引导我完成,如果在程序期间更改了采样率,我该怎么做才能在每次迭代中使它成为半步,因为这个函数会被调用?

问候,摩根

4

2 回答 2

3

独立于采样率的最稳健的淡出方法是跟踪自淡出开始以来的时间,并使用显式fadeout(time)函数。

如果由于某种原因您不能这样做,您可以根据采样率设置指数衰减率,如下所示:

double decay_time = 0.01; // time to fall to ~37% of original amplitude
double sample_time = 1.0 / sampleRate;
double natural_decay_factor = exp(- sample_time / decay_time);
...
double iteration(double sample) {
    iterationSum *= natural_decay_factor;
    ...
}

的原因~37%是因为exp(x) = e^x,其中 e 是“自然对数”基数,并且1/e ~ 0.3678...。如果您想为衰减时间使用不同的衰减因子,则需要按一个常数对其进行缩放:

// for decay to 50% amplitude (~ -6dB) over the given decay_time:
double halflife_decay_factor = exp(- log(2) * sample_time / decay_time);

// for decay to 10% amplitude (-20dB) over the given decay_time:
double db20_decay_factor = exp(- log(10) * sample_time / decay_time);
于 2013-11-18T19:37:30.347 回答
1

我不确定我是否理解,但是这样的事情呢:

public void fadeOut(double sampleRate)
{
    //run 1 iteration per sec?
    int defaultIterations=10;

    double decrement = calculateIteration(sampleRate, defaultIterations);

    for(int i=0; i < defaultIterations; i++)
    {

        //maybe run each one of these loops every x ms?
        sampleRate = processIteration(sampleRate, decrement);
    }
}


public double calculateIteration(double sampleRate, int numIterations)
{
    return sampleRate/numIterations;
}


private double processIteration(double sampleRate, double decrement)
{
    return sampleRate -= decrement;
}
于 2013-11-18T00:32:58.847 回答