2011-08-22 118 views
1

即時通訊播放的內容超出了我通常編程的範圍,所以我想在浪費更多時間之前我會問。音頻輸入編程

所以基本上我有一個按鈕(通常在計算機開/關開關上找到),並使用我不太瞭解的電子電路知識,我將它連接到標準音頻電纜(當然連接到我的電腦音頻插孔)。通過Audacity,我發現當我點擊按鈕時,會生成一個音頻波形並將其拾取。

這是非常基本的東西,我離開了我的Arduino回到我父母的地方,以便在絕望中我決定用我的聲卡作爲微控制器。

無論如何,我相信你們都知道我要去哪裏。 我該如何編程一個運行於命令提示符(用於測試)的小應用程序,以及作爲後臺進程來監視和處理來自輸入的信息以執行某些任務(如鎖定我的計算機或打開Firefox等..)?

我與Java上班我的計算機學位的一部分(我們仍在學習很基本的東西......因此這個問題),並用PHP的工作每天都在工作,所以我不介意學習一門新語言,如果我必須。

回答

1

我最終搞清楚了這一張給自己。基本上就像聽輸入線一樣簡單,然後運行一個方法,如果音頻的幅度得到一定的數量。通過測試,我還發現,當按下按鈕時,幅度的測量值爲負值,釋放按鈕時記錄正幅值。這意味着您可以爲這些單獨事件編寫代碼,並且如果您足夠聰明,還可以使用間隔計時器爲按鈕被按下時添加事件。

反正這裏是代碼(不幸的是我還沒有發表評論它的時間):

AudioInputButton.java

import javax.sound.sampled.AudioFormat; 
import javax.sound.sampled.AudioSystem; 
import javax.sound.sampled.DataLine; 
import javax.sound.sampled.LineUnavailableException; 
import javax.sound.sampled.TargetDataLine; 
import javax.sound.sampled.Mixer.Info; 


public class AudioInputButton { 
    private int line; 
    private AudioFormat format; 
    private Info[] lines; 
    private TargetDataLine inputLine; 
    private DataLine.Info inInfo; 
    private int bufferSize; 

    public AudioInputButton(int line){ 
    this.line = line; 
    this.setup(); 
    } 

    public AudioInputButton(){ 
    this.line = 2; 
    this.setup(); 
    } 

    private void setup(){ 
    format = new AudioFormat(8000, 8, 1, true, true); 
    lines = AudioSystem.getMixerInfo();  
    inInfo = new DataLine.Info(TargetDataLine.class, format); 
    bufferSize = (int) format.getSampleRate() * format.getFrameSize(); 
    } 

    public void printLineInfo(){ 
    for (int i = 0; i < lines.length; i++){ 
     System.out.println(i+": "+lines[i].getName()+"\n"+lines[i].getDescription()); 
    } 
    } 

    public void startListening(){ 
    try{ 
     inputLine = (TargetDataLine)AudioSystem.getMixer(lines[line]).getLine(inInfo); 
     inputLine.open(format, bufferSize); 
     inputLine.start(); 

     byte[] buffer = new byte[bufferSize]; 

     System.out.println("Listening on line " +line+", " + lines[line].getName() + "..."); 

     while(true){ 
     inputLine.read(buffer,0,buffer.length); 
     int sample = listen(buffer); 
     if(sample > 0){ 
      onClick(); 
     } 
     } 
    }catch (LineUnavailableException e){ 
     System.out.println("Line " + line + " is unavailable."); 
     e.printStackTrace(); 
     System.exit(1); 
    } 
    } 

    public int listen(byte[] eightBitByteArray) 
    { 
    int index = 0; 
    int ret = 0; 
    boolean down = false; 
    boolean up = false; 
    for (int audioByte = 0; audioByte < eightBitByteArray.length;) 
    { 
     int low = (int) eightBitByteArray[audioByte]; 
     audioByte++; 
     int high = (int) eightBitByteArray[audioByte]; 
     audioByte++; 
     int sample = (high << 8) + (low & 0x00ff); 
     if(sample < -1100){ 
     if(!down){ 
      onDown(); 
      ret = sample; 
      down = true; 
     } 
     }else if(sample > 1100){ 
     if(!up){ 

      onUp(); 
      ret = sample; 
      down = false; 
      up = true; 
     } 
     } 
     index++; 
    } 
    return ret; 
    } 

    private void onClick(){ 
    System.out.println("Click!"); 
    } 

    private void onDown(){ 
    System.out.println("Down!"); 
    } 

    private void onUp(){ 
    System.out.println("Up"); 
    } 
} 

AudioInputButtonTester.java

public class AudioInputButtonTester { 
    public static void main (String [] args){ 
    AudioInputButton myButton = new AudioInputButton(2); 
    myButton.startListening(); 
    } 
} 

我打算將各種按鈕狀態變成事件,以便您可以在測試者類中爲他們編寫代碼,但是它的凌晨2:30,如果你真的想要分離你的邏輯,創建一個新的按鈕類來擴展AudioInputButton和你自己的代碼。

0

我覺得,這個任務可以標準化或使用COM port簡化。

查閱這些例子 http://www.java2s.com/Code/Java/Development-Class/COM-Port.htm http://java.sun.com/developer/Books/javaprogramming/cookbook/11.pdf

如果你想使用的音頻輸入插孔(做你的任務麥克風輸入端口),您必須檢查聲音幅度的輸入電平並根據亮度等級完成您的任務。對於這一點,你必須讓多線程的想法和記錄的聲音在JAVA

+0

通過我的急躁,我終於找到了一種通過良好的舊Java來實現它的方法。我只是爲了真正的樂趣而嘗試這一點。 –