Sox:连接多个音频文件,中间没有间隙
Posted
技术标签:
【中文标题】Sox:连接多个音频文件,中间没有间隙【英文标题】:Sox: concatenate multiple audio files without a gap in between 【发布时间】:2014-08-13 08:00:14 【问题描述】:我正在使用 SoX 连接多个(最多 25 个)音频文件
sox first.mp3 second.mp3 third.mp3 result.mp3
它做了它应该做的;将给定文件连接到一个文件中。但不幸的是,result.mp3 中的这些文件之间有一个小的时间间隔。有没有办法消除这个差距?
我正在创建 first.mp3、second.mp3 等,然后通过合并多个音频(相同的长度/格式/速率)来连接它们:
sox -m drums.mp3 bass.mp3 guitar.mp3 first.mp3
如何检查并确保所有这些文件都没有添加时间间隔? (合并和连接)
我需要实现所有连接文件的无缝播放(在浏览器中一个接一个播放它们时可以正常播放)。
感谢您的帮助。
编辑:
我正在运行的命令的确切示例(没有真实文件名)现在是:
sox "|sox -m file1.mp3 file2.mp3 file3.mp3 file4.mp3 -p" "|sox -m file1.mp3 file6.mp3 file7.mp3 -p" "|sox -m file5.mp3 file6.mp3 file4.mp3 -p" "|sox -m file0.mp3 file2.mp3 file9.mp3 -p" "|sox -m file1.mp3 file15.mp3 file4.mp3 -p" result.mp3
这会合并文件并将它们直接通过管道连接到连接命令中。生成的 mp3 (result.mp3) 在连接的文件之间有一个非常轻微的延迟。任何想法都非常感谢。
【问题讨论】:
mp3 是一种有损格式,除了可能是最后的编码步骤之外,您不应在任何地方使用它,因为每次转换为 mp3 都会损坏音频。 【参考方案1】:做到这一点的最好(尽管最无用)的方法是不要将 MP3 文件用作源文件。 WAV、FLAC 或 M4A 文件没有这个问题。
MP3 不是由固定速率的样本组成的,因此裁剪任意长度的部分不会像您预期的那样工作。除非编码器很聪明(如跛脚),否则 MP3 文件音频的开头或结尾通常会出现间隙。我用 0.98 秒长的样本进行了测试(恰好是 73½ CDDA 帧,许多 MP3 编码器使用帧来实现最小样本长度)。然后我用三个不同的 MP3 编码器(lame、sox 和古老的shine)对样本进行编码,然后用三个解码器(lame、sox 和 madplay)解码这些文件。以下是样本长度与原始长度的比较:
Enc.→Dec. Length Samples CDDA Frames
----------------- --------- ------- -----------
shine→lame 0.95" 42095 71.5901
shine→madplay 0.97" 42624 72.4898
shine→sox 0.97" 42624 72.4898
lame→lame 0.98" 43218 73.5000
*Original 0.98" 43218 73.5000
sox→sox 0.99" 43776 74.4490
sox→lame 1.01" 44399 75.5085
lame→madplay 1.02" 44928 76.4082
lame→sox 1.02" 44928 76.4082
sox→madplay 1.02" 44928 76.4082
只有被 lame 编码和解码的文件的长度相同(主要是因为 lame 插入了一个长度标签来纠正这些太短的样本,并且知道如何解码)。无论我使用什么解码器,所有由 sox 编码的内容都会有一个微小的差距。所以加入文件会产生微小的点击。
您的浏览器可能会非常轻微地混合和重叠源文件,因此您听不到咔嗒声。 Gapless playback 很难做到正确。
【讨论】:
*VBR(可变比特率)MP3 不是由固定速率样本组成的。 CBR MP3 是。尽管许多 MP3 是 VBR(大多数编码器中的默认设置,它可以节省空间),但该断言在功能上是正确的,并且在连接之前确定 MP3 是否为 CBR 需要额外的努力。最好完全避免它们,即使它只是先转码为 WAV。 CBR mp3 可能是固定速率的样本,但除非您小心地在音频帧边界上精确裁剪,否则您仍然会丢失。更糟糕的是,如果裁剪后的 mp3 没有长度标签,解码器就无法判断文件末尾的额外数据是合法的静音还是帧填充。您可以转码为带有间隙/点击的 WAV。【参考方案2】:这是我对你的问题的猜测:
sox 在串联期间不会添加时间间隔, 但是,它会在其他操作中增加时间间隔,例如,如果您在连接之前进行转换。要了解发生了什么,我建议您每次检查文件的所有持续时间(例如,您可以使用 soxi)以了解发生了什么。
如果它不起作用(在连接过程中添加了时间间隔),让我再猜测一下:
Sox 添加时间间隔,因为您在文件开头或结尾的样本不接近于零。要解决这个问题,您可以在文件上使用非常短的淡入淡出。
此外,要强制 sox 输出具有明确定义长度的文件,您可以像这样使用 trim 参数:
sox filein.mp3 trim 0 duration fileout.mp3
【讨论】:
感谢您的回答。请查看我编辑的问题以及我的命令示例 - 如果它有帮助的话。 (因为您提到了“其他操作”,而我也在使用管道和合并。但没有转换。) 您能否分别检查每个结果的持续时间以查看 sox 何时添加时间间隔? 我使用 'sox result.mp3 -n stat 2>&1' 来查看其中一个合并的文件,看起来长度相同:/ 当我检查生成文件的时间时,如果我将它除以合并次数,它会下降到 4.0489797 秒而不是 4.048980 秒,这是我得到的单个文件的结果。你认为这真的会产生如此大的不同吗? 不,我没有。我认为这种差异是听不出来的。但我想增加的时间间隔是可以听到的。您能在 audacity 等软件上听到或看到它们吗?【参考方案3】:首先,您需要真正检查文件的开始和结束是否没有静音,我不知道 sox 是否可以做到,但您需要检查开始和结束音频信号的能量(rms,dB)并切断开始并结束静音,要无间隙地加入音频文件,您需要在信号中应用一个窗口函数以像淡入/淡出一样工作,然后交叉淡入淡出一个的开头和另一个的结尾。
sox 提供了一个splice
函数来淡入淡出:
splice [−h|−t|−q] position[,excess[,leeway]]
Splice together audio sections. This effect provides two things over simple audio concatenation: a (usually short) cross-fade is applied at the join, and a wave similarity comparison is made to help determine the best place at which to make the join.
检查文档here
【讨论】:
感谢您的回答。我不确定如何在我的情况下使用拼接;这有点复杂。你能为我的情况提供一个例子吗? 你需要测试什么是最适合你的,试试sox first.mp3 second.mp3 third.mp3 result.mp3 splice -q 4,1
或sox first.mp3 second.mp3 third.mp3 result.mp3 splice -h 2,1
或sox first.mp3 second.mp3 third.mp3 result.mp3 splice -t 2,2
,找到最适合你的选择...
这些(当然也尝试过我自己的)都不适合我。无论如何感谢您的努力以上是关于Sox:连接多个音频文件,中间没有间隙的主要内容,如果未能解决你的问题,请参考以下文章