设置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));
    }