我正在两台设备之间传输麦克风音频,一切正常,但回声不好。

这是我在做什么

阅读线程

int sampleFreq = 22050;
        int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO;
        int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
        int minBuffer = 2*AudioTrack.getMinBufferSize(sampleFreq, channelConfig, audioFormat);

        AudioTrack atrack = new AudioTrack(AudioManager.STREAM_MUSIC,
                        sampleFreq,
                        channelConfig,
                        audioFormat,
                        minBuffer,
                        AudioTrack.MODE_STREAM);
        atrack.play();

        byte[] buffer = new byte[minBuffer];
        while (true) {
            try {
                // Read from the InputStream
                bytes = mmInStream.read(buffer);
                atrack.write(buffer, 0, buffer.length);
                atrack.flush();
            } catch (IOException e) {
                Log.e(TAG, "disconnected", e);
                break;
            }
        }

这里的录音线程
int sampleRate = 22050;
    int channelMode = AudioFormat.CHANNEL_CONFIGURATION_MONO;
    int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
    int buffersize = 2*AudioTrack.getMinBufferSize(sampleRate, channelMode, audioFormat);

    AudioRecord arec = new AudioRecord(MediaRecorder.AudioSource.MIC,
            sampleRate, channelMode,
            AudioFormat.ENCODING_PCM_16BIT, buffersize);

    buffer = new byte[buffersize];
    arec.startRecording();

    while (true) {
        arec.read(buffer, 0, buffersize);
        new Thread( new Runnable(){
            @Override
            public void run() {
                try {
                    mOutputStream.write(buffer);
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }).start();
    }

难道我做错了什么?

最佳答案

您需要回声消除逻辑。这是我在Arm5(WM8650)处理器(Android 2.2)上执行的操作,以删除回声。

  • 在将PCM帧发送到编码器之前,我用JNI包裹了Speex,并调用了回声处理例程。无论我尝试了哪种Speex设置,都不会取消任何回声。
  • 因为Speex对回放和回声帧之间的延迟非常敏感,所以我实现了一个队列,并将所有发送到AudioTrack的数据包排队。队列的大小应大致等于内部AudioTrack缓冲区的大小。这种方法大约是在AudioTrack从内部缓冲区将数据包发送到声卡时,将数据包发送到echo_playback的。用这种方法消除了延迟,但是回声仍然没有被消除
  • 在将数据包发送到编码器之前,我用JNI封装了WebRtc回声消除部分,并调用了其方法。回声仍然存在,但是库显然正在尝试取消它。
  • 我应用了P2中描述的缓冲技术,终于开始起作用了。但是,需要为每个设备调整延迟。还请注意,WebRtc具有回声消除的移动版和完整版。完整版会大大减慢处理器的速度,因此可能只能在ARM7上运行。移动版本有效,但质量较低

  • 我希望这会对某人有所帮助。

    09-13 11:33