AudioRecord и AudioTrack эхо - PullRequest
       38

AudioRecord и AudioTrack эхо

1 голос
/ 18 июля 2011

Я передаю звук с микрофона между двумя устройствами, все работает, но у меня плохое эхо.

Вот что я делаю

Тема чтения

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();
    }

Я что-то не так делаю?

Ответы [ 2 ]

3 голосов
/ 19 августа 2011

Вам нужна логика эхоподавления.Вот что я сделал на своем процессоре Arm5 (WM8650) (Android 2.2), чтобы удалить эхо.

  1. Я обернул Speex JNI и вызвал процедуры обработки эха перед отправкой кадров PCM в кодировщик.Эхо не было отменено независимо от того, какие настройки Speex я пробовал.

  2. Поскольку Speex очень чувствителен к задержке между воспроизведением и кадрами эха, я создал очередь и поставил в очередь все пакеты, отправленные в AudioTrack.Размер очереди должен быть примерно равен размеру внутреннего буфера AudioTrack.Таким образом, пакет отправлялся на echo_playback примерно в то время, когда AudioTrack отправлял пакеты на звуковую карту из своего внутреннего буфера.При таком подходе задержка была удалена, но эхо все еще не было отменено

  3. Я обернул часть подавления эха WebRtc с помощью JNI и вызвал ее методы перед отправкой пакетов в кодировщик.Эхо все еще присутствовало, но библиотека, очевидно, пыталась его отменить.

  4. Я применил метод буфера, описанный в P2, и он, наконец, начал работать.Задержка должна быть скорректирована для каждого устройства, хотя.Также обратите внимание, что в WebRtc есть мобильная и полная версия эхоподавления.Полная версия существенно замедляет процессор и, вероятно, должна работать только на ARM7.Мобильная версия работает, но с более низким качеством

Надеюсь, это кому-нибудь поможет.

2 голосов
/ 24 августа 2011

Может быть так:

bytes = mmInStream.read(buffer);                    
atrack.write(buffer, 0, buffer.length);

Если буфер остается заполненным от предыдущего вызова, а новый не заполнен (поэтому bytes < buffer.length), вы повторно воспроизводите удерживаемую часть дорожки.

...