2

javax.sound.sampled.Clips我想在我的 Java 小程序中加载到数组中的两个音频剪辑之间平滑过渡。目前我停止一个剪辑并开始下一个剪辑,但由于音频突然停止和开始,这会产生可听见的咔嗒声。我需要使用 Clip 界面,以便我可以在保持相同轨道位置的剪辑之间进行循环和转换。

我曾尝试在停止一个剪辑之前降低增益,然后在我开始下一个剪辑时使用FloatControl.Type.MASTER_GAIN. 如果我想快速改变增益,这需要刷新缓冲区,即使如此,如果我试图太快地改变增益,我也会出现点击和口吃。加上刷新缓冲区需要我停止并重新启动剪辑以取回已刷新的缓冲区(因此我不会向前跳过已刷新的部分),这会引入我试图摆脱的相同点击。

有没有人有快速改变增益的经验(在 200 毫秒内),比如从 0dB 到 -60dB。我在想我可能不得不降低到缓冲区级别并开始直接操作这些位,但我不知道如何从 Clip 界面进行操作。

有什么建议么?

4

1 回答 1

1

发现 Clip 类的一个很棒的扩展,它允许您创建具有多个流的单个 Clip 对象,然后使用自定义转换(例如淡入和淡出)在流之间切换。这摆脱了烦人的点击!

我在 HydrogenAudio 论坛上找到了它,由一个很棒的家伙写的,他的句柄是 googlebot。它在 GNU 许可下是开源的。

这是一个论坛帖子的链接,该链接描述了为该课程创建的程序:hydrogenaudio.org/forums/index.php?showtopic=80673(垃圾邮件机器人说我只能发布一个链接:P)

这是一个指向 Google 代码页的链接,您可以在其中获取 Java 类文件: http ://code.google.com/p/advancedabx/source/browse/#hg/AdvancedABX/src/de/uebber/sound/lib

如果您最终使用这些类,您可能会在 SwitchableArrayClip.java 类的 open 和 addstream 函数中发现一些数组边界错误。

您将需要更改:

// Fill it
    int numRead = 0;
    int offset = 0;
    while (numRead != -1) {
        numRead = stream.read(audioData[0], offset - numRead, len - numRead);
    }

到:

// Fill it
    int numRead = 0;
    int offset = 0;
    while (numRead != -1) {
        numRead = stream.read(audioData[0], offset, len - offset);
        offset += numRead;
    }

由于播放器是线程化的,还有一些其他问题,例如使用 setFramePosition。但是我会让你弄清楚这些,或者你可以在这里问,我会告诉你我做了什么来修复它们。

希望这对某人有帮助!

于 2010-09-02T18:30:04.867 回答