下面列出了怎么用javax.sound.sampled.FloatControl的API类实例代码及写法,或者点击链接到github查看源代码。
private void play(String wavPath, float db) {
if (!dnd && db > -40) {
ClassLoader classLoader = getClass().getClassLoader();
try (AudioInputStream stream = AudioSystem.getAudioInputStream(classLoader.getResource(wavPath))) {
Clip clip = AudioSystem.getClip();
clip.open(stream);
if (db != 0.0) {
FloatControl gainControl =
(FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
gainControl.setValue(db);
}
clip.start();
} catch (Exception e) {
logger.error("Cannot start playing wav file: ", e);
}
}
}
@Override
public void setVolume(final PercentType volume) throws IOException {
if (volume.intValue() < 0 || volume.intValue() > 100) {
throw new IllegalArgumentException("Volume value must be in the range [0,100]!");
}
if (!isMac) {
runVolumeCommand(new Closure() {
@Override
public void execute(Object input) {
FloatControl volumeControl = (FloatControl) input;
volumeControl.setValue(volume.floatValue() / 100f);
}
});
} else {
Runtime.getRuntime()
.exec(new String[] { "osascript", "-e", "set volume output volume " + volume.intValue() });
macVolumeValue = volume;
}
}
/**
* Sets Gain value. Line should be opened before calling this method. Linear scale 0.0 <--> 1.0 Threshold Coef. : 1/2 to avoid saturation.
*
* @param fGain
*/
public void setGain(float fGain) {
// if (line != null)
// System.out.println(((FloatControl)
// line.getControl(FloatControl.Type.MASTER_GAIN)).getValue())
// Set the value
gain = fGain;
// Better type
if (line != null && line.isControlSupported(FloatControl.Type.MASTER_GAIN))
( (FloatControl) line.getControl(FloatControl.Type.MASTER_GAIN) ).setValue((float) ( 20 * Math.log10(fGain <= 0.0 ? 0.0000 : fGain) ));
// OR (Math.log(fGain == 0.0 ? 0.0000 : fGain) / Math.log(10.0))
// if (line != null)
// System.out.println(((FloatControl)
// line.getControl(FloatControl.Type.MASTER_GAIN)).getValue())
}
public static FloatControl getControl(AudioInputStream in) {
try {
AudioFormat baseFormat = in.getFormat();
AudioFormat decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
baseFormat.getSampleRate(),
16,
baseFormat.getChannels(),
baseFormat.getChannels() * 2,
baseFormat.getSampleRate(),
false);
AudioInputStream ain = AudioSystem.getAudioInputStream(decodedFormat, in);
DataLine.Info info = new DataLine.Info(Clip.class, decodedFormat);
try ( Clip clip = (Clip) AudioSystem.getLine(info)) {
clip.open(ain);
FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
return gainControl;
}
} catch (Exception e) {
logger.debug(e.toString());
return null;
}
}
public void setGain(float ctrl) {
try {
Mixer.Info[] infos = AudioSystem.getMixerInfo();
for (Mixer.Info info : infos) {
Mixer mixer = AudioSystem.getMixer(info);
if (mixer.isLineSupported(Port.Info.SPEAKER)) {
try ( Port port = (Port) mixer.getLine(Port.Info.SPEAKER)) {
port.open();
if (port.isControlSupported(FloatControl.Type.VOLUME)) {
FloatControl volume = (FloatControl) port.getControl(FloatControl.Type.VOLUME);
volume.setValue(ctrl);
}
}
}
}
} catch (Exception e) {
}
}
public static void playClip(final File file) {
Task miaoTask = new Task<Void>() {
@Override
protected Void call() {
try {
FloatControl control = SoundTools.getControl(file);
Clip player = SoundTools.playback(file, control.getMaximum() * 0.6f);
player.start();
} catch (Exception e) {
}
return null;
}
};
Thread thread = new Thread(miaoTask);
thread.setDaemon(true);
thread.start();
}
private void runVolumeCommand(Closure closure) {
Mixer.Info[] infos = AudioSystem.getMixerInfo();
for (Mixer.Info info : infos) {
Mixer mixer = AudioSystem.getMixer(info);
if (mixer.isLineSupported(Port.Info.SPEAKER)) {
Port port;
try {
port = (Port) mixer.getLine(Port.Info.SPEAKER);
port.open();
if (port.isControlSupported(FloatControl.Type.VOLUME)) {
FloatControl volume = (FloatControl) port.getControl(FloatControl.Type.VOLUME);
closure.execute(volume);
}
port.close();
} catch (LineUnavailableException e) {
logger.error("Cannot access master volume control", e);
}
}
}
}
/**
* Plays the clip with the specified volume.
* @param volume the volume the play at
* @param listener the line listener
* @throws LineUnavailableException if a clip object is not available or
* if the line cannot be opened due to resource restrictions
*/
public void start(float volume, LineListener listener) throws LineUnavailableException {
Clip clip = getClip();
if (clip == null)
return;
// PulseAudio does not support Master Gain
if (clip.isControlSupported(FloatControl.Type.MASTER_GAIN)) {
// set volume
FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
float dB = (float) (Math.log(volume) / Math.log(10.0) * 20.0);
gainControl.setValue(Utils.clamp(dB, gainControl.getMinimum(), gainControl.getMaximum()));
} else if (clip.isControlSupported(FloatControl.Type.VOLUME)) {
// The docs don't mention what unit "volume" is supposed to be,
// but for PulseAudio it seems to be amplitude
FloatControl volumeControl = (FloatControl) clip.getControl(FloatControl.Type.VOLUME);
float amplitude = (float) Math.sqrt(volume) * volumeControl.getMaximum();
volumeControl.setValue(Utils.clamp(amplitude, volumeControl.getMinimum(), volumeControl.getMaximum()));
}
if (listener != null)
clip.addLineListener(listener);
clip.setFramePosition(0);
clip.start();
}
/**
* Sets Gain value. Line should be opened before calling this method. Linear
* scale 0.0 <--> 1.0 Threshold Coef. : 1/2 to avoid saturation.
*
* @param fGain
*/
public void setGain(float fGain) {
// if (line != null)
// System.out.println(((FloatControl)
// line.getControl(FloatControl.Type.MASTER_GAIN)).getValue())
// Set the value
gain = fGain;
// Better type
if (line != null && line.isControlSupported(FloatControl.Type.MASTER_GAIN))
((FloatControl) line.getControl(FloatControl.Type.MASTER_GAIN))
.setValue((float) (20 * Math.log10(fGain <= 0.0 ? 0.0000 : fGain)));
// OR (Math.log(fGain == 0.0 ? 0.0000 : fGain) / Math.log(10.0))
// if (line != null)
// System.out.println(((FloatControl)
// line.getControl(FloatControl.Type.MASTER_GAIN)).getValue())
}
/**
* Sets Gain value. Line should be opened before calling this method. Linear
* scale 0.0 <--> 1.0 Threshold Coef. : 1/2 to avoid saturation.
*
* @param fGain
*/
public void setGain(float fGain) {
// if (line != null)
// System.out.println(((FloatControl)
// line.getControl(FloatControl.Type.MASTER_GAIN)).getValue())
// Set the value
gain = fGain;
// Better type
if (line != null && line.isControlSupported(FloatControl.Type.MASTER_GAIN))
((FloatControl) line.getControl(FloatControl.Type.MASTER_GAIN))
.setValue((float) (20 * Math.log10(fGain <= 0.0 ? 0.0000 : fGain)));
// OR (Math.log(fGain == 0.0 ? 0.0000 : fGain) / Math.log(10.0))
// if (line != null)
// System.out.println(((FloatControl)
// line.getControl(FloatControl.Type.MASTER_GAIN)).getValue())
}
/**
* Mute the Clip (because destroying it, won't stop it)
*/
public void mute() {
try {
Clip c = getClip();
if (c == null) {
return;
}
float val = (float) (Math.log(Float.MIN_VALUE) / Math.log(10.0) * 20.0);
if (val < -80.0f) {
val = -80.0f;
}
((FloatControl) c.getControl(FloatControl.Type.MASTER_GAIN)).setValue(val);
} catch (IllegalArgumentException ignored) {
} catch (LineUnavailableException e) {
e.printStackTrace();
}
}
@Subscribe
private void onConfigChanged(ConfigChanged event)
{
if (!event.getGroup().equals("metronome"))
{
return;
}
if (event.getKey().equals("volume"))
{
float gainValue = (((float) config.volume()) * 40f / 100f) - 35f;
FloatControl gainControlTick = (FloatControl) tickClip.getControl(FloatControl.Type.MASTER_GAIN);
gainControlTick.setValue(gainValue);
FloatControl gainControlTock = (FloatControl) tockClip.getControl(FloatControl.Type.MASTER_GAIN);
gainControlTock.setValue(gainValue);
}
if (event.getKey().equals("tickSoundFilePath"))
{
if (tickClip != null)
{
tickClip.close();
}
tickClip = GetAudioClip(config.tickPath());
}
if (event.getKey().equals("tockSoundFilePath"))
{
if (tockClip != null)
{
tockClip.close();
}
tockClip = GetAudioClip(config.tockPath());
}
}
public AudioPlayer(InputStream in, Listener listener) throws Exception {
this.in = in;
this.listener = listener;
AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100.0F, 16, 2, 4, 44100.0F, true);
line = AudioSystem.getSourceDataLine(format);
line.open(format);
LOG.debug("Opened line " + line);
if (line.isControlSupported(FloatControl.Type.MASTER_GAIN)) {
gainControl = (FloatControl) line.getControl(FloatControl.Type.MASTER_GAIN);
setGain(DEFAULT_GAIN);
}
new AudioDataWriter();
}
public AudioPlayer(InputStream in, Listener listener) throws Exception {
this.in = in;
this.listener = listener;
AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100.0F, 16, 2, 4, 44100.0F, true);
line = AudioSystem.getSourceDataLine(format);
line.open(format);
LOG.debug("Opened line " + line);
if (line.isControlSupported(FloatControl.Type.MASTER_GAIN)) {
gainControl = (FloatControl) line.getControl(FloatControl.Type.MASTER_GAIN);
setGain(DEFAULT_GAIN);
}
new AudioDataWriter();
}
public void setPanning(int chan,int sep){
Clip c=channels[chan];
if (c.isControlSupported(Type.PAN)){
FloatControl bc=(FloatControl) c.getControl(Type.PAN);
// Q: how does Doom's sep map to stereo panning?
// A: Apparently it's 0-255 L-R.
float pan= bc.getMinimum()+(bc.getMaximum()-bc.getMinimum())*(float)sep/ISoundDriver.PANNING_STEPS;
bc.setValue(pan);
}
}
/**
* Sets the volume of the clip, 1f is the normal volume, 0f is completely quiet and 2f is twice as loud.
*
* @param volume the new volume of this audio
*/
public void setVolume(float volume) {
volume = GeneralUtil.clamp(volume, 0f, 2f);
final FloatControl gainControl = (FloatControl) getClip().getControl(FloatControl.Type.MASTER_GAIN);
gainControl.setValue(20f * (float) Math.log10(volume));
this.volume = volume;
}
public void setLineGain(float gain) {
if (source != null) {
if (source.isControlSupported(FloatControl.Type.MASTER_GAIN)) {
FloatControl volControl = (FloatControl) source.getControl(FloatControl.Type.MASTER_GAIN);
float newGain = Math.min(Math.max(gain, volControl.getMinimum()), volControl.getMaximum());
volControl.setValue(newGain);
}
}
}
public static FloatControl getControl(File file) {
try {
try ( AudioInputStream in = AudioSystem.getAudioInputStream(file)) {
return getControl(in);
}
} catch (Exception e) {
logger.debug(e.toString());
return null;
}
}
public static FloatControl getControl(URL url) {
try {
try ( AudioInputStream in = AudioSystem.getAudioInputStream(url)) {
return getControl(in);
}
} catch (Exception e) {
logger.debug(e.toString());
return null;
}
}
@Override
public float getMasterGain() {
final FloatControl gainControl = this.gainControl.get();
if (gainControl == null || !this.working) {
return -1.0f;
} else {
return gainControl.getValue();
}
}
@Override
public void setMasterGain(final float valueInDb) {
final FloatControl gainControl = this.gainControl.get();
if (gainControl != null && this.working) {
gainControl.setValue(
Math.max(gainControl.getMinimum(), Math.min(gainControl.getMaximum(), valueInDb)));
}
}
/**
* Sets the volume.
*
* @param vol the volume
*/
private void setVolume(final int vol) {
int volume = vol;
if (volume < 0) {
volume = MAX_VOLUME;
}
float gainDb = 0.0f;
final FloatControl gain = (FloatControl)
clip.getControl(FloatControl.Type.MASTER_GAIN);
if (volume == 0) {
gainDb = gain.getMinimum();
} else if (volume < MAX_VOLUME) {
// The volume algorithm is subtractive: The implementation assumes that
// the sound is already at maximum volume, so we avoid distortion by
// making the amplitude values
// The scaling factor for the volume would be 20 normally, but
// it seems that 13 is better
gainDb = (float) (Math.log10(MAX_VOLUME - volume) * 13.0);
}
gain.setValue(-gainDb);
}
/**
* Attempt to set the global gain (volume ish) for the play back. If the
* control is not supported this method has no effect. 1.0 will set maximum
* gain, 0.0 minimum gain
*
* @param gain The gain value
*/
private void setGain(float gain) {
if (gain != -1) {
if ((gain < 0) || (gain > 1)) {
throw new IllegalArgumentException("Volume must be between 0.0 and 1.0");
}
}
this.gain = gain;
if (outputLine == null) {
return;
}
try {
FloatControl control = (FloatControl) outputLine.getControl(FloatControl.Type.MASTER_GAIN);
if (gain == -1) {
control.setValue(0);
} else {
float max = control.getMaximum();
float min = control.getMinimum(); // negative values all seem to be zero?
float range = max - min;
control.setValue(min + (range * gain));
}
} catch (IllegalArgumentException e) {
// gain not supported
e.printStackTrace();
}
}
private Gain() {
super(FloatControl.Type.MASTER_GAIN,
Toolkit.linearToDB(0.0f),
Toolkit.linearToDB(2.0f),
Math.abs(Toolkit.linearToDB(1.0f)-Toolkit.linearToDB(0.0f))/128.0f,
-1,
0.0f,
"dB", "Minimum", "", "Maximum");
}
/**
* Set the volume
* @param vol New configuration volume (1.0The default )
*/
public void setVolume(double vol) {
volume = vol;
Set<String> set = clipMap.keySet();
for(String name: set) {
try {
Clip clip = clipMap.get(name);
FloatControl ctrl = (FloatControl)clip.getControl(FloatControl.Type.MASTER_GAIN);
ctrl.setValue((float)Math.log10(volume) * 20);
} catch (Exception e) {}
}
}
private void rawplay(AudioFormat trgFormat, AudioInputStream ain, float volume)
throws IOException, LineUnavailableException {
byte[] data = new byte[8192];
try {
clip = getLine(ain, trgFormat);
if (clip == null) {
return;
}
Control.Type vol1 = FloatControl.Type.VOLUME, vol2 = FloatControl.Type.MASTER_GAIN;
FloatControl c = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
float min = c.getMinimum();
float v = volume * (c.getMaximum() - min) / 100f + min;
if (this.clip.isControlSupported(vol1)) {
FloatControl volumeControl = (FloatControl) this.clip.getControl(vol1);
volumeControl.setValue(v);
} else if (this.clip.isControlSupported(vol2)) {
FloatControl gainControl = (FloatControl) this.clip.getControl(vol2);
gainControl.setValue(v);
}
clip.start();
int nBytesRead = 0;
while (isRunning && (nBytesRead != -1)) {
nBytesRead = ain.read(data, 0, data.length);
if (nBytesRead != -1) {
clip.write(data, 0, nBytesRead);
}
}
} finally {
clip.drain();
clip.stop();
clip.close();
ain.close();
}
}
public void updateVolume(int percent) {
if (out != null && out.isOpen()) {
try {
FloatControl c = (FloatControl) out.getControl(FloatControl.Type.MASTER_GAIN);
float min = c.getMinimum();
float v = percent * (c.getMaximum() - min) / 100f + min;
c.setValue(v);
} catch (IllegalArgumentException e) {
}
}
volume = percent;
}
public ControlNode(Control control) {
super(control.getType(), true);
this.control = control;
if (control instanceof BooleanControl) {
component = createControlComponent((BooleanControl) control);
} else if (control instanceof EnumControl) {
component = createControlComponent((EnumControl) control);
} else if (control instanceof FloatControl) {
component = createControlComponent((FloatControl) control);
} else {
component = null;
}
}
private Pan() {
super(FloatControl.Type.PAN, -1.0f, 1.0f, (1.0f / 128.0f), -1,
0.0f, "", "Left", "Center", "Right");
}
private ReverbSend() {
super(FloatControl.Type.REVERB_SEND, -80f, 6.0206f, 80f / 128.0f,
-1, -80f, "dB", "Minimum", "", "Maximum");
}