我面临着混合音频文件中的原始数据的任务。我目前正在努力从混合数据中获得干净的声音,我不断出现失真或白噪声。
让我们说我有一个来自两个AudioInputStream的两字节数据数组。 AIS用于从给定的音频文件流式传输字节数组。在这里,我可以使用SourceDataLine的write方法播放单个音频文件。我想同时播放两个音频文件,因此我知道我需要执行某种PCM相加操作。
有人可以建议应使用浮点值还是字节值来完成此加法运算?另外,当添加3,4个或更多音频文件时,我想我的问题会更加困难!我需要除以一定数量以避免这种溢出吗?可以说我要添加两个16位音频文件(最小-32,768,最大32,767)。
我承认,我之前对此有一些建议,但似乎无法使其正常工作!我有我尝试过的代码,但没有。
任何建议都会很棒。
谢谢
答案 0 :(得分:2)
首先,我怀疑您是否正在使用完全解码的PCM数据值。如果直接添加字节,则只有在声音以8位分辨率录制的情况下才有意义,这样做越来越少。如今,音频通常以16位或更高的值记录。我认为在某些情况下不需要太多的频率内容,但是在当前系统中,节省CPU并不是那么关键,因此人们选择至少保留“ CD质量”(16位分辨率,立体声,41000 fps) )。
因此,第一步,必须确保将字节流正确转换为有效的PCM。例如,如果使用16位编码,则必须按正确的顺序(可以是big-endian或little-endian)附加两个字节,并使用结果值。
一旦处理妥当,通常只需将这些值相加即可,并且可能施加最小和最大滤波器以确保信号不会超出定义范围。我可以想到有两个原因:(a)音频通常以足够低的音量录制,求和不会引起溢出;(b)信号具有足够的随机性,既有正值又有负值,正面或负面排列的贡献者很少见,而且寿命很短。
使用最小值和最大值将“削波”信号,并可能会引入一些听觉失真,但这是比溢出少的可怕声音!如果您的信号源通常要达到最小值和最大值,则可以将音量因子(在0到1范围内)乘以一个或多个总体贡献信号,以降低音频值。
对于16位数据,它可以直接对两个整数(-32768至32767)相加后的有符号整数执行运算。但是,更常见的做法是“标准化”值,即将16位整数转换为-1到1的浮点数,在该级别上执行操作,然后再转换回-32768到32767范围内的整数并将这些整数分成字节对。
有一本关于数字信号处理的免费书,非常值得一读:史蒂文·史密斯(Steven Smith)的“数字信号处理的科学家和工程师指南”。它将提供更多细节和背景。