2016-11-09 2 views
1

Есть ли способ установить соответствующий объем Clip в Java?Установите громкость Java Clip

У меня есть этот метод:

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() возвращает Integer в диапазоне 0 - 100

Объемы:

  1. 0: Нет звука
  2. 40: Optimal Звук с наушниками
  3. 60: Оптимальный звук
  4. 100: Full Sound

Так, по существу, это должно быть, как в масштабе VLC (но наполовину с КПД от 0 to 200).

Я обнаружил, что я могу уменьшить децибел клипа с помощью volume.setValue(-10f);

Но я предпочел бы что-то типа volume.setValue(clip.getMaxVolume() * Settings.getSettings().getVolume()/100).

Где clip.getMaxVolume() вернет максимальный объем клипа.

ответ

1

Согласно Killer Game Programming Эндрю Дэвисон вы можете регулировать громкость этого простой:

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

volume будучи требуемый объем в обращении (0.0f означает, что ни звука, 1.0f означает полный аудио) gainControl является FloatControl

Надеюсь, вы сможете заставить его работать!

+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_GAIN Значение FloatControl в децибелах, а это означает, что это логарифмическая шкала, а не линейным.

Хотя децибел отлично подходит для аудио профессионалов, нас программисты обычно хотят хорошую линейную шкалу, где 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.

Смежные вопросы