1

我正在混合四个缓冲区并应用平移。但是,当我触发平移变化时,我会听到一个剪辑。任何人都可以看到以下代码可能有什么问题:-

for (int i = 0 ; i < numFrames; i++) {
    //Convert buffer to float
    float s1 = track1[0][i] / 32768.0f;
    float s2 = track2[0][i] / 32768.0f;;
    float s3 = track3[0][i] / 32768.0f;;
    float s4 = track4[0][i] / 32768.0f;;

    //Apply pan on track one
    float s1R = s1 * sqrt( 1 - panA ); 
    float s1L = s1 * sqrt( panA ); 

    //Apply pan on track two
    float s2R = s2 * sqrt( 1 - panB ); 
    float s2L = s2 * sqrt( panB ); 

    //Apply pan on track three
    float s3R = s3 * sqrt( 1 - panC ); 
    float s3L = s3 * sqrt( panC );

    //Apply pan on track four
    float s4R = s4 * sqrt( 1 - panD ); 
    float s4L = s4 * sqrt( panD );

    //Mix the right channel
    float mixedR = s1R + s2R + s3R + s4R;

    mixedR *= 0.6f;
    if(mixedR > 1.0f) mixedR = 1.0f; 
    if(mixedR < -1.0f) mixedR = -1.0f;

    //Mix the Left channel
    float mixedL = s1L + s2L + s3L + s4L;

    mixedL *= 0.6f;
    if(mixedL > 1.0f) mixedL = 1.0f; 
    if(mixedL < -1.0f) mixedL = -1.0f;

    //Apply the Left channel 
    audioIn[0][i] = (short) (mixedL * 32768.0f);

    //Apply the right channel
    audioIn[1][i] = (short) (mixedR * 32768.0f);
}

平移算法可以改进,我从这里提出:-

http://www.kvraudio.com/forum/viewtopic.php?t=181222&postdays=0&postorder=asc&start=0

NumFrames 为 512;混合音频后,我将使用 Dirac 应用时间拉伸算法。

剪裁在没有经过 Dirac 处理的情况下发生。

4

3 回答 3

2

您正在获取 4 个可能的满量程信号,将它们加在一起,然后在使结果输出信号饱和之前按 0.6 缩放。因此,在饱和之前,您的最大范围是 +/- 4 * 0.6 = +/- 2.4。因此,您听到一些剪辑就不足为奇了。如果乘以 0.25 而不是 0.6,那么即使在最极端的情况下也应该消除削波,但在一般情况下输出信号电平可能会有点低。

为了验证这一点,您可以在饱和代码中添加一些调试日志,例如

#if DEBUG
    if (mixedR > 1.0f || mixedR < -1.0f)
        fprintf(stderr, "Clipping occurred for mixedR = %g\n", mixedR);
#endif
    if(mixedR > 1.0f) mixedR = 1.0f; 
    if(mixedR < -1.0f) mixedR = -1.0f;
于 2011-10-13T09:08:37.400 回答
0

您的“将缓冲区转换为浮动”功能是错误的。您必须除以 32767 而不是 32768,否则您将因 MSB 翻转而出现削波。

于 2013-10-28T17:45:44.107 回答
0

您听到的可能不是剪辑,而是每 4096 个样本(或无论您的缓冲区长度是多少)从不连续性中弹出。您需要平滑地插入平移值以避免突然变化。两种简单的方法可以做到这一点:1)定义每个样本的最大变化或 2)在整个缓冲区长度上插入新值。

无论哪种方式,本质的创新是存储当前的实际平移值和要移动的目标平移值。

于 2011-10-25T22:25:14.257 回答