我正在混合四个缓冲区并应用平移。但是,当我触发平移时,我会听到一个剪辑。任何机构都能看到以下代码可能存在的问题: -
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处理的情况下发生。
答案 0 :(得分: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;
答案 1 :(得分:0)
你听到的可能不是剪辑,而是每隔4096个样本(或无论你的缓冲区长度是多少)从不连续处弹出。您需要平滑地插入平移值以避免突然变化。两种简单的方法: 1)定义每个样本的最大变化或2)在整个缓冲区长度内插入新值。
无论哪种方式,最重要的创新是存储当前实际的平移值和目标平移值以便移动。
答案 2 :(得分:0)
您的“将缓冲区转换为浮动”功能是错误的。你必须除以32767而不是32768,否则你会因为MSB的翻转而受到限制。