javax.sound.sampled.* - Hilfe zu den Controls

I.Haffner

Mitglied
Hallo,
Ich bin seit einigen Stunden dabei mich in das Audio Processing mit Java einzuarbeiten.
Mein Ziel ist es, einen
Code:
Control
für den
Code:
Mixer
meiner Creative-Soundkarte und dessen
Code:
Line
für die Lautsprecher einzurichten, sodass ich entwerder mit einem
Code:
FloatControl
die Lautstärke variieren oder mit einem
Code:
BooleanContol
die Lautsprecher muten kann.

Dazu habe ich mir drei Funktionen geschrieben:

1) Ein Array aller Mixer erzeugen
Java:
public static Mixer[] getMixers(){
		LinkedList<Mixer> mixerlist = new LinkedList<>();
		Mixer.Info[] infos = AudioSystem.getMixerInfo();
		for(Mixer.Info info : infos)
			mixerlist.add(AudioSystem.getMixer(info));
		return mixerlist.toArray(new Mixer[0]);
	}

2) Ein Array aller Lines eines speziellen Mixers
Java:
public static Line[] getLines(Mixer mixer){
		LinkedList<Line> linelist = new LinkedList<>();
		Line.Info[] linesininfo = mixer.getSourceLineInfo();
		Line.Info[] linesoutinfo = mixer.getTargetLineInfo();
		Line.Info[] linesinfo = new Line.Info[linesininfo.length+linesoutinfo.length];
		System.arraycopy(linesininfo, 0, linesinfo, 0, linesininfo.length);
		System.arraycopy(linesoutinfo, 0, linesinfo, linesininfo.length, linesoutinfo.length);
		for(Line.Info info : linesinfo){
			try {
				linelist.add(mixer.getLine(info));
			} catch (LineUnavailableException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return linelist.toArray(new Line[0]);
	}
Ich vermute es ist überflüssig
Code:
mixer.getSourceLineInfo()
überhaupt zu betrachen wenn man die Lautstärke der Lautsprecher manipulieren will, aber so hab ich wirklich ALLE Lines eines Mixers.

3) Ein Array aller Controls einer Line
Java:
public static Control[] getControls(Line line){
		try{
			line.open();
			return line.getControls();
		}
		catch(LineUnavailableException ex){
			return null;			
		}
	}

Das bisherige war mehr zum Filtern meiner Daten gedacht. Nun zur eigentlichen Funktion.
Ich möchte zu einem speziellen Mixer und einem speziellen Line eine bestimmte Control (sofern unterstützt) erhalten.
Java:
public static Control getControl(Mixer mixer, Line.Info lineinfo, Control.Type controltype){
		if(mixer.isLineSupported(lineinfo)){
			try{
				mixer.open();
				Port port = (Port) mixer.getLine(lineinfo);
				try{
					port.open();
					Control[] controls = port.getControls();
					for(Control control : controls){
						if(control.getType().equals(controltype)){
							System.out.println(port.getLineInfo());
							return control;
						}
					}
				}
				catch(LineUnavailableException ex){
					
				}
			}
			catch(LineUnavailableException ex){
				
			}
		}
	return null;
	}

Das funktioniert soweit auch ganz prima. Z.B. erhalte ich zu dem Mixer meiener Creative-Soundkarte und dem Line für die SPEAKER ein VolumeControl / MuteControl. Dieses ist auch kein Nullpointer!
Allerdings scheinen alle Änderungen mit Hilfe der Control keinen Effekt zu haben.

Vielen vielen Dank schonmal im Voraus.
Die Lösung interessiert mich wirklich brennend : )

PS: Ich nutze einmal meine Creative-Soundkarte und dann hat mein USB-Headset noch seine Treiber (also auch eigene Mixer/Lines).
 
Danke dafür. Aber das Tutorial hatte ich schon mehrmals gelesen : )
Und auch das Thema im Forum wurde ja nicht richtig gelöst... leider geht es so nicht.
 
Da du ja die Antwort in dem Thema gegeben hast kannst du es vllt auch nochmal etwas genauer hier erklären : )
Ich habe zB einen FloatControl vom TYPE VOLUME für meinen SPEAKER. Ich kann mir Anzeigen lassen dass die Range 0.0 -1.0 ist. getValue() liefert zB 0.0. aber das würde doch bedeuten dass ich keinen ton habe? wenn ich setValue durchführe ändern auch den wert, allerdings merke ich keine änderung der lautstärke.

Habe auch schon BooleanControl vom TYPE MUTE getestet, aber das scheint auch nicht zu funktionieren.

Ich hab auch zu dem Thema iwo gelesen dass sich die Controls der Lines garnicht instanzieren lassen (aber das kann ja nicht sein).

Auf jeden Fall hab ich jetzt schon viel methoden probiert und nix geht. Ich hoffe wirklich dass ich es irgendwann noch schaffe : )
 
Ich hab mal die
Code:
Lines
gefiltert, die vom
Code:
TYPE
Code:
SPEAKER
sind und den
Code:
Control
Code:
FloatControl.TYPE.VOLUME
oder
Code:
BooleanControl.TYPE.MUTE
unterstützen und mir die Informationen gedruck.

Hier das Ergebnis
Code:
Port Lautsprecher (Creative SB X-Fi), version 6.1
SPEAKER target port
Minimum 0.0	Maximum 1.0
Precision 1.5258789E-5	Units 	UpdatePeriod 1000

Port Lautsprecher (C-Media USB Headp, version 1.0
SPEAKER target port
Minimum 0.0	Maximum 1.0
Precision 1.5258789E-5	Units 	UpdatePeriod 1000
 
Ports... hmmm... Dabei handelt es sich afaik direkt um die Hardware-Ports des Betriebssystems - hier anscheinend Windows 7. Ein direkter Hardwarezugriff wird aber anscheinend höchst selten unterstützt. Bei den Lines aber, welche für diesen Mixer zur Verfügung stehen, sollte es gehen. Für die Ports könnte man statt "VOLUME" es auch mal mit "MASTER_GAIN" ausprobieren.
Im übrigen... deine HW wird vom standard Sound-API eh nicht vollkommen unterstützt, denn dieses ist seit eh und je auf 2 Kanäle (Stereo) begrenzt. Da ist man am Ende eindeutig mit LWJGL oder JOAL ohnehin besser bedient.
 
Danke für die Antwort. Ports sind es doch nur weil ich die Lines zu Ports gecastet habe. Habe gelesen dass die Ports die Lines-Class erweitern. Und in den Tutorials wird überall zu nem Port gecastet.
Aber wenn eh nur Stereo unterstützt wird lese ich mich wohl besser in die von dir genannten APIs ein.
Vorerst würde ich sagen, das Thema hat sich erledigt : )
 

Neue Themen


Zurück
Oben