2016-11-09 93 views
1

有没有什么办法可以在Java中设置Clip的体积?Java Clip的设置体积

我有这样的方法:

  1. 0::没有声音
  2. 40:

    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

    卷的范围内返回一个Integer最优带耳机的声音

  3. 60:最佳音效
  4. 100:声音饱满

所以基本上这应该是一样的VLC规模(但一半因为VLC是从0 to 200)。

我发现我可以用volume.setValue(-10f);

降低剪辑的分贝,但我宁愿型volume.setValue(clip.getMaxVolume() * Settings.getSettings().getVolume()/100)的东西。

其中clip.getMaxVolume()将返回剪辑的最大音量。

回答

1

根据Killer Game Programming由Andrew戴维森可以调整音量这个简单的:

float range = gainControl.getMaximum() - gainControl.getMinimum(); 
float gain = (range * volume) + gainControl.getMinimum(); 
gainControl.setValue(gain); 

volume是在浮动所需的体积(0.0F装置没有声音,1.0F意味着全音频) gainControlFloatControl

希望你能得到它的工作!

+0

'gainControl.getMinimum()'是否必要?我的方法不行吗? (两个版本都有效)。 –

+0

如果两个版本都能正常工作,请使用不带'gainControl.getMinimum()'的版本,因为它的速度要快一些。 – Squiddie

+0

我只用一个文件试过这个,这就是为什么我问,你认为其他文件可能不适用于我的方法? –

1

所以有点试验和错误后,我想出了这个:

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(); 
    } 
} 
0

我相信你居然找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);  
    } 
} 
+0

我曾试过,它表示剪辑不支持音量。 –

5

MASTER_GAINFloatControl值是分贝,这意味着它是一个对数刻度,不是直线的。

虽然分贝是伟大的音频专家,我们的程序员通常需要一个很好的线性度,其中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。