Эхоподавление WebRTC на Android. Слишком маленький буфер

У меня возникла проблема при попытке сделать эхоподавление на Android с помощью WebRTC. Я в основном слежу за проектом, размещенным здесь, но я пытаюсь осуществлять прямую трансляцию с удаленного устройства.

/* Prepare AEC */
    MobileAEC aecm = new MobileAEC(null);
    aecm.setAecmMode(MobileAEC.AggressiveMode.MILD)
            .prepare();
         /*Get Minimum Buffer Size */
    int minBufSize = AudioRecord.getMinBufferSize(HBConstants.SAMPLE_RATE,
            AudioFormat.CHANNEL_CONFIGURATION_STEREO,
            AudioFormat.ENCODING_PCM_16BIT) ;
    int audioLength=minBufSize/2;
    byte[] buf = new byte[minBufSize];

    short[] audioBuffer = new short[audioLength];
    short[] aecOut = new short[audioLength];


/*Prepare Audio Track */
    AudioTrack speaker = new AudioTrack(AudioManager.STREAM_MUSIC,
            HBConstants.SAMPLE_RATE,
            AudioFormat.CHANNEL_OUT_MONO,
            AudioFormat.ENCODING_PCM_16BIT, audioLength,
            AudioTrack.MODE_STREAM);
    speaker.play();
    isRunning = true;

    /*Loop around and read incoming network buffer.  PlayerQueue is a read LinkedBlockingQueue set elsewhere containing incoming network data */
    while (isRunning) {
        try {
            buf = playerQueue.take();

            /* Convert to short buffer and send to aecm*/
            ByteBuffer.wrap(buf).order(ByteOrder.nativeOrder())
                .asShortBuffer().get(audioBuffer);

            aecm.farendBuffer(audioBuffer, audioLength);
            aecm.echoCancellation(audioBuffer, null, aecOut,
                    (short) (audioLength), (short) 10);
/*Send output to speeker */
            speaker.write(aecOut, 0, audioLength);

        } catch (Exception ie) {

        }

        try {
            Thread.sleep(5);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
        }

    }

Когда я делаю это, я получаю это исключение:

12-23 17:31:11.290: W/System.err(8717): java.lang.Exception: setFarendBuffer() failed due to invalid arguments.
12-23 17:31:11.290: W/System.err(8717):     at com.android.webrtc.audio.MobileAEC.farendBuffer(MobileAEC.java:204)
12-23 17:31:11.290: W/System.err(8717):     at com.example.twodottwo.PlayerThread.run(PlayerThread.java:62)
12-23 17:31:11.290: W/System.err(8717):     at java.lang.Thread.run(Thread.java:841)

Теперь я немного покопался в коде и обнаружил, что сэмплер будет принимать только 80 или 160 сэмплов за раз. Чтобы компенсировать это, я пытался получить только 160 выборок за раз, но это меньше минимального размера буфера в объекте AudioRecord и выдает ошибку.

Таким образом, чтобы обойти это, я также попробовал этот код и установил очередь, чтобы доставлять только максимум 320 байтов за раз (так как мы используем 2 байта для краткости):

ShortBuffer sb = ShortBuffer.allocate(audioLength);
int samples = audioLength / 160;
while(i < samples) {
    buf = playerQueue.take();
    ByteBuffer.wrap(buf).order(ByteOrder.nativeOrder()).asShortBuffer().get(audioBuffer);
    aecm.farendBuffer(audioBuffer, 160);
    aecm.echoCancellation(audioBuffer, null, aecOut, (short) (160), (short) 10);
    sb.put(aecOut);
    i ++;
}
speaker.write(sb.array(), 0, audioLength);

Теперь это должно буферизовать каждый массив из 160 элементов и передать его в библиотеку WebRtc, чтобы выполнить эхо-команду. Кажется, он просто производит случайный шум. Я попытался также изменить порядок результирующего массива, но все равно производит случайный шум.

Есть ли способ разделить образец звука и заставить его звучать как оригинал так, как нравится WebRTC? или есть способ заставить WebRtc принимать больше образцов одновременно? Я думаю, что либо было бы хорошо, но на данный момент я немного застрял.

0 ответов

Другие вопросы по тегам