Android主动降噪

我正在开展一个有点雄心勃勃的项目,通过耳机或耳机在Android上实现主动降噪

我的目标是用android手机麦克风录制环境噪音,反转相位(从audiologging中拉出的简单值为简单* -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实际上已经有一个NoiseSuppressionalgorithm(你会看到它在上面注释掉了)。 我用它进行了testing,发现NoiseSuppressor没有做太多的工作来消除不断的音调,这导致我相信它实际上只是在非人声频率下执行带通滤波器。

所以,我的问题是:

1)上述代码通过耳机播放从话筒logging大约需要250-500ms。 这个延迟很糟糕,减less它会很好。 任何build议,将不胜感激。

2)不pipe延时有多紧,我的理解是回放波形将具有相对于实际环境噪声波形的相位偏移。 这表明我需要执行某种波形匹配来计算这个偏移量并进行补偿。 关于如何计算的思考?

3)当涉及补偿延迟,这将是什么样子? 每个周期都会有一些短路,所以30毫秒或250毫秒的延迟会是什么样子?

我意识到这种方法的根本问题是手机的位置不在头上可能会引入一些错误,但我希望有一些dynamic的或固定的延迟校正,可能有可能克服它。

感谢您的任何build议。

Solutions Collecting From Web of "Android主动降噪"

即使你能对延迟做些什么,但是这是个难题,因为你不知道手机与耳朵之间的距离,还有距离不固定的情况(用户会移动手机),加上每个耳朵上都没有麦克风的事实(所以即使你有零延迟,你也不能知道在一个耳朵上会有什么波动)

话虽如此,你也许可以做一些可以取消高度周期性的波形。 所有你可以做的事情是允许用户手动调整每个耳朵的时间延迟 – 因为你的耳朵本身没有麦克风,所以在你的代码中没有办法知道你是在让问题变得更好还是更糟。

在添加一个NoiseSuppresor之前,你必须检查是否有可用的,如:

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

另一个有趣的地方是AcousticEchoCanceler

自KitKat以来,audio延迟应该是固定的。 看看这个和这个 。