2016-06-17 7 views
0

Я хочу смешивать два потока аудио с помощью java-микшера и записывать вывод в файл.Смешивание двух потоков аудио с помощью Java-микшера

Чтобы сделать это, я захвачу вход моих двух микрофонов, читая от TargetDataLines моих микрофонных смесителей:

//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); 

Полученных данных, захваченных у микрофонов будут targetData, targetData2. Теперь я хочу смешать эти два байтовых массива, содержащие мои образцы звука, полученные от микрофона, в новый массив байтов , и я хочу использовать другой Java-микшер для этого.

Для этого я создаю два SourceDataLine и один TargetDataLine используя следующий код:

 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(); 

, а затем внутри «а» я добавлю:

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); 
    } 

однако, в то время как звук на самом деле правильно воспроизводится через наушники, массив результатов остается пустым. Как я могу решить эту проблему? Что я делаю не так?

+0

Вы хотите сохранить результат или воспроизвести его? и если вы играете в нее, у вас есть еще одна звуковая карта? целевая линия - захват не для записи, поэтому результат не будет сохранен; вам нужно уточнить, что именно вы хотите сделать; у вас много звуковых карт? До того места, где вы получаете два микрофона, вы в порядке – gpasch

+0

Чтобы лучше помочь, опубликуйте [MCVE] или [Short, Self Contained, Correct Example] (http://www.sscce.org/). –

+0

У меня два микрофона на моих 2 веб-камерах и 1 звуковая карта. Мне нужно захватить сигнал, который поступает на мой динамик из моей программы. Я хочу захватить целевую линию, связанную с этим микшером. – Hossein

ответ

1

Интересно, есть ли у вас неправильное представление о том, что делает Java-микшер. Я думаю, что этот класс плохо назван, из-за моего опыта работы в качестве звукорежиссера. На мой взгляд, микшер - это то, где вы комбинируете различные звуковые дорожки. Это не, что делает Java Mixer.

Я думаю, что для того, чтобы делать то, что вы хотите сделать, вам нужно прочесть ваши две строки параллельно. Для каждого вы читаете буфер байтов и должны будете преобразовать байты в данные PCM. Затем вы можете добавить данные PCM и преобразовать их обратно в байты и вывести их.

Существует хороший учебник, в котором показано, как получить отдельные байты/фреймы here. Короткий путь вниз по странице, есть пример кода. Обратите внимание на расположение комментария:

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

Этот пример читает из AudioInputStream, но способ для получения на отдельных байтов из TargetDataLines не отличается. Конечно, вы читали бы из обеих строк, а не из одной AIS. И «полезная вещь», которую вы делаете, - это просто добавление данных PCM на основе каждого кадра параллельно.

После того как вы суммировали аудиоданные, вы могли бы использовать some code I wrote и размещать на другом сайте, который принимает поток PCM и записывает его как файл wav. Надеюсь, обсуждение на этой странице достаточно ясно для вас.

+0

Это довольно просветительская. Мне удалось написать простой миксер, используя указанную вами ссылку. Тем не менее, мне было интересно, могу ли я получить доступ к аппаратным микшерам с Java, которые будут делать аудио-микширование для меня. – Hossein

+0

Кажется правдоподобным, но я никогда этого не делал. Я планирую, наконец, попробовать кодировать возможности чтения MIDI-данных для java-синтеза, который я написал в следующем месяце. Это будет моя первая попытка обработать строки, отличные от стандартных SourceDataLine & TargetDataLine. –

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