Как избежать автоматической регулировки усиления с помощью AudioRecord?

Как я могу делать аудиозаписи с помощью android.media.AudioRecord без какой-либо сложной обработки сигнала, зависящей от производителя смартфона, такой как автоматическая регулировка усиления (АРУ) и/или выравнивание, шумоподавление, эхоподавление, ... только чистый сигнал микрофона?

Задний план

MediaRecorder.AudioSource предоставляет девять констант,

  • DEFAULT и MIC изначально были там,
  • VOICE_UPLINK, VOICE_DOWNLINK и VOICE_CALL добавлены в уровень API 4,
  • CAMCORDER и VOICE_RECOGNITION добавлены в API 7,
  • VOICE_COMMUNICATION добавлено в API 11,
  • REMOTE_SUBMIX добавлено в API 19, но недоступно для сторонних приложений.

Но ни один из них не работает идеально на всех смартфонах. Скорее мне самому предстоит выяснить похоже, какое устройство использует какие комбинации блоков обработки сигналов для каких MediaRecorder.AudioSource констант.

Было бы неплохо добавить десятую константу, такую ​​как PURE_MIC, на уровне API 20.

Но пока это недоступно, что я могу сделать вместо этого?


person Hartmut Pfitzinger    schedule 17.01.2013    source источник


Ответы (4)


Короткий ответ: «Ничего».

AudioSources соответствуют различным логическим устройствам ввода звука в зависимости от аксессуаров, подключенных к телефону, и текущего варианта использования, который, в свою очередь, соответствует физическим устройствам (основной встроенный микрофон, дополнительный микрофон, микрофон проводной гарнитуры и т. д.). с разными настройками.

Каждое такое сочетание физического устройства и настройки корректируется OEM-производителем в соответствии как с внешними требованиями (например, CTS, требованиями оператора и т. д.), так и с внутренними акустическими требованиями, установленными самим OEM-производителем. Этот процесс может привести к введению различных фильтров, таких как AGC, шумоподавление, выравнивание и т. д., в тракт ввода звука на уровне аппаратного кодека или мультимедийного DSP.

Хотя источник PURE_MIC может быть полезен для некоторых приложений, сегодня он недоступен.
На многих устройствах вы можете управлять такими параметрами, как усиление микрофона и, возможно, даже цепочка фильтров, используя amixer для записи в ALSA аппаратного кодека. контролирует. Тем не менее, это, очевидно, будет очень специфичным для платформы подходом, и я также подозреваю, что вы должны работать как пользователь root или аудио, чтобы иметь возможность делать это.

person Michael    schedule 17.01.2013
comment
Я бы согласился на DEFAULT, MIC, VOICE_*, но я понял, что VOICE_RECOGNITION был введен специально, чтобы избежать дополнительной обработки сигнала (которую некоторые OEM-производители явно проигнорировали). Есть ли другой способ, например. «волшебная» комбинация вызовов audioManager.setParameters? - person Hartmut Pfitzinger; 17.01.2013
comment
Я работаю с SW аудио, так что я не участвую в процессе настройки. Но я ожидаю, что в случае VOICE_RECOGNITION желателен чистый речевой сигнал (без фонового шума, обрезки и т. д.), чтобы его можно было использовать для обработки речи в текст. Поэтому я бы предположил, что по крайней мере будет использоваться шумоподавитель и АРУ/многополосный компрессор. - person Michael; 17.01.2013
comment
ASR обычно выиграет от чистого звука, поскольку он выполняет свою собственную квази-АРУ при извлечении вектора признаков и обычно обучается с шумом. В документе «Определение совместимости с Android 4.1» (7 сентября 2012 г.), раздел 5.3 четко указано: при использовании VOICE_RECOGNITION обработка шумоподавления и автоматическая регулировка усиления ДОЛЖНЫ быть отключены. Производители надеются изменить это для Android ›=4.1, тогда PURE_MIC не нужен. Но у меня есть сомнения. Итак, все же мой вопрос: есть ли другой способ? - person Hartmut Pfitzinger; 18.01.2013
comment
Вы нашли способ получить чистый звук с микрофона без какой-либо обработки? - person Anonymous Me; 29.04.2015
comment
Спустя более 2 лет после моего вопроса и еще несколько уровней API спустя, я все еще не вижу другого пути, кроме как попробовать и ошибиться. Но я все равно был бы рад, если бы кто-то мог добавить второй ответ с другим содержанием. - person Hartmut Pfitzinger; 30.04.2015

Некоторые устройства по умолчанию добавляют эффект АРУ к тракту ввода звука. Поэтому вам необходимо получить ссылку на соответствующий объект AudioEffect и принудительно отключить его.

Сначала получите объект AutomaticGainControl, связанный с аудиосеансом AudioRecord, и затем просто отключите его:

if (AutomaticGainControl.isAvailable()) {
    AutomaticGainControl agc = AutomaticGainControl.create(
            myAudioRecord.getAudioSessionId()
        );
    agc.setEnabled(false);
}
person AterLux    schedule 18.04.2016
comment
Спасибо. Я пробовал это для большого количества устройств, но безуспешно. Не могли бы вы назвать некоторые из этих устройств и версию Android, на которой работает этот метод? - person Hartmut Pfitzinger; 18.04.2016

Примечание. Большинство аудиоисточников (включая DEFAULT) обрабатывают аудиосигнал. Для записи необработанного звука выберите UNPROCESSED. Некоторые устройства не поддерживают необработанный ввод. Сначала вызовите AudioManager.getProperty("PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED"), чтобы убедиться, что он доступен. Если это не так, попробуйте вместо этого использовать VOICE_RECOGNITION, который не использует AGC или подавление шума. Вы можете использовать UNPROCESSED в качестве источника звука, даже если свойство не поддерживается, но нет гарантии, будет ли сигнал необработанным или нет в этом случае.

Ссылка на документацию Android https://developer.android.com/guide/topics/media/mediarecorder.html#example

    AudioManager audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
    if(audioManager.getProperty(AudioManager.PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED) !=null)
        mRecorder.setAudioSource(MediaRecorder.AudioSource.UNPROCESSED);
    else
        mRecorder.setAudioSource(MediaRecorder.AudioSource.VOICE_RECOGNITION);
person Arun Shankar    schedule 15.02.2017

MIC должно быть хорошо, а в остальном вам нужно знать, поддерживаются ли они.

Я сделал класс для этого:

enum class AudioSource(val audioSourceValue: Int, val minApi: Int) {
    VOICE_CALL(MediaRecorder.AudioSource.VOICE_CALL, 4), DEFAULT(MediaRecorder.AudioSource.DEFAULT, 1), MIC(MediaRecorder.AudioSource.MIC, 1),
    VOICE_COMMUNICATION(MediaRecorder.AudioSource.VOICE_COMMUNICATION, 11), CAMCORDER(MediaRecorder.AudioSource.CAMCORDER, 7),
    VOICE_RECOGNITION(MediaRecorder.AudioSource.VOICE_RECOGNITION, 7),
    VOICE_UPLINK(MediaRecorder.AudioSource.VOICE_UPLINK, 4), VOICE_DOWNLINK(MediaRecorder.AudioSource.VOICE_DOWNLINK, 4),
    @TargetApi(Build.VERSION_CODES.KITKAT)
    REMOTE_SUBMIX(MediaRecorder.AudioSource.REMOTE_SUBMIX, 19),
    @TargetApi(Build.VERSION_CODES.N)
    UNPROCESSED(MediaRecorder.AudioSource.UNPROCESSED, 24);

    fun isSupported(context: Context): Boolean =
            when {
                Build.VERSION.SDK_INT < minApi -> false
                this != UNPROCESSED -> true
                else -> {
                    val audioManager: AudioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
                    Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && "true" == audioManager.getProperty(AudioManager.PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED)
                }
            }

    companion object {
        fun getAllSupportedValues(context: Context): ArrayList<AudioSource> {
            val values = AudioSource.values()
            val result = ArrayList<AudioSource>(values.size)
            for (value in values)
                if (value.isSupported(context))
                    result.add(value)
            return result
        }
    }

}
person android developer    schedule 28.02.2019