设置 Java 剪辑的音量
Set volume of Java Clip
有什么方法可以设置 Java
中 Clip
的相应音量吗?
我有这个方法:
public static void play(Clip clip) {
if (Settings.getSettings().isVolumeOn()) {
FloatControl volume = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
volume.setValue(-1 * Settings.getSettings().getVolume());
clip.start();
}
}
Settings.getSettings().getVolume()
return是0 - 100
范围内的Integer
Volumes:
- 0 : No Sound
- 40 : Optimal Sound with headphones
- 60 : Optimal Sound
- 100: Full Sound
所以本质上这应该像 VLC
的比例(但是一半因为 VLC 来自 0 to 200
)。
我发现使用 volume.setValue(-10f);
可以降低剪辑的分贝
但我更喜欢 volume.setValue(clip.getMaxVolume() * Settings.getSettings().getVolume()/100)
类型的内容。
其中 clip.getMaxVolume()
将 return 剪辑的最大音量。
根据 Andrew Davison 的 Killer Game Programming,您可以如此简单地调节音量:
float range = gainControl.getMaximum() - gainControl.getMinimum();
float gain = (range * volume) + gainControl.getMinimum();
gainControl.setValue(gain);
volume
是浮动的所需音量(0.0f 表示没有声音,1.0f 表示完整音频)
gainControl
是 FloatControl
希望你能成功!
经过反复试验,我想到了这个:
public static void play(Clip clip) {
if (Settings.getSettings().isVolumeOn()) {
FloatControl control = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
int volume = Settings.getSettings().getVolume();
float range = control.getMinimum();
float result = range * (1 - volume / 100.0f);
control.setValue(result);
clip.start();
}
}
我相信您实际上是在寻找 FloatControl.Type.VOLUME 控件,而不是 MASTER_GAIN。试试这个:
public static void setVolume(Clip clip, int level) {
Objects.requireNonNull(clip);
FloatControl volume = (FloatControl) clip.getControl(FloatControl.Type.VOLUME);
if (volume != null) {
volume.setValue(level / 100.0);
}
}
MASTER_GAIN FloatControl
值以分贝为单位,这意味着它是对数标度,而不是线性标度。
虽然分贝对音频专业人士来说很棒,但我们程序员通常想要一个漂亮的线性刻度,其中 0.0
是静音,0.5
是半音量,1.0
是全音量;我的意思是声音样本的正常音量。在播放音效的时候,我们一般不会对声音片段进行放大,只是对其进行衰减。
Decibel (dB) to Float Value Calculator 解释了将分贝转换为线性刻度背后的数学原理,但这里是代码:
在Fantom中:
using [java] javax.sound.sampled::Clip
using [java] javax.sound.sampled::FloatControl
using [java] javax.sound.sampled::FloatControl$Type as FType
...
private Clip clip
Float volume {
get {
gainControl := (FloatControl) clip.getControl(FType.MASTER_GAIN)
return 10f.pow(gainControl.getValue / 20f)
}
set {
if (it < 0f || it > 1f) throw ArgErr("Invalid volume: $it")
gainControl := (FloatControl) clip.getControl(FType.MASTER_GAIN)
gainControl.setValue(20f * it.log10)
}
}
并转换为Java:
import javax.sound.sampled.Clip;
import javax.sound.sampled.FloatControl;
...
private Clip clip
public float getVolume() {
FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
return (float) Math.pow(10f, gainControl.getValue() / 20f);
}
public void setVolume(float volume) {
if (volume < 0f || volume > 1f)
throw new IllegalArgumentException("Volume not valid: " + volume);
FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
gainControl.setValue(20f * (float) Math.log10(volume));
}
请注意,不需要涉及 clip.getMaxVolume()
或 clip.getMinVolume()
,因为使用上面的代码,1.0
的体积对应于 0 Db
(无变化)和0.1
的音量对应于 -20 Db
(非常非常安静)。
如果您确实想要放大声音剪辑,那么没有什么可以阻止您将 2.0
传递给正常音量的两倍,a-la VLC。
作为一个无耻的插件,看看我用这些知识做了什么 - 参见 Escape the Mainframe - 一个在浏览器和桌面上运行的迷你跳跃游戏Java 申请。写在 Fantom - 玩得开心!
有什么方法可以设置 Java
中 Clip
的相应音量吗?
我有这个方法:
public static void play(Clip clip) {
if (Settings.getSettings().isVolumeOn()) {
FloatControl volume = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
volume.setValue(-1 * Settings.getSettings().getVolume());
clip.start();
}
}
Settings.getSettings().getVolume()
return是0 - 100
Integer
Volumes:
- 0 : No Sound
- 40 : Optimal Sound with headphones
- 60 : Optimal Sound
- 100: Full Sound
所以本质上这应该像 VLC
的比例(但是一半因为 VLC 来自 0 to 200
)。
我发现使用 volume.setValue(-10f);
但我更喜欢 volume.setValue(clip.getMaxVolume() * Settings.getSettings().getVolume()/100)
类型的内容。
其中 clip.getMaxVolume()
将 return 剪辑的最大音量。
根据 Andrew Davison 的 Killer Game Programming,您可以如此简单地调节音量:
float range = gainControl.getMaximum() - gainControl.getMinimum();
float gain = (range * volume) + gainControl.getMinimum();
gainControl.setValue(gain);
volume
是浮动的所需音量(0.0f 表示没有声音,1.0f 表示完整音频)
gainControl
是 FloatControl
希望你能成功!
经过反复试验,我想到了这个:
public static void play(Clip clip) {
if (Settings.getSettings().isVolumeOn()) {
FloatControl control = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
int volume = Settings.getSettings().getVolume();
float range = control.getMinimum();
float result = range * (1 - volume / 100.0f);
control.setValue(result);
clip.start();
}
}
我相信您实际上是在寻找 FloatControl.Type.VOLUME 控件,而不是 MASTER_GAIN。试试这个:
public static void setVolume(Clip clip, int level) {
Objects.requireNonNull(clip);
FloatControl volume = (FloatControl) clip.getControl(FloatControl.Type.VOLUME);
if (volume != null) {
volume.setValue(level / 100.0);
}
}
MASTER_GAIN FloatControl
值以分贝为单位,这意味着它是对数标度,而不是线性标度。
虽然分贝对音频专业人士来说很棒,但我们程序员通常想要一个漂亮的线性刻度,其中 0.0
是静音,0.5
是半音量,1.0
是全音量;我的意思是声音样本的正常音量。在播放音效的时候,我们一般不会对声音片段进行放大,只是对其进行衰减。
Decibel (dB) to Float Value Calculator 解释了将分贝转换为线性刻度背后的数学原理,但这里是代码:
在Fantom中:
using [java] javax.sound.sampled::Clip
using [java] javax.sound.sampled::FloatControl
using [java] javax.sound.sampled::FloatControl$Type as FType
...
private Clip clip
Float volume {
get {
gainControl := (FloatControl) clip.getControl(FType.MASTER_GAIN)
return 10f.pow(gainControl.getValue / 20f)
}
set {
if (it < 0f || it > 1f) throw ArgErr("Invalid volume: $it")
gainControl := (FloatControl) clip.getControl(FType.MASTER_GAIN)
gainControl.setValue(20f * it.log10)
}
}
并转换为Java:
import javax.sound.sampled.Clip;
import javax.sound.sampled.FloatControl;
...
private Clip clip
public float getVolume() {
FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
return (float) Math.pow(10f, gainControl.getValue() / 20f);
}
public void setVolume(float volume) {
if (volume < 0f || volume > 1f)
throw new IllegalArgumentException("Volume not valid: " + volume);
FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
gainControl.setValue(20f * (float) Math.log10(volume));
}
请注意,不需要涉及 clip.getMaxVolume()
或 clip.getMinVolume()
,因为使用上面的代码,1.0
的体积对应于 0 Db
(无变化)和0.1
的音量对应于 -20 Db
(非常非常安静)。
如果您确实想要放大声音剪辑,那么没有什么可以阻止您将 2.0
传递给正常音量的两倍,a-la VLC。
作为一个无耻的插件,看看我用这些知识做了什么 - 参见 Escape the Mainframe - 一个在浏览器和桌面上运行的迷你跳跃游戏Java 申请。写在 Fantom - 玩得开心!