我正在进行一个相当有雄心的项目,旨在实现安卓系统上耳塞或者耳机的主动降噪。
我的目标是使用安卓手机麦克风记录环境噪声,对相应的音频数据进行相位反转(从 Audio Record 中获取的 short-value 加一个简单的 *-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) 在补偿延迟方面,它会是什么样子?我每个周期都有一组shorts数据,那么30ms或250ms的延迟会是什么样子?
我知道这种方法的基本问题是手机位置不在头旁边可能会引入一些误差,但我希望通过一些动态或固定的延迟校正来克服它。
感谢您提出的任何建议。