【问题标题】:Smooth sound seek平滑的声音搜索
【发布时间】:2013-07-14 15:23:19
【问题描述】:

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

我正在实现具有交叉淡入淡出和平滑音量和搜索控件的 MP3 播放器。

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

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

我的问题是:我怎样才能使从一个声波块到另一个声波块的跳跃更平滑?我尝试了插值,但“听不到跳跃”的合理时间是 300 毫秒,这对于 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 audio javasound seek


【解决方案1】:

如果要过渡的块太短而无法进行交叉淡化,则无法真正创建平滑过渡,但您可以消除边界中最糟糕的伪影。

我所指的不良伪像通常听起来像咔哒声或爆裂声,但如果有很多连续的声音,它可能听起来像一种颠簸的声音,或者如果间隔是规则的,它甚至可能引入它自己的特定音高。这种伪影是创建任意音频块的结果,因为边界处的音频幅度可能会从一个块跳到下一个块,或者从块的末尾跳到静音。有几种方法可以消除它,其中最常见的是将边界从任意位置移动到最近的“零交叉”,这样就不再有跳跃或不连续性。或者,由于您的块在彼此的顶部腐烂,您可以做一些事情来找到块的值相互交叉的地方,最好是朝着相同的方向。

【讨论】:

  • 我试过了。我尝试重叠和“平均”每个块之间的转换,我什至尝试使用主增益调制来平衡“音高”跳跃,但问题的核心是 DataLine 是一个 InputStream 管道(这就是 Java 的制作方式,因为 3 JDX13 中的本机库已签名 JVM 不会让我以任何其他方式访问声卡)。所以我不能插值,因为“我不知道接下来会发生什么”它是一个流。如果我“读到,做插值然后排空源”。这需要时间(大约 10 毫秒)才能在快进中产生非常沉重的声音跳跃......
  • 这也是为什么我不将 seek 函数“输出”为用 C 编写的本机函数,因为出于安全原因,JVM 不允许我访问这些地址。
  • Mabye 我不知道有什么噪声调制可以抵消类似的“太多跳跃”的波。一些聪明的东西可以让 API 本身保持轻量级。我知道它可以做到重量级,但这不是我寻求的解决方案......
  • 我不是建议插值:我建议您根据它们的幅度重新定义您播放的块的边界。
  • 过零搜索的方法有哪些?
【解决方案2】:

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

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

例如,我制作了一个“剪辑切片器”,它使用剪辑的等效项作为源声音。它随机抽取样本切片并将它们串在一起。仅 16 帧的重叠插值就可以保持声音流畅。使用具有 16 帧重叠的 1/10 秒的片段非常适合从 4 秒的录制中制作出无尽的流小溪。

我制作了一个 Theremin,它将鼠标运动听者的位置用于音量和音高。我让它在大约 30 或 40 帧延迟的情况下工作得非常顺利。诀窍是对鼠标运动侦听器的输出进行时间标记,并根据基于该数据进行的计算来控制控制,因为事件不会实时到达或得到平滑处理,从而产生拉链或其他不连续性。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-30
    • 2014-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多