重新启动 Clip 对象 - flush() 方法
Posted
技术标签:
【中文标题】重新启动 Clip 对象 - flush() 方法【英文标题】:Restarting a Clip object - flush() method 【发布时间】: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() 方法做了什么来解决我之前的问题?还有,我当初为什么会遇到这个问题?
【问题讨论】:
【参考方案1】:像Clip
这样的数据线有一个内部数据缓冲区,可能是byte[]
。缓冲区通常会在播放位置之前以块的形式填充。
假设在某个时刻我们有:
playback position
v
buffer: [..|.....]
file: [..........|.....................]
因此,如果我们停止该行,缓冲区中仍然有数据——位于播放位置之前的数据。
如果我们所做的只是设置播放位置,则数据仍然存在,并且会在我们下次启动时播放。刷新该行会丢弃此数据。
我们也可以致电drain
等待此数据播放完毕。
【讨论】:
@Kootling 你看我的回答了吗?这回答了你的问题了吗?你还有什么不明白的吗? 这将取决于实现。您可以通过getBufferSize
查找。 open
的一些重载也允许您指定它。我在源代码中四处寻找,似乎默认值(在com.sun.media.sound.AbstractDataLine
中找到)的大小为给定格式的 500 毫秒音频。以上是关于重新启动 Clip 对象 - flush() 方法的主要内容,如果未能解决你的问题,请参考以下文章
从 Xcode 启动 App Clip 时未调用 SceneDelegate 的“继续”
关于hibernate的saveOrUpdate方法的一个问题