设置Java Clip的音量

nic*_*oum 1 java audio volume clip

有没有办法设置一个Clipin 的相应音量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();
    }
}
Run Code Online (Sandbox Code Playgroud)

所述Settings.getSettings().getVolume()返回一个Integer在范围内0 - 100

卷:

  1. 0:没有声音
  2. 40:带耳机的最佳音效
  3. 60:最佳声音
  4. 100:完整的声音

所以基本上这应该是规模VLC(但是VLC来自的一半0 to 200).

我发现我可以通过使用减少剪辑的分贝 volume.setValue(-10f);

但我更喜欢这种类型的东西volume.setValue(clip.getMaxVolume() * Settings.getSettings().getVolume()/100).

哪里clip.getMaxVolume()会返回剪辑的最大音量.

Ste*_*non 6

所述MASTER_GAIN FloatControl值以分贝为单位,这意味着它是一个对数标度,不是直线的.

虽然分贝对于音频专业人士来说非常棒,但我们程序员通常需要一个很好的线性音阶,其中0.0是静音,0.5音量为一半,音量1.0是全音量.我的意思是声音样本的正常音量.在播放声音效果时,我们通常不会放大声音片段,只是将它们衰减.

分贝(dB)到浮点值计算器解释了将分贝转换为线性标度的数学,但这里是代码:

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

并转换为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));
}
Run Code Online (Sandbox Code Playgroud)

注意,不需要涉及clip.getMaxVolume()clip.getMinVolume()因为体积1.0对应于0 Db(无变化)且体积0.1对应于-20 Db(非常非常安静).

如果你确实想要放大声音片段,那么没有什么可以阻止你传入2.0以使正常音量加倍,即a-la VLC.


小智 4

根据Andrew Davison 的《杀手游戏编程》,您可以如此简单地调整音量:

float range = gainControl.getMaximum() - gainControl.getMinimum();
float gain = (range * volume) + gainControl.getMinimum();
gainControl.setValue(gain);
Run Code Online (Sandbox Code Playgroud)

volume所需的浮点音量(0.0f 表示无声音,1.0f 表示完整音频) gainControlFloatControl

希望你能让它发挥作用!