我已经成功使用此处的答案以不同的速度播放声音文件,但我需要能够在播放时调整速度。我想到过使用两种方法。第一种是将音频文件分割成短片并在最后一个结束后播放每个短片。我还没有尝试过,但似乎它很容易以文件自行播放或有短暂间隙而结束。
另一种方法是将原始文件作为流,然后使用它创建一个流,根据需要加速或减慢它的速度。这看起来效果很好,但是为了构造一个 AudioInputStream,我要么需要一个已知长度的 InptutStream,这是不可能提前弄清楚的,要么是一个 TargetDataLine,这是一个比我有更多方法的接口(interface)愿意实现。
有更好的方法吗?另外,为什么AudioInputStream需要知道流的长度?
或者,有我可以使用的外部库吗?
最佳答案
如果您只是简单地播放音频文件(例如 .wav)并且可以改变声音的音调,那么一种简单的方法是从 AudioInputStream
读取数据,转换为 PCM,以所需的速率插入数据,转换回字节并通过 SourceDataLine
发送出去。
要实时加速或减速,请将输入松散地耦合到保存用于处理传入帧的增量的变量。为了最大限度地减少不连续性,您可以在给定帧数内平滑从一个音高到另一个音高的过渡。
这样做是为了实现开源库中频率的实时变化AudioCue ,在 github 上。频率变化之间的平滑设置为在 1028 帧(大约 1/40 秒)内进行。但更快的改变当然是可能的。该库中的声音数据取自 PCM 值的内部 float 组。但是,将数据读取为一行而不是固定数组所需的代码的一个很好的示例可以在 Sound Trail, Using File Filters and Converters 中的第一个代码示例中看到。 。您可能希望使用 InputStream
作为 AudioInputStream
的参数。在示例中,当它显示“这里,做一些有用的事情..”时,您将转换为 PCM,然后使用线性插值将光标浏览具有所需频率的结果 PCM,然后重新打包并通过 源数据行
。
如果您希望保留音调(仅时间拉伸(stretch)或压缩),那么这开始需要更重型的 DSP。 This thread at the StackExchange Digital Processing网站有一些相关信息。我在使用汉明窗制作颗粒以帮助它们之间的交叉淡入淡出方面取得了一些成功,但是其他一些解决方案超出了我的能力(并且我在很长一段时间)。但如果我没记错的话,可以实时改变颗粒的间距。虽然听起来不如 Audacity 工具的算法那么好,但这可能更适合我。我基本上是自学和尝试,而不是在该领域专业工作。
关于java - 用Java制作不同播放速度的声音文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58107196/