设置Java剪辑的音量
有没有办法在设置Java剪辑的音量,java,audio,volume,clip,Java,Audio,Volume,Clip,有没有办法在Java中设置剪辑的相应音量 我有这个方法: public static void play(Clip clip) { if (Settings.getSettings().isVolumeOn()) { FloatControl volume = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN); volume.setValue(-1 * Settings.getSet
Java
中设置剪辑的相应音量
我有这个方法:
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()
返回一个整数,范围为0-100
卷数:
0:没有声音
40:耳机的最佳声音
60:最佳声音
100:全音效
因此,本质上这应该类似于VLC
(但一半是因为VLC从0到200)
我发现使用volume.setValue(-10f)可以降低剪辑的分贝代码>
但是我更喜欢volume.setValue(clip.getMaxVolume()*Settings.getSettings().getVolume()/100)
其中clip.getMaxVolume()
将返回剪辑的最大音量。根据Andrew Davidson的说法,您可以通过以下简单方式调整音量:
float range = gainControl.getMaximum() - gainControl.getMinimum();
float gain = (range * volume) + gainControl.getMinimum();
gainControl.setValue(gain);
音量
为所需的浮动音量(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_增益。试试这个:
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);
}
}
FloatControl
值以分贝为单位,这意味着它是对数刻度,而不是线性刻度
虽然分贝对于音频专业人士来说非常好,但美国程序员通常想要一个好的线性刻度,其中0.0
是静音,0.5
是半音量,1.0
是全音量;我指的是声音样本的正常音量。在播放音效时,我们通常不会放大声音片段,而是衰减它们
解释了将分贝转换为线性刻度背后的数学原理,但代码如下:
在:
使用[java]javax.sound.sampled::Clip
使用[java]javax.sound.sampled::FloatControl
使用[java]javax.sound.sampled::FloatControl$Type作为FType
...
私人剪辑
浮动容积{
得到{
增益控制:=(FloatControl)clip.getControl(FType.MASTER\u增益)
返回10f.pow(增益控制值/20f)
}
设置{
如果(it<0f | | it>1f)抛出ArgErr(“无效卷:$it”)
增益控制:=(FloatControl)clip.getControl(FType.MASTER\u增益)
增益控制设置值(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));
}
import javax.sound.sampled.Clip;
导入javax.sound.sampled.FloatControl;
...
私人剪辑
公共卷{
FloatControl增益控制=(FloatControl)clip.getControl(FloatControl.Type.MASTER\u增益);
return(float)Math.pow(10f,gainControl.getValue()/20f);
}
公共void设置卷(浮动卷){
如果(容积<0f | |容积>1f)
抛出新的IllegalArgumentException(“卷无效:+Volume”);
FloatControl增益控制=(FloatControl)clip.getControl(FloatControl.Type.MASTER\u增益);
增益控制设定值(20f*(浮点)数学日志10(体积));
}
注:无需涉及clip.getMaxVolume()
或clip.getMinVolume()
,因为使用上述代码,1.0
的音量对应0 Db
(无变化),而0.1
的音量对应-20 Db
(非常安静)
如果您确实想放大声音片段,那么没有什么可以阻止您通过2.0
将正常音量a-la VLC翻倍
作为一个无耻的插件,看看我用这些知识做了什么-看-一个迷你跳跃游戏,在浏览器中运行,作为桌面Java应用程序。写在-有乐趣 是否需要gainControl.getMinimum()
?我的方法不管用吗?(两个版本都有效)。我只尝试了一个文件,这就是为什么我要问,你认为其他文件可能不适合我的方法吗?好的,我接受你的答案,如果你发现你的答案应该更新,请这样做。也许你想回顾史蒂夫的答案;正如他所说,分贝不是线性的,因此你的转换可能不是用户所期望的,比如将音量设置为0.5就不会是剪辑音量的一半。
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));
}