2011-07-27 51 views
4

我需要從輸入端口而不是麥克風捕獲聲音。如何使用Java只從輸入端口錄製聲音

雖然我完成了從麥克風錄音,但我無法完成從輸入端口或特定端口捕捉聲音。我該如何處理這個問題?

+0

您使用的是哪個平臺? Java聲音的內容與OS到OS稍有不同。 – joev

回答

0

熟悉TargetDataLine類。另外,從它自己的Javadoc:

目標數據線可以由混頻器通過調用Mixer的 函數getline方法用適當的DataLine.Info對象獲得。

具體來說,我還審查Mixer.getTargetLineInfo(),並檢查返回的輸出選擇符合你正在尋找線路的線路輸入端口。

2

我也沒有想通這一點,但你確實需要

mixer.getSourceLineInfo(),因爲這是從調音臺的看法...真是混亂!

一個TargetDataLine的是可記錄輸入線,但要看到,這些線路可能來自你需要查找該混頻器具有IE瀏覽器(話筒,LINE_IN,SPDIF)端口,所以你需要調用

混合機.getSourceLineInfo()

這隻給出端口。這些可用於控制LINE_IN輸入的錄製音量,但不能直接從PORT對象錄製。

您需要使用 DataLine.Info targetDataLineInfo = new DataLine.Info(TargetDataLine.class,AudioFormat);

其中的AudioFormat就像

audioFormat = new AudioFormat(
       Encoding.PCM_SIGNED, 
       sampleRate, 
       bitRate, 
       monoOrStereo, 
       monoOrStereo * 2, // 
       sampleRate, 
       false); 

一些用戶自定義格式然後你得到的優選的混合器行:

Mixer.getLine(audioFormat); 

這會給你一個記錄的行,因爲你可能已經完成...

我不能弄清楚的是,就像你一樣,如何選擇一個端口如LINE_IN並創建一個匹配的PortData對象可以控制的TargetDataLine,我已經搜查,搜查..

()

任何人只要有一個工作的例子在那裏..

0

試試這個。如果它有效,讓我知道,因爲我無法在筆記本電腦上完全測試它。 然後,您可以自己設置功能,以獲得具有指定輸入類型和/或所需混音器的PortMixerActualMixerTargateDataLine

private void testGettingInput() { 
    //Check this out for interest 
    //http://www.java-forum.org/spiele-multimedia-programmierung/94699-java-sound-api-zuordnung-port-mixer-input-mixer.html 
    final String newLine = System.getProperty("line.separator"); 
    final String inputTypeString = "LINE_IN"; // or COMPACT_DISC or MICROPHONE etc ... 
    final Port.Info myInputType = new Port.Info((Port.class), inputTypeString, true); 
    final AudioFormat af = new AudioFormat(
      Encoding.PCM_SIGNED, 
      44100.0F, 
      16, 
      2, 
      2 * 2, 
      44100.0F, 
      false); 
    final DataLine.Info targetDataLineInfo = new DataLine.Info(TargetDataLine.class, af); 
    TargetDataLine targetDataLine; 

    //Go through the System audio mixers 
    for (Mixer.Info mixerInfo : AudioSystem.getMixerInfo()) { 
     try { 
      Mixer targetMixer = AudioSystem.getMixer(mixerInfo); 
      targetMixer.open(); 
      //Check if it supports the desired format 
      if (targetMixer.isLineSupported(targetDataLineInfo)) { 
       System.out.println(mixerInfo.getName() + " supports recording @" + af); 
       //now go back and start again trying to match a mixer to a port 
       //the only way I figured how is by matching name, because 
       //the port mixer name is the same as the actual mixer with "Port " in front of it 
       // there MUST be a better way 
       for (Mixer.Info mifo : AudioSystem.getMixerInfo()) { 
        String port_string = "Port "; 
        if ((port_string + mixerInfo.getName()).equals(mifo.getName())) { 
         System.out.println("Matched Port to Mixer:" + mixerInfo.getName()); 
         Mixer portMixer = AudioSystem.getMixer(mifo); 
         portMixer.open(); 
         portMixer.isLineSupported((Line.Info) myInputType); 
         //now check the mixer has the right input type eg LINE_IN 
         if (portMixer.isLineSupported((Line.Info) myInputType)) { 
          //OK we have a supported Port Type for the Mixer 
          //This has all matched (hopefully) 
          //now just get the record line 
          //There should be at least 1 line, usually 32 and possible unlimited 
          // which would be "AudioSystem.Unspecified" if we ask the mixer 
          //but I haven't checked any of this 
          targetDataLine = (TargetDataLine) targetMixer.getLine(targetDataLineInfo); 
          System.out.println("Got TargetDataLine from :" + targetMixer.getMixerInfo().getName()); 
          return; 
         } 
        } 
       } 
       System.out.println(newLine); 
      } 
      targetMixer.close(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 
2
import javax.sound.sampled.*; 

/** 
* 
* @author d07114915 
* 
* Class to get a mixer with a specified recordable audio format from a specified port 
* For instance get a 44.1kHz 16bit record line for a "line in" input 
*/ 
public class MixerMatcher { 
private static final String THE_INPUT_TYPE_I_WANT = "MICROPHONE"; 
private static final String THE_NAME_OF_THE_MIXER_I_WANT_TO_GET_THE_INPUT_FROM = "Realtek HD Audio Input"; 
private static final AudioFormat af = new AudioFormat(
     AudioFormat.Encoding.PCM_SIGNED, 
     44100.0F, 
     16, 
     2, 
     2 * 2, 
     44100.0F, 
     false); 
private static final DataLine.Info targetDataLineInfo = new DataLine.Info(TargetDataLine.class, af); 
private static final Port.Info myInputType = new Port.Info((Port.class), THE_INPUT_TYPE_I_WANT, true); 
private static TargetDataLine targetDataLine = null; 

public static void main(String[] args) { 
    Mixer portMixer = null; 
    Mixer targetMixer = null; 
    try { 
     for (Mixer.Info mi : AudioSystem.getMixerInfo()) { 
      //    System.out.println("-" +mi.getName() + "-"); 
      if (mi.getName().equals(THE_NAME_OF_THE_MIXER_I_WANT_TO_GET_THE_INPUT_FROM)) { 
       System.out.println("Trying to get portMixer for :" + mi.getName()); 
       portMixer = getPortMixerInfoFor(mi); 
       if (portMixer != null) { 
        System.out.println(portMixer.getMixerInfo().toString()); 
        targetMixer = AudioSystem.getMixer(mi); 
        break; 
       } 
      } 
     } 
     if (targetMixer != null) { 
      targetMixer.open(); 

      targetDataLine = (TargetDataLine) targetMixer.getLine(targetDataLineInfo); 
      System.out.println("Got TargetDataLine from :" + targetMixer.getMixerInfo().getName()); 

      portMixer.open(); 

      Port port = (Port) portMixer.getLine(myInputType); 
      port.open(); 

      Control[] controls = port.getControls(); 
      System.out.println((controls.length > 0 ? "Controls for the "+ THE_INPUT_TYPE_I_WANT + " port:" : "The port has no controls.")); 
      for (Control c : controls) { 
       System.out.println(c.toString()); 
      } 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

} 

//return the portMixer that corresponds to TargetMixer 
private static Mixer getPortMixerInfoFor(Mixer.Info mixerInfo) { 
    //Check this out for interest 
    //http://www.java-forum.org/spiele-multimedia-programmierung/94699-java-sound-api-zuordnung-port-mixer-input-mixer.html 
    try { 
     // get the requested mixer 
     Mixer targetMixer = AudioSystem.getMixer(mixerInfo); 
     targetMixer.open(); 
     //Check if it supports the desired format 
     if (targetMixer.isLineSupported(targetDataLineInfo)) { 
      System.out.println(mixerInfo.getName() + " supports recording @ " + af); 
      //now go back and start again trying to match a mixer to a port 
      //the only way I figured how is by matching name, because 
      //the port mixer name is the same as the actual mixer with "Port " in front of it 
      // there MUST be a better way 
      for (Mixer.Info portMixerInfo : AudioSystem.getMixerInfo()) { 
       String port_string = "Port "; 
       if ((port_string + mixerInfo.getName()).equals(portMixerInfo.getName())) { 
        System.out.println("Matched Port to Mixer:" + mixerInfo.getName()); 
        Mixer portMixer = AudioSystem.getMixer(portMixerInfo); 
        portMixer.open(); 
        //now check the mixer has the right input type eg LINE_IN 
        boolean lineTypeSupported = portMixer.isLineSupported((Line.Info) myInputType); 
        System.out.println(portMixerInfo.getName() +" does " + (lineTypeSupported? "" : "NOT") + " support " + myInputType.getName()); 
        if (lineTypeSupported) { 
         portMixer.close(); 
         targetMixer.close(); 
         return portMixer; 
        } 
        portMixer.close(); 
       } 
      } 
     } 
     targetMixer.close(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return null; 
} 
} 

運行此我得到:
Trying to get portMixer for :Realtek HD Audio Input
Realtek HD Audio Input supports recording @ PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, little-endian
Matched Port to Mixer:Realtek HD Audio Input
Port Realtek HD Audio Input does support MICROPHONE
Port Realtek HD Audio Input, version 5.10
Got TargetDataLine from :Realtek HD Audio Input
Controls for the MICROPHONE port:
Mic Volume Control containing Select, Microphone Boost, Volume, and Balance Controls.

改變混頻器和輸入型的喜好來 「USB聲音設備」 和 「」 LINE_IN」分別我得到以下幾點:(注意有8空格在單詞「設備」後的混頻器的名字,但他們不會在該網頁上顯示!)

Trying to get portMixer for :USB Sound Device
Trying to get portMixer for :USB Sound Device
USB Sound Device supports recording @ PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, little-endian
Matched Port to Mixer:USB Sound Device
Port USB Sound Device does support LINE_IN
Port USB Sound Device , version 0.16
Got TargetDataLine from :USB Sound Device
Controls for the LINE_IN port:
Line Control containing Select, Mute, Volume, and Balance Controls.

這裏的USB聲卡顯示一個輸入端口和一個輸出端口,因此其中一個不支持LINE_IN,這可能是因爲它是一個輸出,因此可能允許錄製「立體聲混音」或某種其他輸出類型

希望這可以工作,並幫助某人......因爲Java文檔相當含糊...... 在Windows上測試過,但我認爲Linux不會識別諸如LINE_IN之類的端口名稱,因此您需要檢查一下操作系統端口,以及可能的其他一些東西一樣需要混音名稱等... 在我的Linux麥克風被稱爲「捕獲」 ......

檢查jsresources.org FAQ一個子更多信息

錯誤等任何改進讓我知道。

d07114915