2013-11-21 126 views
3

因此,让我们说,我想混这2个音轨:Audacity如何混合音频样本?

Unmixed

在Audacity中,我可以使用“混合和渲染”选项将它们混合在一起,我会得到这个:

Audacity Mix

然而,当我尝试写我自己的代码混合,我得到这个:

My Mix

这基本上是我怎么混的样本:(语法HAXE但它应该是容易遵循,如果你不知道它)

private function mixSamples(sample1:UInt, sample2:UInt):UInt 
{ 
    return (sample1 + sample2) & 0xFF; 
} 

这些是8位采样音频文件,并且我希望产品也是8位的,因此& 0xFF

我明白,只要简单地加入样本,我就会期望剪裁。我的问题是,Audacity中的混音不会导致裁剪(至少不会导致我的代码),并且通过查看第二个(较长)轨道的“尾部”,似乎不会减小幅度。它听起来也不软。

所以基本上,我的问题是这样的:Audacity在做什么,我不是?我想混合音轨听起来就好像他们在另一个上面播放,但我(显然)不想要这个可怕的剪辑。

编辑:

这里是我所得到的,如果我签值之前添加,然后unsign和值,如建议通过Radiodef:

My Signed Mix

正如你所看到的它比以前好得多,但与Audacity产生的结果相比,仍然很扭曲和嘈杂。所以我的问题依然存在,Audacity必须以不同的方式做事。

EDIT2:

予混合所述第一轨道上本身,都与我的代码和Audacity的,并且与发生失真的点。这就是无畏的结果:

Zoom Audacity

这是我的结果:

enter image description here

+1

仅基于屏幕截图,看起来它们是相乘的,而不是相加的。 – ashes999

+0

这看起来比剪裁更怪异。看看短片段的总和,音频完全被破坏,然后完全不受影响。你确定你的8位样本在读入时没有被放大吗?试着拿出&看看会发生什么。 – Radiodef

+0

@ ashes999:我不确定你在说什么,但我可以向你保证我的是被添加的(主要失真的原因是他们没有签名,正如Radiodef指出的那样)。至于Audacity混音,Audacity手册本身陈述了“混合多个曲目_adds_波形混在一起”的行为:http://manual.audacityteam.org/man/Mixing – puggsoy

回答

5

我认为正在发生的事情是,你正在总结他们作为无符号。一个典型的声波是正面和负面的,这就是为什么他们加在一起的方式(有些部分取消)。如果你有一些8位的采样是-96,另一个是96,你总结他们,你会得到0.如果你有什么是无符号的音频,你将取而代之的样本32和224总结= 256(偏移和溢出) 。

你需要做的是在求和之前对它们进行签名。要签名8位样本,将它们转换为带符号的int类型,并从它们中减去128。我假设你所拥有的是WAV文件,你需要在总和之后再次对其进行排序。

Audacity可能会进行浮点处理。我听说过一些关于浮点的可疑声明,例如它具有“无限动态范围”和类似垃圾,但它不像整数那样以明确的方式截取。浮点数的有限范围与整数相同,但最大值和最小值的距离更远。 (这是关于最简单的方式)。浮点可以允许音频中的幅度变化更大,但捕获是整体信噪比低于整数。

随着奇怪的变形我最好的猜测是它是从你正在做的面具& 0xFF。如果你想实际剪辑而不是溢出,你将需要自己做。

for (int i = 0; i < samplesLength; i++) { 
    if (samples[i] > 127) { 
     samples[i] = 127; 
    } else if (samples[i] < -128) { 
     samples[i] = -128; 
    } 
} 

否则说你有两个样本是125,总结得到你250(11111010)。然后你取消签名(加128)并得到378(101111010)。一个&会得到你1111010这是122.其他数字可能会让你的结果是有效的负数或接近0.

如果你想剪辑的东西以外的比特深度n的8位,满量程将为positive (2^(n - 1)) - 1negative 2^(n - 1),例如32767和-32768为16位。

你可以做的另一件事情,而不是裁剪是搜索裁剪和规范化。例如:

double[] normalize(double[] samples, int length, int destBits) { 

    double fsNeg = -pow(2, destBits - 1); 
    double fsPos = -fsNeg - 1; 

    double peak = 0; 
    double norm = 1; 

    for (int i = 0; i < length; i++) { 
     // find highest clip if there is one 

     if (samples[i] < fsNeg || samples[i] > fsPos) { 
      norm = abs(samples[i]); 

      if (norm > peak) { 
       norm = peak; 
      } 
     } 
    } 

    if (peak != 0) { 

     // ratio to reduce to where there is not a clip 
     norm = -fsNeg/peak; 

     for (int i = 0; i < length; i++) { 
      samples[i] *= norm; 
     } 
    } 

    return samples; 
} 
+0

啊,这非常有道理,有点愚蠢我没有意识到:P仍然使用这种方法后(签名,添加,不签名),我仍然得到相当嘈杂的波形,特别是在开始时。这不是可怕的剪裁,但它仍然显着磨擦和不愉快。我将用截图编辑问题。 – puggsoy

+0

“Scratchy”听起来像量化噪声的描述。这可能是由于8位,虽然在我的经验中,8位的量化误差通常不是那么明显。这取决于您的原始信号的RMS有多低。如果出于某种原因需要8位,我的建议是使用更高的位深度,并且只在最后进行量化。只有在最后量化才能最大限度地减少错误,因为它不会通过中间操作复合。这可能是Audacity所做的记录。没有严肃的音频应用程序会在源位深处执行任何DSP。 – Radiodef

+0

不幸的是,似乎没有帮助,我得到了相同的结果。我甚至将它们转换为32位整数(乘以0xFFFFFF是如何完成的),并将它们加在一起,然后将它们写入32位WAV,仍然是同样的事情。在添加之前将它们转换为在1.0和-1.0之间浮动,然后再变回,也不起作用。 – puggsoy

1

这比您想象的要简单得多;尽管您的原始文件是8位,但Audacity在内部将它们作为32位浮点处理。您可以在屏幕截图中的每条曲目左侧的信息面板中看到这一点。这意味着将2个轨道加在一起意味着在每个点处添加两个浮点采样,并且将简单地产生-2.0至+2.0的采样值,然后将其钳位到-1至+1范围。相比之下,将两个8位整数加在一起将产生另一个8位数字,其中的值溢出并包围。 (无论您使用带符号还是无符号值,这都可以应用。)

+0

我注意到了,是的。事情是,我使用Haxe,所有整数都是32位,所以我认为添加两个8位整数不应该成为问题。正如Radiodef指出的那样,用0xFF掩盖它会导致它环绕,这是我没有意识到的。 – puggsoy