8

私は、イヤフォンまたはヘッドフォンを装着した 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) 上記のコードは、マイクの録音からヘッドフォンでの再生まで約 250 ~ 500 ミリ秒かかります。この遅延はひどいものであり、それを減らすことは素晴らしいことです. そこにどんな提案もいただければ幸いです。

2) レイテンシーがどれほどタイトであっても、再生波形には実際の周囲ノイズ波形からの位相オフセットがあることを理解しています。これは、このオフセットを計算して補正するために、何らかの波形マッチングを実行する必要があることを示唆しています。それがどのように計算されるかについての考えは?

3) レイテンシーの補正に関しては、どのようになりますか? サイクルごとに一連のショートが発生するので、30 ミリ秒または 250 ミリ秒のレイテンシはどのように見えるでしょうか?

このアプローチの根本的な問題は、電話の位置が頭の横にないために何らかのエラーが発生する可能性があることを認識していますが、動的または固定の遅延補正でそれを克服できる可能性があることを願っています.

提案をありがとう。

4

1 に答える 1