8

我正在開展一項有點雄心勃勃的項目,以通過耳塞或耳機在Android上實現主動降噪。Android主動式噪音消除

我的目標是用android手機麥克風錄製環境噪音,反轉相位(從音頻記錄中拉出的短值的簡單* -1),並通過耳機播放該反轉的波形。如果延遲和幅度接近正確,則應該消除環境中的大量機械結構噪聲。

這裏是我到目前爲止有:

@Override 
    public void run() 
    { 
     Log.i("Audio", "Running Audio Thread"); 
     AudioRecord recorder = null; 
     AudioTrack track = null; 
     short[][] buffers = new short[256][160]; 
     int ix = 0; 

    /* 
    * Initialize buffer to hold continuously recorded audio data, start recording, and start 
    * playback. 
    */ 
     try 
     { 
      int N = AudioRecord.getMinBufferSize(8000,AudioFormat.CHANNEL_IN_MONO,AudioFormat.ENCODING_PCM_16BIT); 
      recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, 8000, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, N*10); 
      //NoiseSuppressor ns = NoiseSuppressor.create(recorder.getAudioSessionId()); 
      //ns.setEnabled(true); 

      track = new AudioTrack(AudioManager.STREAM_MUSIC, 8000, 
        AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, N*10, AudioTrack.MODE_STREAM); 
      recorder.startRecording(); 
      track.play(); 
     /* 
     * Loops until something outside of this thread stops it. 
     * Reads the data from the recorder and writes it to the audio track for playback. 
     */ 
      while(!stopped) 
      {      
       short[] buffer = buffers[ix++ % buffers.length]; 
       N = recorder.read(buffer,0,buffer.length); 

       for(int iii = 0;iii<buffer.length;iii++){ 
        //Log.i("Data","Value: "+buffer[iii]); 
        buffer[iii] = buffer[iii] *= -1;       
       }      
       track.write(buffer, 0, buffer.length); 
      } 
     } 
     catch(Throwable x) 
     { 
      Log.w("Audio", "Error reading voice audio", x); 
     } 
    /* 
    * Frees the thread's resources after the loop completes so that it can be run again 
    */ 
     finally 
     { 
      recorder.stop(); 
      recorder.release(); 
      track.stop(); 
      track.release(); 
     } 
    } 

我一度興奮地找到了Android API已經有一個NoiseSuppression算法(你會看到它上面註釋掉)。我對它進行了測試,發現NoiseSuppressor沒有做太多的工作來消除不斷的音調,這導致我相信它實際上只是在非人聲頻率下執行帶通濾波器。

所以,我的問題:

1)上面的代碼中的耳機需要從MIC錄音約250-500ms通過播放。這個延遲很糟糕,減少它會很好。任何建議,將不勝感激。 2)不管延遲多麼緊,我的理解是回放波形將具有相對於實際環境噪聲波形的相位偏移。這表明我需要執行某種波形匹配來計算此偏移量並進行補償。關於如何計算的思考?

3)當涉及補償延遲時,會是什麼樣子?每個週期都會有一些短路,所以30毫秒或250毫秒的延遲會是什麼樣子?

我知道這種方法的根本問題是手機的位置不在頭部旁邊可能會引入一些錯誤,但我希望有一些動態或固定的延遲校正,它可能是有可能克服它。

感謝您的任何建議。

+0

從理論上講,您可能可以爲極低頻率做些事情,但即使這樣也不現實。 –

+0

關於您的項目如何通過的任何更新? –

+0

很遺憾沒有。在得出結論之後,我擱置了它,我無法彌補從電話麥克風到用戶耳朵的可變距離。我很樂意再次選擇它,但現在還不清楚從哪裏開始。 – Raevik

回答

4

即使您能夠對延遲做些事情,但由於您不知道手機與耳朵之間的距離,還有一個事實,即距離不固定(因爲用戶會移動手機),加上每個耳朵都沒有麥克風的事實(因此,即使您有零延遲,您仍然無法知道一隻耳朵會在一隻耳朵上出現什麼波形,即使您有零延遲)

話雖如此,你也許可以做一些可以取消高度週期性波形的東西。所有你可以做的是允許用戶手動調整每個耳朵的時間延遲 - 因爲你的耳朵本身沒有麥克風,你可以在你的代碼中沒有辦法知道你是否讓問題變得更好,或者更差。

+0

我討厭這可能是真實的,因爲我不喜歡接受某些事情是不可能的。即使解決方案不完美,我也必須相信有一種方法可以設置校準方案或機制來動態補償。我讚賞反饋和upvoted,雖然:) – Raevik

+0

我看不出你可以做任何校準或補償,除非你涉及到用戶,並且這個過程可能比噪聲本身更惱人,特別是如果他們有無論如何,這些緊身耳塞可以阻擋很多噪音!再次,它僅對非常週期性或可預測的噪音有幫助。現實世界的環境噪音並非如此,所以你進入了必須預測未來的境界......但是,嘗試使用校準來處理非常週期性的外部噪音(可能是低頻率)可能很有趣,因爲比約恩羅氏說) –

+0

索尼Xperia Z2似乎已經拍攝了這個。查看http://www.androidheadlines.com/page/2。正如您已經正確指出的那樣,在決定噪音消除方案 –

0

之前加入NoiseSuppresor你必須檢查是否有可用這樣的:

if (NoiseSuppressor.isAvailable()) 
    { 
     // create and set enable 
    } 

另一個intresting一點是AcousticEchoCanceler

音頻延遲應該因爲奇巧固定。看看thisthis