# Lautstärke kontrollieren per Master gain



## Eule (30. Jan 2013)

Hallo Forum

ich stehe vor dem Problem, dass ich die Systemlautstärke überwachen muss. Das Programm an sich habe ich unter Windows XP geschrieben und dort funktioniert es auch ohne Probleme. Wenn die Systemlautstärke unter einen bestimmten Wert rutscht, dann korregiere ich sie automatisch auf 80% des Maximalwertes, so dass der Benutzer es nicht leise stellen kann. Das gleiche Problem habe ich mit Mute, was unter XP auch funktioniert.

Nun habe ich mein Programm unter Windows 7 probiert und musste festellen, dass ich nur noch den Lautstärkeregler für mein Programm kontrollieren kann. Stellt jetzt jedoch der Benutzer die Systemlautstärke runter, kommt nichts mehr aus den Lautstärker, weil die Lautstärke meines Programmes nur noch 80% relativ zur Systemlautstärke ist. Ist die auf 10% Lautstärke eingestellt, habe ich also noch 8% Ausgabelautstärke.

Meine Frage lautet dem nach: ist es möglich dem Hauptregler zu kontrollieren?

Hier noch mal mein Code:


```
public class CheckWinSoundLevel7 extends Thread
{
	private boolean kill = false;
	private MainWindow mainWin = null;
	private Port port;
	private boolean openPortNeeded;
	
	public CheckWinSoundLevel7(MainWindow mainWin) {
		this.mainWin = mainWin;

		try {
			Mixer.Info[] mixers = AudioSystem.getMixerInfo();
			
			for (Mixer.Info info : mixers) {
				Mixer mixer = AudioSystem.getMixer(info);
				if (mixer.isLineSupported(Port.Info.SPEAKER)) {
					

					port = (Port) mixer.getLine(Port.Info.SPEAKER);

					openPortNeeded = !port.isOpen();

					if (openPortNeeded) {
						port.open();
					}
					
					break;
				}
			}
		} catch (LineUnavailableException e) {
			e.printStackTrace();
		}
		
	}
	
	public void run()
	{
		while(!kill)
		{
			
			if (port.isControlSupported(FloatControl.Type.VOLUME))
			{
				FloatControl volumeControl = (FloatControl) port.getControl(FloatControl.Type.VOLUME);
				float min = volumeControl.getMinimum();
				float max = volumeControl.getMaximum();
				float current = volumeControl.getValue();
				double percent = 100.0 * (current - min) / (max - min);

				if(DATA.DEBUG)
				{
					System.out.println("Volume: max="+max+"   min="+min);
				}
				
				// Wenn die Lautstärke kleiner als 20% ist, dann auf 80% setzen
				// 1.25f = 1/0,80%
				if(mainWin.getProject().isAutoCorrectVolume() && percent < mainWin.getProject().getMinAllowedVolume()) {
					volumeControl.setValue((max - min) / (100/(float)mainWin.getProject().getMinAllowedVolume()) + min);
				}
			
			}
			
			//hier das Mute weg nehmen
			if(mainWin.getProject().isAutoUnMuteVolume() && port.isControlSupported(BooleanControl.Type.MUTE))
			{
				BooleanControl muteControl = (BooleanControl) port.getControl(BooleanControl.Type.MUTE);
				muteControl.setValue(false);
			}
			
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				if(DATA.DEBUG)
					e.printStackTrace();
			}
		}
		
		if (openPortNeeded && port.isOpen()) {
			port.close();
		}
	}
	
	/**
	 * Set a variable to run this thread into death
	 */
	public void killThread()
	{
		kill = true;
	}

}
```

Danke schon einmal für die hilfreichen Antworten.


----------



## Spacerat (30. Jan 2013)

Ich lese die Frage und weis sofort um was es geht ohne auch nur geringfügig einen Blick in deinen Quelltext geworfen zu haben... erstaunlich nicht wahr?
Was mich kaum erstaunt, ist dass viele Entwickler rein intuitiv programmieren und selbst im Fehlerfall der API-Doku keinen Blick würdigen (das müsste doch eigentlich funktionieren). Keine Sorge, geht mir genauso.
Im Falle der Lautstärkereglung bedeutet "intuitiv" die Verwendung von Angaben in Prozent (linear), statt in Dezibell (logarithmisch), wie es in der API steht. Viel Spass beim Umrechnen. 

```
private float linearToDB(float f)
	{
		float f1 = (float) ((Math.log((f != 0.0) ? f : 1.0E-14) / Math.log(10.0)) * 20.0);
		return f1;
	}

	private float dBToLinear(float f)
	{
		float f1 = (float) Math.pow(10.0, f / 20.0);
		return f1;
	}
```
Aber gut... evtl. hätte ich mit die Frage vorher doch mal durchlesen sollen, so ist das halt mit der Intuition. 
Evtl. suchst du ja nur "FloatControl.Type.MASTER_GAIN". Den Tip mit der logarithmischen Teilung der Skala würde ich aber dennoch ausprobieren.


----------



## Eule (30. Jan 2013)

jaja so ist das mit der Intuition, hätte mir genauso passieren können. Danke für das stehen lassen dieser kleinen Erheiterung. Der Quelltext von mir wird eh noch wesentlich vereinfacht, weil viele Funktionen zur Laufzeit nicht gebraucht werden. Mit dem DB und log ist mir auch klar, nur musste es damals schnell gehen.

Den Tipp mit dem "FloatControl.Type.MASTER_GAIN" habe ich bereits gefunden gehabt nur leider vergessen zu erwähnen, entschuldigung. Diesen Regler gibt es zwar, jedoch lässt sich dieser anscheinend unter Windows7 nicht mehr ansprechen. 

Dazu kann man diese, gut gemachte Klasse, ausprobieren:
https://github.com/Kunagi/ilarkesto/blob/master/src/main/java/ilarkesto/media/Audio.java

Auf meinem System findet er keinen Master_gain, wirft also die Exception.


----------

