необходимо понять, как AudioRecord и AudioTrack работают для захвата и воспроизведения необработанного PCM

Я использую следующий код в потоке для захвата необработанных звуковых образцов с микрофона и воспроизведения их через динамик.

public void run(){
            short[] lin = new short[SIZE_OF_RECORD_ARRAY];
            int num = 0;
            // am = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE); // -> MOVED THESE TO init()
            // am.setMode(AudioManager.MODE_IN_COMMUNICATION);
            record.startRecording();
            track.play();
            while (passThroughMode) {
            // while (!isInterrupted()) {
                num = record.read(lin, 0, SIZE_OF_RECORD_ARRAY);
                for(i=0;i<lin.length;i++)
                    lin[i] *= WAV_SAMPLE_MULTIPLICATION_FACTOR; 
                track.write(lin, 0, num);
            }
            // /*
            record.stop();
            track.stop();
            record.release();
            track.release();
            // */
        }  

где record — это AudioRecord, а track — это Audiotrack. Мне нужно знать подробно (и, если возможно, в упрощенном виде), как AudioRecord сохраняет данные PCM, а AudioTrack воспроизводит данные PCM. Вот как я понял это до сих пор:

введите здесь описание изображения

Поскольку цикл while() выполняется непрерывно, record получает количество выборок SIZE_OF_RECORD_ARRAY (которое на данный момент равно 1024), как показано на рисунке. Образцы сохраняются последовательно в массиве шорт lin[] (16-битные шорты, так как я использую 16-битное кодирование PCM). Это сделано record.read(). Затем track.write() помещает эти сэмплы в динамик, который воспроизводится оборудованием. Это правильно или я что-то пропустил здесь?


person user13267    schedule 21.08.2013    source источник


Ответы (1)


Что касается того, как сэмплы располагаются в памяти; это просто массивы линейных аппроксимаций звуковой волны, взятые в дискретное время (как показано на вашем рисунке). В случае стерео сэмплы будут чередоваться (LRLRLRLR...).

Когда дело доходит до пути звука, вы в основном правы, хотя есть еще несколько шагов:

При записи с внутреннего микрофона (ов) у вас будут более или менее те же шаги, за исключением того, что они будут выполняться в противоположном порядке.

Обратите внимание, что некоторые из этих шагов (практически все, начиная со звукового HAL и ниже) зависят от платформы и, следовательно, могут отличаться для платформ разных поставщиков (и даже для разных платформ одного и того же поставщика).

person Michael    schedule 21.08.2013
comment
Извините, но что вы имели в виду под typically going through some kind of DSP that applies various acoustic compensation filters,? Означает ли это, что цифровое представление входа микрофона не совсем то, что на микрофоне? Он уже каким-то образом обрабатывается аппаратно? - person user13267; 21.08.2013
comment
Опять же, изменение SIZE_OF_RECORD_ARRAY , похоже, не приводит к каким-либо изменениям в выводе. Я думал, что если сделать это значение очень маленьким, это вызовет какие-то дрожания или эффекты пропуска кадров на выходе, но, похоже, это вообще ничего не делает. - person user13267; 21.08.2013
comment
Он уже каким-то образом обработан?. Правильный. Типичными фильтрами, которые будут применяться при записи звука, являются автоматическая регулировка усиления или сжатие динамического диапазона, а также шумоподавление. - person Michael; 21.08.2013
comment
Вы можете запросить у AudioRecord минимальный размер буфера, используя метод getMinBufferSize. - person Michael; 21.08.2013
comment
Пожалуйста, позвольте мне объяснить это так, как я понимаю, и, пожалуйста, поправьте меня, если я ошибаюсь. Это означает, что если я, например, записываю чистый тон, используя свое устройство Android, и в то же время записываю его на компьютер с той же частотой дискретизации и 16-битным кодированием PCM и сохраняю результат в виде файла wav, затем сравните шестнадцатеричные значения в файлах, представляющих звуковые данные из обоих файлов wav, они будут разными, потому что система Android уже применила некоторые фильтры к записи? - person user13267; 21.08.2013
comment
Я думал о реализации некоторых алгоритмов шумоподавления, которые подавляют фоновый шум, когда люди разговаривают. Но если устройство уже выполняет такие алгоритмы на аппаратном уровне, не повлияет ли это на то, как я должен выполнять свои реализации? Я реализовал такие алгоритмы на C на ПК и предварительно записал wav-файл, но я предполагаю, что до того, как я получил файл данных wav, не применялись какие-либо фильтры аппаратного уровня. Как на меня повлияют предварительно примененные фильтры, если я захочу сделать то же самое, но на андроид-устройстве? - person user13267; 21.08.2013
comment
Вполне вероятно, что вы не получите точного совпадения для записей, сделанных на двух разных устройствах. Но для этого может быть множество причин (вы должны учитывать среду, в которой вы записываете, форм-факторы устройств, тип используемого микрофона, тип АЦП и т. д.). Что касается того, как вы будете реализовывать свое приложение, я не знаю. Точная комбинация используемых фильтров и способ их настройки различаются для разных продуктов, поскольку их акустические свойства различаются (по причинам, перечисленным выше). - person Michael; 21.08.2013