如何在双簧管增加音量后避免爆裂的爆裂声?

时间:2018-12-07 17:12:32

标签: android oboe

我开始为Android实现Oboe c ++库。 (根据Build a Musical Game using Oboe 我只是按比例缩放样本以增加音量,它可以正常工作,但会发出爆裂声。 如何增加振幅而不会发出爆裂声? 我试图以一点点增益保存样本声音,但听起来很糟糕。 谢谢。

顺便说一句,在不增加音量的情况下,听起来很清晰,但与其他音乐应用程序相比却非常低。

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

    mTracks[i]->renderAudio(mixingBuffer, numFrames);

    for (int j = 0; j < numFrames * kChannelCount; ++j) {
        audioData[j] += (mixingBuffer[j] * ((float)volume));
    }

编辑:

int16_t Mixer::hardLimiter(int16_t sample) {
    int16_t audioData = sample * volume;
    if(audioData >= INT16_MAX){
        return INT16_MAX;
    }else if(audioData <= INT16_MIN){
        return  INT16_MIN;
    }
    return audioData;
};

1 个答案:

答案 0 :(得分:0)

您发布的代码来自Mixer::renderAudio(int16_t *audioData, int32_t numFrames)。它的工作是将各个轨道的样本值混合在一起,形成一个16位样本的数组。

如果将2个或更多轨道混合在一起而没有先减小这些值,则可能会超过最大采样值32,767(aka INT16_MAX)。这样做会导致回绕(即,将32,768写入int16_t会导致存储-32,768的值),因此会听到失真/破裂的声音。

考虑到这一点,您可以编写一个非常基本的(硬性)限制器-使用int32_t进行音量缩放,并且仅在值不超过最大值时才将其写入int16_t数组中,否则只需写入最大值。

这并不是一个很好的方法,因为您不应该达到16位值的限制。更好的方法是先按比例缩小您的输入采样值,然后在混频器之后(或混频器内部的单个轨道上)添加一个增益级,以使总幅度达到可接受的水平。