【问题标题】:Restarting a Clip object - flush() method重新启动 Clip 对象 - flush() 方法
【发布时间】:2015-04-24 01:44:31
【问题描述】:

Javadoc for DataLine.flush() 状态

从行中清除排队的数据。刷新的数据被丢弃。在某些情况下,并非所有排队的数据都可以丢弃。例如,混音器可以从缓冲区中刷新特定输入行的数据,但仍然会播放输出缓冲区中已经存在的任何未播放数据(混合的结果)。如果您想在重新开始播放或捕获时跳过“陈旧”数据,您可以在暂停一行(正常情况)后调用此方法。 (刷新未停止的行是合法的,但在活动行上这样做可能会导致数据不连续,从而导致可察觉的点击。)

这到底是什么意思?

此外,对于重新启动 Clip 对象,该站点上的许多人建议使用此:

clip.stop();
clip.setFramePosition(0);
clip.start();

当使用上面的代码时,我注意到一个示例剪辑(如果重要的话,大约 15 秒长)不会从一开始就重新开始,并且它的“重新开始位置”不一致。但是,当我尝试

clip.stop();
clip.flush();
clip.setFramePosition(0);
clip.start();

剪辑完美运行,并在声音开始时重新开始。我的问题是,flush() 方法做了什么来解决我之前的问题?还有,我当初为什么会遇到这个问题?

【问题讨论】:

    标签: java flush javasound clip javax.sound.sampled


    【解决方案1】:

    Clip 这样的数据线有一个内部数据缓冲区,可能是byte[]。缓冲区通常会在播放位置之前以块的形式填充。

    假设在某个时刻我们有:

                playback position
                       v
    buffer:         [..|.....]
      file: [..........|.....................]
    

    因此,如果我们停止该行,缓冲区中仍然有数据——位于播放位置之前的数据。

    如果我们所做的只是设置播放位置,则数据仍然存在,并且会在我们下次启动时播放。刷新该行会丢弃此数据。

    我们也可以致电drain 等待此数据播放完毕。

    【讨论】:

    • @Kootling 你看我的回答了吗?这回答了你的问题了吗?你还有什么不明白的吗?
    • 这将取决于实现。您可以通过getBufferSize 查找。 open 的一些重载也允许您指定它。我在源代码中四处寻找,似乎默认值(在com.sun.media.sound.AbstractDataLine 中找到)的大小为给定格式的 500 毫秒音频。
    猜你喜欢
    • 1970-01-01
    • 2020-02-13
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多