JMF Mikrofon Rückkoppelung (VOIP)

athikka

Aktives Mitglied
Hallo zusammen!

Ich mache gerade ein VOIP programm wo ich eben mit einem partner reden kann.
funktioniert soweit ganz gut, aber ich hab noch ein problem mit der rückkopplung, d.h. ich höre mich selbst wieder (weil von dem boxen des anderen meine stimme gleich wieder ins mikro geht...)

hat jemdand erfahrung damit und wie man soetwas lösen könnte?
so ähnlich wie skype, da funktioniert das ja super.

ich dachte schon dass ich die aufnahme von mir stoppe sobald mein gegenüber spricht und umgekehrt (oder zumindest die mikro-empfindlichkeit runterdrehe)...

aber ich weiß nicht obs was bessere gibt - hat wer code dazu?

so mache ich es:

Java:
	private AudioFormat getAudioFormat(){
	    float sampleRate = 16000.0F;		 //11025 oder 16000 für besseres signal 
	    int sampleSizeInBits = 16;		   
	    int channels = 1;		    
	    boolean signed = true;		    
	    boolean bigEndian = false;		 
	    return new AudioFormat(sampleRate,sampleSizeInBits,channels,signed,bigEndian);
	}

//und zum aufnehmen:

		try {
			
			Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo();
			System.out.println("Available mixers:");
			for (int cnt = 0; cnt < mixerInfo.length; cnt++) {
				System.out.println(mixerInfo[cnt].getName());
			}
			
			audioFormat = getAudioFormat();
			try{
				
				//TODO um probleme zu vermeiden, mikro "leiser" machen wenn anderer spricht und so auch beim anderen (und wieder laut wenn man selbst spricht)
				if(captureDataLine == null){
					DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, audioFormat);
					Mixer mixer = AudioSystem.getMixer(mixerInfo[4]);
					captureDataLine = (TargetDataLine) mixer.getLine(dataLineInfo);
				} else {
					Table.p("mixer problem");
				}
				
				if(captureDataLine != null && !captureDataLine.isOpen()) {
					captureDataLine.open(audioFormat);
					captureDataLine.start();
				} else {
					Table.p("TDL open + start problem");
				}
				
				startThread(); //siehe unten
				
			} catch (Exception e){
				e.printStackTrace();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

und zum aufnehmen (natürlich im thread der durhc startthread erzeugt wird):

Java:
byte soundBuffer[] = new byte[1000]; // immer 1000 bytes aufnehmen		
int cnt = captureDataLine.read(soundBuffer, 0, soundBuffer.length)

wie gesagt, der code geht, jedoch ist das problem der rückkopplung da... also muss ich da was machen - hat jemand eine Idee (mikro leiser, andere soundeinstllungen...)

Vielen DAnk!
 

athikka

Aktives Mitglied
ja aber das kann ja keine lösung sein da skype wunderbar funktioniert
die haben da irgendeinen trick dabei kennst du den? mir ist aufgefallen dass die die mikro aufnahmeempfinlichkeit je nach umgebungslautstärke anpassen...

vl mirkrofonverstärkung?
wie kann ich den "microphone-boost" vom java aus modifizieren?

wenn ich den nämlich deaktiviere, hallt es nicht so
 

mjdv

Bekanntes Mitglied
Schon das muten ausprobiert?

Mute
Muting is independent of the gain. If mute is true, no audio signal is produced by this object; if mute is false an audio signal is produced and the gain is applied to the signal.

JMF 2.0 API (03/10/01): Interface GainControl

Da steht auch was von gain und db

Defaults
Gain defaults to a value of 0.0 dB. The corresponding level is implementation dependent. Note that for some implementations, the default level might change on a per-instance basis.

Kp was des is. Aber vll hilfts dir ja
 

mjdv

Bekanntes Mitglied
Oh achso.

Ne ich denke nicht, die Standard API ist etwas beschränkt denke ich.

Du könntest auch versuchen den Sound der aus den Lautsprechern kommt und gleichzeitig auch ins Mikrofon irgendwie rauszufiltern. Das ist zwar mühselig, aber sollte gehen, und wenn einem eben gar ncihts mehr einfällt ^^
 

athikka

Aktives Mitglied
ok dann lasse ich mich zu JMF überreden :)

wie kann ich damit nun die Mikro-empfindlichkeit bzw aktuelle aufnahmelautstärke ermitteln? bzw verstellen?
 
T

tuxedo

Gast
Skype und Co. benutzen u.A. "echo cancelling filter". D.h. die greifen in den Audio-Strom aktiv ein und unterdrücken den Echo-Effekt so gut wie es eben nur geht.

Es gibt auch Codecs (welche logischerweise den Audiodatenstrom komprimieren/reduzieren) die das schon eingebaut haben.


- Alex
 

athikka

Aktives Mitglied
super, das ist genau das was ich hören wollte :)
also gibt es eine lösung

kennst du solche Codecs? bzw beispiele die mir helfen könnten? (die vl autom. meine lautsprecherausgabe vom mikroeingang fernhalten?)
 

Empire Phoenix

Top Contributor
Eine einfache Lösung wäre btw einfach solange jemand anders redet die Lautstärke des Mikrofons auf faust 0 runterzuregeln, (normalerweise sollt ja eh nur einer Reden, nur das Microfon halt so laut lassen, dass man hört wenn wer anders auch irgetwas sagt)
 
T

tuxedo

Gast
Das führt zu seltsamen Effekten....

Haben wir hier in der Firma in unseren Telefonkonferenzen auch. Einer der Chefs hat ein Telefon das offenbar den Lautsprecher massiv runterdreht wenn er spricht. Und da er lang und viel redet, ist es nahezu unmöglich ihn zu unterbrechen.. Denn er hört einen ja nicht wenn er spricht.

Moderne Sprachcodecs haben die Echo-Unterdrückung wie gesagt schon implementiert.

Am besten optimiert man das ganze noch durch geeignete Hardware. Es gibt nämlich Mikrofone die das auch schon mit drin haben: ClearOne AccuMic® PC | AccuMic® PC Conferencing Microphone | Echo Cancellation | Noise Cancellation

Eine gute Audiokonferenz bekommt man nur dann hin, wenn man das passende Equipment hat. Die Software-Echo-Unterdrücking ist schon nicht schlecht, aber oftmals nicht das allheilmittel.

Aber wenn man mit den Nachteilen die eine einfache Softwarelösung (Lautsprecher muten und so) mit sich bringt leben kann: Warum nicht...

- Alex

P.S. Let me google that for you
 

athikka

Aktives Mitglied
jetzt wäre noch super wenn jemand eventuell einen solchen Code (ausschnitt) hat (softwareseitig echo unterdrückung)... oder zumindest wie man erkennen kann, ob wer spricht oder ob es nur hintergrundgeräusche sind?

das wäre super
 
T

tuxedo

Gast
Du stellst dir das so einfach vor.. Aber zum Thema Echo-Unterdrückung kann man ganze Doktor-Arbeiten schreiben. Da gehört ordentlich Mathematik dazu um das softwareseitig sauber zu lösen.

"Einfache" Lösungen sind solche, wie Empire Phoenix sie vorgeschlagen hat. Und das solltest du alleine können. Aber ich formulier's mal mit etwas Pseudo-Code:

Code:
while (microphone.getLevel()>=levelOfATypicalTalkingPerson){
    speaker.setVolume(veryLow)
}

Natürlich sollte man beachten dass es wenig Sinn macht den Lautsprecher in einer Schleife immer und immer wieder auf "leise" zu drehen. Aber so in etwa könnte die einfache Lösung aussehen.

- Alex
 

athikka

Aktives Mitglied
Danke schonmal für die vielen Antworten


Hat jemand trotzdem vl etwas code?
z.b. wie man das mikrofon-inputsignal z.b. von 0-100 messen kann?

finde dazu nichts brauchbares bzw gut funktionierendes (weils z.b. nur auf 8 bit ausgelegt ist)?

ich habe unlängst die idee gehabt, einfach zu schauen, wie lange ein ping dauert und dann je das ausgangssignal MINUS dem "damaligen" mikrofoninput zu subtrahieren - natürlich z.b. um 50% abgeschwächt. das sollte doch das problem ansatzweise lösen oder?

weiß jemand, wie ich rausfinden, wieviele millisekunden z.b. 1000 bytes im sound-buffer sind? (bei 16 bit)
und dann würde ich einfach signal1-altsignal/2 rechnen... oder bin ich da falsch
 
T

tuxedo

Gast
Zu allererst: JMF ist TOT. Macht es Sinn sich auf so eine Library bei einer Neuentwicklung zu stützen?!

Du kannst das ganze auch über die Java Sound API machen. Das ist in jeder Standard-SUN JRE schon mit drin und funktioniert "out of the box".
Eine sehr gute Quelle wie man was mit dem API macht ist Java Sound Resources

"Richtiges" Echo-Cancelling implementier man "nicht mal eben schnell" (irgendwie treten wir in der Diskussion auf der Stelle... Liest du eigentlich was wir ratschlagen??).
Du hast jetzt folgende Möglichkeiten:

1) Signalverarbeitung: Einen (Sprach-)Codec benutzen der Echo-Cancelling schon drin hat
2) Simple Programmlogik: Eine Low-End Variante selbt implementieren. Die macht dann kein Echo-Cancelling, hat aber einen positiven Einfluss auf die Ursache der Rückkopplung

Zu 1): Geh zu google und such nach Sprachcodecs und lerne wie man welchen Sprachcodec benutzt --> nicht ganz so easy, da viele (oder die meisten) Codecs nicht in Java geschrieben sind und man dann JNI/JNA braucht --> C/C++ Kenntnisse erfoderlich

Zu 2): Das Problem ist ja unter anderem folgendes: A spricht. Das Signal wird zu B übertragen wo es aus dem Lautsprecher kommt. B hat aber auch ein Mikrofon das das SIgnal gleich wieder auf nimmt und zurück an A schickt, wo es aus dem Lautsprecher kommt und vom Mikrofon von A wieder aufgenommen wird. Die Rückkopplungskette ist "geschlossen".
Du musst also versuchen das Signal an einer sinnvollen Stelle zu unterbrechen, oder zumindest zu schwächen.
Unterbrechen: Nun, das ist eher unschön. Meist wird das implementiert in dem der Sprecher eine Taste drücken muss "um sein Mikrofon zu öffnen". Bei Teamspeak und Co. noch "vertretbar". Bei einer anderen VoIP Anwendung vermutlich nicht so, da nicht praktikabel.
Abschwächen: Nun. Du könntest, während A spricht, einfach den Laursprecher von A entwas herunterdrehen. Dadurch machst du es dem Mikrofon schwer das eigene Signal das über B die Runde gemacht hat nochmal aufzunehmen. Natürlich gibts noch andere Ecken und Enden wo man bzgl. des Abschwächend oder unterbrechens ansetzen kann. Man muss da nur ein klein wenig das Hirn anstrengen...

Lösung 1) ist natürlich immer zu bevorzugen, da sie direkter und genauer wirken kann. Diese Lösung selbst implementieren: Nun, da sollte man schon sehr fit sein im Umgang und dem Filtern (da gehört einiges an Mathematik dazu) von digitalisierten Audiosignalen.

Lösung 2) kann auch recht gut gehen. Ist aber stark davon abhängig welche Hardware man hat. Man wird also schauen müssen dass das passende Equipment hat. Also entweder ein Headset das Lautsprecher und Mikro allein schon von der Lautstärker des Kopfhöreres her separiert, oder aber ein anständiges Tisch-Mikrofon das das kann. Hab ja schon eins verlinkt. Es gibt aber für "wenig Geld" auch Tisch-USB-Mikros die gleich noch einen Lautsprecher drin haben und die dann ebenfalls "hardwareseitige" Echo-Unterdrückung drin haben. Ich meine mich erinnern zu können das solche Teile zwischen 50 und 80EUR (aufwärts) kosten.
 

athikka

Aktives Mitglied
glaubst du hat es sinn wenn ich es so angehe:

ich schaue, wie lang der Ping zu meinem gesprächspartner ist (z.b. 100ms)

dann merke ich mir beim senden immer die letzten 200ms (hin und zurück) und ziehe wenn das signal von meinem partner ankommt, dann die gemerkten bytes in abgeschwächter form ab?

das solle ja mein signal abziehen oder?

wie kann ich überhaupt das signal abschwächen und kann ich bei dem byte array einfach Minus rechnen?
habe da leider nicht viel erfahrung
 

fb

Neues Mitglied
Hallo zusammen,
wirkungsvoller als eine mathematische Echounterdrückung, ist das Problem an der Wurzel zu packen! Jedes einzelne Mikro Stummschalten/Unterbrechen, solang nicht gesprochen wird.
Ich empfehle zwei Möglichkeiten, die das Gleiche bewirken;

__Hardwarelösung__
Das Mikro bekommt einen Unterbrecherkontakt in Form eines Tasters. Hier gibt es auch 2 Varianten. Für einen Elektroniker absolut Easy.
(1) Einmal den Taster als Schließer, der direkt im Mikrosignalweg liegt und bei Tasten (Sprechen), das Mikro frei schaltet.
(2) Einen Taster als Öffner, der parallel zu Mikro liegt und somit im Ruhezustand/Nichtsprechen den Mikro-Vorverstärker kurz schließt. "Kurzschluß" klingt verboten, ist im Fall einers Audioeingangs meist selbstverständlich.
Diese Variante hat gegenüber (1) mehrere Vorteile was Störsicherheit und Übertragungsqualitäten angeht.

__Softwarelösung__
Den Mikro-VV (Audio-In im Rechner) mit einem kleinen Patch, via Computer-Mouse auf dem Bildschirm einschalten. "Ein" (=Mikro freigeschaltet) solang der Mouse-Cursor auf dem Button verweilt.

Mal was anderes - aber wenn´s hilft... fRANK b.

Weitere Infos über "bersi-son ( ät ) web.de"
 
T

tuxedo

Gast
Naja, mit "Hardware" würde ich das nicht lösen wollen. Zumindest nicht in Form eines "Unterbrechers". Das ist "billig", "unprofessionell" und "qualitativ schlecht" (allein schon wegen dem möglichen Prellen des Schalters und dem damit verbundenen knacksen bei der Wiedergabe).


Den Mikro-VV (Audio-In im Rechner) mit einem kleinen Patch, via Computer-Mouse auf dem Bildschirm einschalten. "Ein" (=Mikro freigeschaltet) solang der Mouse-Cursor auf dem Button verweilt.

Oh man. Du hast noch nciht viel Software entwickelt, oder? Wie wär's mir "einfach nix senden wenn es nix zu senden gibt" ?! Das ist einfacher zu lösen, man muss nix patchen und gar nix. Man muss es einfach nur so implementieren.

Davon abgesehen: Es gibt auch die Möglichkeit den Pegel des Mikrofonsignals zu überwachen und nur dann die Aufnahme zu senden, wenn ein gewisses Level überschritten wird. Funktioniert bei Teamspeak und Co. bestens.

Alles in allem: Anständige VoIP Lösungen brauchen anständige Hardware (mit eingebauter Echounterdrückung, oder halt ein Headset das ein Mirkofon hat das etwas unempfindlicher als ein Tischmikrofon ist), und eine anständige Software die entweder aktiv das Echo rausfiltert, oder Maßnahmen ergreift um das Echo erst gar nicht entstehen zu lassen (Einschalten ab gewissem Pegel, Einschalten per Tastendruck, ...)

Alles andere klingt doch sehr nach einer Frickellösung.

- Alex
 

athikka

Aktives Mitglied
Hallo

ja es sollte schon halbwegs professionell sein und auch für otto-normalverbraucher ohne großes drücken und tippen möglich sein :D

das mit dem mikrofonpegel überwachen -> hast du da eine lösung dafür? also ab welchem pegel es als "sprache" erkannt wird und sendet und ab welchem nicht?

bin im thema audio leider nicht so dingfest und alle inet-quellen liefern nur lösungen für standard-probleme. da braucht man ja richtig einen, der da profi ist und der es dann einfach erklärt - da würd man sich oft ne unmenge an zeit sparen

das würde mir sehr helfen... (also eine art methode die zurückgibt ob er spricht oder nicht und das dann bei "true" sendet und bei "false" verwirft)
 
T

tuxedo

Gast
Das kannst du nicht fest definieren. Der eine brüllt ins Mikro, der andere flüstert...


Du musst dir eine Pegelanzeige basteln und da einen "Schieberegler" daneben legen. Mit dem Schieberegler kann dann der User einstellen ab welchem Pegel das Mikrofon offen bzw. zu ist.

Gibt natürlich noch andere Wege. Aber das ist der naheliegendste. Anregungen kannst du dir unter anderem bei "Teamspeak 2" holen. Keine Ahnung ob "Teamspeak 3" das immer noch so handhabt.

- Alex
 

Andi_CH

Top Contributor
Die Pegel sind so individuell wie es Mikrofonhersteller, Lausprecherhersteller, Sprecher und Räume gibt - das lässt sich so unmöglich beantworten!

Grundsätzlich nimmst du die Eingangs-Audiodaten und zählst davon die Daten ab die du gleich davor über Lautsprecher ausgegeben hast - natürlich entsprechend den oben aufgezählten Einflüssen gewichtet und möglicherweise um einige Mikro- oder Millisekunden verzögert. (Die Zeit die es braucht bis die Ausgabedaten durch den D/A-Wandler, den Lautsprecher, die Luft, das Mikro und den A/D Wandler "gewandert" sind.
Ach ja, vielleicht wurden die im Frequenzgang ja noch verändert - also bitte auch das kompensieren ....

Ist dir jetzt etwas klarer was tuxedo mit Doktorarbeit gemeint hat?

Codeschnippsel gibt es nicht, besser gesagt sie bringen dir nichts, weil die Konfiguration das eigentliche Problem ist.

Stummschalten von Mirofonen ist doof - wir sind uns nun mal 2-Weg-Kommunikation gewohnt (VoIP ist nun mal nicht Amateurfunk) und eben der Chef der sich gerne reden hört .....

Das Problem an der Wurzel packen tönt gut, aber nicht mit stummschalten sondern schlicht und einfach damit, dass keine Lautsprecher sondern Headsets verwendet werden.
 

Ähnliche Java Themen

Neue Themen


Oben