如何在不使用控件的情况下调整线路的音量

发布于 2024-12-22 22:36:52 字数 827 浏览 3 评论 0原文

我刚开始使用 javax.sound.sampled 包,我选择使用该包的原因是与一些更简单的声音解决方案(例如 AudioClip)相比,我可以更好地控制我正在使用的音频。

我已通读:Oracle 的声音教程 (或者至少是我能掌握的),但我没有看到使用他们看起来的 Clip 界面来调节 Line 上播放的级别/音量的方法在允许您创建声音的包部分中提供此类选项,但我找不到任何方法可以通过我的 Line 或 AudioInputStream 进行这些调整。

我找到了带有文字的[此]页面,

另一方面,浮动控件非常适合表示连续可变的控件,例如平移、平衡或音量。

但我的计算机上没有线路返回任何控件(使用Line.getControls()

(我试图强制线路接受FloatControl.Type.VOLUME,类似于这个但我收到“不支持的控制类型异常”)

是仅有的通过使用线路控件来修改线路上的音量/级别(使用剪辑界面)的方法?或者是否可以修改 AudioInputStream 的音量?

或者是否有一种方法可以将控件添加到现有线路?

I'm new to using the javax.sound.sampled package, the reason I chose to to use the package was to have more control over the audio I was using than some simpler sound solutions such as AudioClip.

I've read through: Oracle's Sound Tutorial
(or at least as much as I could grasp) but I don't see a method of modulating the level/volume of playback on a Line using the Clip interface they seemed to give these kinds of options in the portions of the package that allow you to create sound, but I can't find any way of making these adjustments be it through my Line, or my AudioInputStream.

I found [this] page with the text,

Float controls, on the other hand, are well suited to represent continuously variable controls, such as pan, balance, or volume.

but no Lines on my computer return any Controls (using Line.getControls())

(I tried to force the line to accept the FloatControl.Type.VOLUME similar to this but I get an "unsupported control type exception")

Is the only way to modify the volume/level on a Line (using the Clip interface) through use of the Line's controls? Or is it possible to modify the volume of an AudioInputStream?

Alternatively is there a method of adding Controls to an existing Line?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

起风了 2024-12-29 22:36:53

使用 FloatControl.Type.MASTER_GAIN 代替 FloatControl.Type.VOLUME。

Instead of using FloatControl.Type.VOLUME use FloatControl.Type.MASTER_GAIN.

浊酒尽余欢 2024-12-29 22:36:53

除了使用线路之外,至少还有另一种方法。 (我在获得控制线时也遇到了麻烦,并发现按照特拉维斯·迈耶斯(Travis Meyers)的建议,主控线有效。我给了他+票。)不确定你是否想去那里,但可以乘以每个帧的音频值均按音量系数计算。 Java 教程对此技术进行了简要引用,但与该文档中的其他内容一样,它们没有提供明确的示例。

因此,当您获取字节缓冲区时,您必须循环遍历该缓冲区,组合字节以获取音频值。然后,乘以音量系数(通常是 0 到 1.0 之间的浮点数),然后将音频值分解回字节。

有用。我用一个简单的 Java Theremin 来实现,你可以尝试一下。我还在该程序中逐帧操纵我的音高。但程序还是有问题!我现在正在努力改进将 GUI 事件数据传输到音频循环的方式。另外,我是在每帧的基础上而不是在每个缓冲区的基础上响应更改。但对于大多数用途来说,每个缓冲区就可以了。

也就是说,需要注意的是发送的音量变化会导致不连续性,从而导致响亮的咔嗒声。引起咔嗒声的量在不同的音量范围内可能会有所不同。此外,当音量系数从 0 变为 1.0 时,音量并不完全以线性方式下降。

There is at least one other way, besides using lines. (I was also having trouble getting a control line, and found that a Master line worked, as recommended by Travis Meyers. I'm giving him a + vote.) Not sure if you want to go there, but it is possible to multiply EVERY frame's audio values by a volume factor. The Java Tutorial makes a passing reference to this technique, but like much else in that document, they don't provide explicit examples.

Thus, when you acquire a buffer of bytes, you have to loop through the buffer, assembling the bytes to get the audio values. Then, multiply by your volume factor (often a float from 0 to 1.0), then dissassemble the audio value back into bytes.

It works. I do it in a crude Java Theremin you can try out. I also manipulate my pitches on a per frame basis in that program. But there are still issues with the program! I'm working right now on improving the way I pipe GUI event data to the audio loop. Also, I'm responding to changes on a per-frame basis rather than via per-buffer basis. But for most uses, per-buffer is fine.

That said, something to listen for is to take care about sending in changes in volume that cause discontinuities, which can cause loud clicks. The amount that causes the click can vary in the different volume ranges. Also, volume doesn't exactly drop off in a linear fashion, as you go from 0 to 1.0 with your volume factor.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文