频率变化平稳

时间:2017-06-04 12:31:09

标签: java android audio frequency

我试图连续播放声音,应该更改smoothley频率。例如,我的AudioTrack当前正在以100 Hz的频率播放,新频率为1000 Hz。然后我不希望频率跳跃,但是要使smoothley适应变化。我目前的代码如下:

int buffSize = AudioTrack.getMinBufferSize(sampleRate,
                                           AudioFormat.CHANNEL_OUT_MONO,
                                           AudioFormat.ENCODING_PCM_16BIT);
AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
                                       AudioFormat.CHANNEL_OUT_MONO,
                                       AudioFormat.ENCODING_PCM_16BIT, buffSize,
                                       AudioTrack.MODE_STREAM);
short samples[] = new short[buffSize];
int amp = 10000;
double twopi = 8. * Math.atan(1.);
double phase = 0.0;
audioTrack.play();
while (playing)
{
    double newFrequency = getFrequency();
    for (int i = 0; i < buffSize; i++)
    {
        samples[i] = (short) (amp * Math.sin(phase));
        phase += twopi * newFrequency / sampleRate;
    }
    audioTrack.write(samples, 0, buffSize);
}
audioTrack.stop();
audioTrack.release();

当然,这是在后台运行的。我的sampleRate自动设置为可能的最低值:

private int getMinSampleRate()
{
    for (int i = 1; i < 100000; i++)
        if (AudioTrack.getMinBufferSize(i, AudioFormat.CHANNEL_OUT_MONO,
                                        AudioFormat.ENCODING_PCM_16BIT) > 0)
            return i;

    return -1;
}

1 个答案:

答案 0 :(得分:1)

您可以使用low-pass filter来平滑过渡。这是另一个example

double currentFrequency = getFrequency();
double smoothing  = 10;   // calculate based on your sample rate and desired time delta for the change
while (playing)
{
    double newFrequency = getFrequency();
    for (int i = 0; i < buffSize; i++)
    {
        // because you are filling the buffer, deltaTime will be a constant: the time between samples
        currentFrequency += deltaTime * ( newFrequency - currentFrequency ) / smoothing;
        samples[i] = (short) (amp * Math.sin(phase));
        phase += twopi * currentFrequency / sampleRate;
    }
    audioTrack.write(samples, 0, buffSize);
}

保留频率的历史记录,并使用基于增量的增量步骤将其慢慢更改为新值。对于大的增量,值将在开始时更快地变化,然后在结束时更慢。 IIRC,这称为一阶滤波器,因为您无法控制变化的加速度。二阶滤波器可以平滑加速度。

有许多不同的技巧,请查看Wikipedia处的过滤器。

相关问题