2016-06-17 33 views
0

Ich möchte zwei Audio-Streams mit einem Java-Mixer mischen und die Ausgabe in eine Datei schreiben.Mischen von zwei Audio-Streams mit Java-Mixer

so zu tun, erfassen ich den Eingang meiner zwei Mikrofone von der TargetDataLines meiner Mikrofonmischer zu lesen:

//microphone TargetDataLines 
    TargetDataLine finalIn = null; 
    TargetDataLine finalIn2 = null; 

    Mixer.Info[] mixerInfos = AudioSystem.getMixerInfo(); 
    for (Mixer.Info info: mixerInfos){ 

     Mixer m = AudioSystem.getMixer(info); 
     Line.Info[] lineInfos = m.getSourceLineInfo(); 
     System.out.println("****mixer name:" + info.getName()); 
     if(info.getName().equals("C920 [plughw:1,0]")) 
      finalIn=(TargetDataLine) m.getLine(m.getTargetLineInfo()[0]); 
     if(info.getName().equals("C920_1 [plughw:3,0]")) 
      finalIn2=(TargetDataLine) m.getLine(m.getTargetLineInfo()[0]); 

     for (Line.Info lineInfo:lineInfos){ 
      System.out.println ("\n source line info: "+lineInfo); 
     } 
     lineInfos = m.getTargetLineInfo(); 
     for (Line.Info lineInfo:lineInfos){ 
      System.out.println ("target line info: "+lineInfo); 
     } 

    } 

    AudioFormat format = new AudioFormat(8000,16, 1, true,false); 

    finalIn.open(format,2000); 
    finalIn.start(); 
    finalIn2.open(format,2000); 
    finalIn2.start(); 

    int numBytesRead; 
    byte[] targetData = new byte[finalIn.getBufferSize()/5]; 

    int numBytesRead2; 
    byte[] targetData2 = new byte[finalIn2.getBufferSize()/5]; 

    while (true) { 
      numBytesRead = finalIn.read(targetData,0,targetData.length); 
      numBytesRead2 = finalIn2.read(targetData2, 0, targetData2.length); 

Die resultierenden Daten von den Mikrofonen erfasst werden in targetData sein, targetData2. Nun möchte ich diese zwei Byte-Arrays, die meine vom Mikrophon empfangenen Sound-Samples enthalten, in ein neues Byte-Array mischen und ich möchte einen anderen Java-Mixer für dieses verwenden.

so zu tun, ich schaffe zwei SourceDataLine und ein TargetDataLine mit dem folgenden Code:

 DataLine.Info targetInfo = new DataLine.Info(TargetDataLine.class, format); 
     DataLine.Info sourceInfo = new DataLine.Info(SourceDataLine.class, format); 
     SourceDataLine sourceLine = (SourceDataLine) AudioSystem.getLine(sourceInfo); 
     SourceDataLine sourceLine2 = (SourceDataLine) AudioSystem.getLine(sourceInfo); 

     sourceLine.open(format,2000); 
     sourceLine.start(); 

     sourceLine2.open(format,2000); 
     sourceLine2.start(); 

     TargetDataLine targetLine = (TargetDataLine)  AudioSystem.getLine(targetInfo); 
     targetLine.open(format,2000); 
     targetLine.start(); 

und dann in der "while" Ich will hinzufügen:

byte[] result = new byte[finalIn.getBufferSize()/5]; 

    while (true) { 
      numBytesRead = finalIn.read(targetData,0,targetData.length); 
      numBytesRead2 = finalIn2.read(targetData2, 0, targetData2.length); 

      sourceLine.write(targetData, 0, numBytesRead); 
      sourceLine.write(targetData2, 0, numBytesRead2); 
      targetLine.read(result, 0, numBytesRead2); 
    } 

jedoch, während der Klang wird tatsächlich richtig über meine Kopfhörer gespielt, das Ergebnis-Array bleibt leer. Wie kann ich dieses Problem lösen? Was mache ich falsch?

+0

Sie möchten das Ergebnis speichern oder abspielen? und wenn du es spielst hast du eine andere Soundkarte? die Ziellinie soll erfassen, nicht schreiben, damit das Ergebnis nicht gespeichert wird; Sie müssen klären, was Sie genau machen wollen; Hast du viele Soundkarten? Bis dahin, wo Sie die beiden Mikrofone bekommen, sind Sie in Ordnung. – gpasch

+0

Für eine bessere Hilfe schreiben Sie früher ein [MCVE] oder [Short, Self Contained, Correct Example] (http://www.sscce.org/). –

+0

Ich habe zwei Mikrofone auf meinen 2 Webcams und 1 Soundkarte. Ich muss das Signal erfassen, das von meinem Programm an meinen Lautsprecher geht. Ich möchte die mit diesem Mixer verknüpfte Ziellinie erfassen. – Hossein

Antwort

1

Ich frage mich, ob Sie ein falsches Verständnis darüber haben, was ein Java-Mixer tut. Ich denke, dass diese Klasse wegen meiner Hintergrunderfahrung als Tontechniker schlecht benannt wurde. In meinen Augen kombiniert ein Mixer verschiedene Audiotracks. Das ist nicht was ein Java Mixer tut.

Ich denke, um zu tun, was Sie tun möchten, müssen Sie Ihre zwei Zeilen parallel lesen. Sie lesen jeweils einen Byte-Puffer und müssen die Bytes in PCM-Daten konvertieren. Dann können Sie die PCM-Daten zusammenfügen und diese zurück in Bytes konvertieren und ausgeben.

Es gibt ein gutes Tutorial, das zeigt, wie man die einzelnen Bytes/Frames bekommt here. Ein kurzer Weg auf der Seite, gibt es ein Codebeispiel. Achten Sie auf die Lage des Kommentars:

// Here, do something useful with the audio data that's 
// now in the audioBytes array... 

Dieses Beispiel aus einem AudioInputStream liest, aber die Technik für an den einzelnen Bytes von TargetDataLines immer ist das nicht anders. Natürlich würden Sie von beiden Zeilen anstatt vom einzelnen AIS lesen. Und die "nützliche Sache", die Sie tun würden, ist einfach die PCM-Daten pro Frame parallel hinzuzufügen.

Sobald Sie die Audiodaten summiert haben, könnten Sie vielleicht some code I wrote verwenden und an einer anderen Stelle, die einen PCM-Stream und schreibt es als WAV-Datei. Hoffentlich ist die Diskussion auf dieser Seite klar genug, dass Sie folgen können.

+0

Dies ist ziemlich aufschlussreich. Ich habe es geschafft, einen einfachen Mixer mit dem von Ihnen bereitgestellten Link zu schreiben. Allerdings habe ich mich gefragt, ob ich auf einen Hardware-Mixer von Java zugreifen könnte, der das Audio-Mischen für mich tun würde. – Hossein

+0

Scheint plausibel, aber ich habe es noch nie getan. Ich habe vor, endlich zu versuchen, MIDI-Input-Lesefähigkeiten für den Java-Synth zu programmieren, den ich im nächsten Monat geschrieben habe. Das wird mein erster Versuch sein, mit anderen Zeilen als Standard SourceDataLine & TargetDataLine umzugehen. –