平滑的声音搜索



关于Java Sound(javax.Sound包),我有一个不那么简单的问题。

我正在实现MP3播放器与交叉淡出和平滑的音量和搜索控制。

我正在以4096字节块的流形式读取声音,并手动计算以毫秒为单位的位置。

当我想寻找()(从流变为红色的位置改变基本位置)时,我听到声波中非常丑陋的"跳跃"声。我试着检查JLayer和其他MP3 API,但它们根本没有seek()函数,或者它们也有这种"丑陋的声音跳跃"。

我的问题是:如何使从一个声波块到另一个声波段的跳跃更平滑?我尝试了插值,但"听不到跳跃"的合理时间是300ms,对于seek()函数来说太长了。

你遇到这个问题了吗?

你知道解决办法吗?

我会在这里粘贴一个代码示例来确定。

public void seek( long pPosition )
{
  sourceDataLine.flush();
  seekIndex = ( sourceDataLine.getMicrosecondPosition() / 1000 ) - currentPositionInMilliseconds;
}
public long getPositionInMilliseconds()
{ return ( sourceDataLine.getMicrosecondPosition() / 1000 ) - seekIndex; }

由于javax.sound 的DataLine API,需要"以毫秒为单位的位置"

谢谢,我很沮丧。。。

如果要转换的块太短,无法进行交叉淡入,则无法真正创建平滑转换,但可以从边界中消除最糟糕的工件。

我所指的糟糕的人工制品通常听起来像是点击或弹出,但如果在短时间内有很多,它可能听起来像是颠簸的声音,或者如果间隔有规律,它甚至可能引入自己的特定音高。这种伪影是创建任意音频块的结果,因为边界处的音频幅度可能从一个块跳到下一个块,或者从块的末尾跳到静音。有几种方法可以消除它,其中最常见的是将边界从任意位置移动到最近的"过零点",这样就不再有跳跃或不连续。或者,由于你的区块在彼此之上腐烂,你可以做点什么来找到区块价值相互交叉的地方,最好是朝着同一个方向。

我知道的唯一方法是直接处理每帧级别的数据。你必须"打开"声音来获取字节并直接进行计算。大多数内置Java控件的粒度都受到缓冲区大小的阻碍,即每个声音数据缓冲区实际上只能处理一个音量变化。

即使在每帧级别上工作,Java缺乏实时性保证也存在一些问题需要克服。但它们是可以克服的。

例如,我制作了一个"剪辑切片器",它使用相当于剪辑的声音作为源。它取样本的随机切片,并将它们串在一起。只有16帧的重叠插值可以保持声音流畅。使用具有16帧重叠的十分之一秒切片,可以很好地从4秒的记录中制作出源源不断的小溪。

我做了一个Theremin,它为音量和音高获取鼠标动作监听器的位置。我让它在大约30或40帧延迟的情况下工作得很顺利。诀窍是在鼠标运动侦听器的输出上加上时间戳,并基于基于该数据进行的计算进行控制,因为事件没有实时顺利到达或处理,从而造成了压缩或其他不连续性。

另一件需要考虑的事情是,数据的范围并不能很好地映射到分贝。因此,低端的小音量差比高端的相同音量间隔更不连续(更容易发出咔嗒声)。我通过将音频数据映射到分贝音量,并根据振幅映射为音量变化量提供动力来解决这个问题。我希望其中的一些想法能有所帮助!

最新更新