Ответ 1
Я однажды реализовал функциональные возможности, которые вы используете на телефоне на платформе Qualcomm APQ8064 (которая, похоже, почти та же платформа, что и на вашем целевом устройстве). Ниже приведено резюме того, что я могу вспомнить из этого, так как у меня больше нет доступа к написанному мной коду или к среде, где я могу легко выполнять такие модификации. Поэтому, если этот ответ читается как беспорядок фрагментарных воспоминаний, это потому, что это именно то, что есть.
Эта информация может также применяться более или менее к другим платформам Qualcomm (например, MSM8960 или MSM8974), но, скорее всего, она будет совершенно бесполезной для платформ других производителей (NVidia Tegra, Samsung Exynos, TI OMAP и т.д.).
Краткое примечание. Метод, который я использовал, означает, что звук, который получает приложение для записи, прошел через управление микшированием/громкостью в мультимедийной системе Android и/или платформе мультимедиа DSP. Поэтому, если вы играете что-то с объемом 75%, записываете его, а затем воспроизводите запись на 75% громкости, это может показаться довольно тихим. Если вы хотите получить необработанные данные PCM (после декодирования, но до смешивания/регулировки громкости), вам придется изучить другой подход, например. настраивая AudioFlinger
, но это не то, что я пробовал или могу предоставить информацию.
Несколько интересных мест:
Звуковые драйверы платформы. В частности, файл msm-pcm-routing.c.
Файл настроек ALSA UCM (Use-Case Manager). Это всего лишь пример файла настроек UCM. Существует много вариантов этих файлов в зависимости от используемой точной платформы, поэтому у вас может быть несколько другое имя (хотя оно должно начинаться с snd_soc_msm_
), и его содержимое, вероятно, также будет немного отличаться от того, с которым я связан.
ПРИМЕЧАНИЕ для Kitkat и более поздних версий: Файлы настроек UCM использовались на Jellybean (и, возможно, ICS). Я понимаю, что эти настройки были перенесены в файл с именем mixer_paths.xml
на Kitkat. Содержимое практически одинаково, только в другом формате.
Код аудио HAL. ALCA UCM присутствует в libalsa-intf
, а код AudioHardware
/AudioPolicyManager
/ALSADevice
присутствует в audio-alsa
. Обратите внимание, что этот код предназначен для Jellybean, так как это последняя версия, с которой я знаком. Структура каталогов (и, возможно, некоторые из файлов/классов) отличается от Kitkat.
Если вы откроете файл настроек UCM и выполните поиск "HiFiPROXY Rx"
, вы найдете что-то вроде этого:
SectionVerb
Name "HiFiPROXY Rx"
EnableSequence
'AFE_PCM_RX Audio Mixer MultiMedia1':1:1
EndSequence
DisableSequence
'AFE_PCM_RX Audio Mixer MultiMedia1':1:0
EndSequence
# ALSA PCMs
CapturePCM 0
PlaybackPCM 0
EndSection
Это определяет глагол (по существу, основу использования аудио файла, а также модификаторы, которые могут применяться поверх глаголов для таких вещей, как одновременное воспроизведение и запись) с именем "HiFiPROXY Rx"
(прокрутка HiFi
используется для большинства глаголов не-голосового вызова, PROXY
относится к используемому аудиоустройству, а Rx
означает вывод) и указывает, какие ALSA-элементы управления должны записывать и что писать для них, когда использование файлу следует включить/отключить. Наконец, он перечисляет устройства воспроизведения/записи ALSA PCM для использования в этом прецеденте. Например, PlaybackPCM 0
означает, что должно использоваться устройство воспроизведения 0 (предполагается, что карта ALSA является той, которая представляет встроенный аппаратный кодек, который обычно является карточкой 0). Эти глаголы выбираются аудио HAL на основе прецедента (воспроизведение музыки, голосовой вызов, запись,...), какие аксессуары вы подключили и т.д.
Если вы посмотрите "AFE_PCM_RX Audio Mixer"
в msm_qdsp6_widgets table в msm-pcm-routing.c
, вы увидите, что это относится к список элементов управления микшера с именем afe_pcm_rx_mixer_controls
, который выглядит следующим образом:
static const struct snd_kcontrol_new afe_pcm_rx_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_AFE_PCM_RX,
MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_AFE_PCM_RX,
... and so on...
В этом списке DAI переднего конца вам разрешено подключаться к заднему концу DAI (AFE_PCM_RX
). Чтобы получить представление о том, как они относятся друг к другу, см. эти диаграммы. AFE_PCM_RX
и AFE_PCM_TX
- это пара DAI на некоторых платформах Qualcomm, которые реализуют своего рода фиктивное/прокси-устройство. Что вы делаете, это передать аудио в AFE_PCM_RX
, который затем обрабатывается мультимедийным DSP (QDSP), а затем вы можете прочитать его обратно через AFE_PCM_TX
. Это используется для реализации маршрутизации аудио и аудио USB и Wi-Fi, а также A2DP IIRC.
Вернемся к строке AFE_PCM_RX Audio Mixer MultiMedia1
: это говорит о том, что вы кормите MultiMedia1
в AFE_PCM_RX Audio Mixer
. MultiMedia1
используется для нормального воспроизведения/записи и соответствует pcmC0D0
(вы должны иметь возможность отображать устройства на вашем телефоне с помощью adb shell cat /proc/asound/devices
). Существуют и другие DAI переднего конца, такие как MultiMedia3
и MultiMedia5
, которые используются в особых случаях, таких как воспроизведение с низкой задержкой и воспроизведение звука с низким энергопотреблением.
Когда вы подаете MultiMedia1
на AFE_PCM_RX Audio Mixer
все, что вы пишете на устройство воспроизведения 0 на карточке 0, будет отправлено в DAI AFE_PCM_RX
. Чтобы прочитать его, вы можете настроить глагол UCM, который делает что-то вроде 'MultiMedia1 Mixer AFE_PCM_TX':1:1
, а затем вы читаете от pcmC0D0c
(который должен быть устройством захвата ALSA по умолчанию).
Простым тестом было бы вытащить файл настроек UCM с вашего телефона (он должен быть расположен где-то под /system/etc/
) и изменить текст "HiFi"
verb EnableSequence
следующим образом:
'AFE_PCM_RX Audio Mixer MultiMedia1':1:1
'AFE_PCM_RX Audio Mixer MultiMedia3':1:1
'AFE_PCM_RX Audio Mixer MultiMedia5':1:1
(и аналогично в DisableSequence
, но с :1:0
в конце каждой строки).
Затем перейдите к модификатору "Capture Music"
(это слабо названный модификатор для нормальной записи) и измените SLIM_0_TX
на AFE_PCM_TX
.
Скопируйте измененный файл настроек UCM обратно на телефон (требуется разрешение root) и перезагрузите телефон. Затем запустите некоторое воспроизведение (подключите проводную гарнитуру/наушники и отключите звуки касания, чтобы глагол с низкой задержкой не был выбран) и начните запись с AudioSource.MIC
. Затем проверьте запись и посмотрите, удалось ли записать звуковой сигнал воспроизведения. Если нет, то, возможно, был выбран слабый звуковой глагол, и вам придется изменить глагол "HiFi Low Power"
аналогично тому, что вы сделали с глаголом "HiFi"
. Это поможет вам, если у вас есть все отладочные отпечатки, включенные в аудио HAL (т.е. uncomment #define LOG_NDEBUG 0
во всех файлах cpp, где вы можете их найти), чтобы вы могли видеть, какие UCM-глаголы/модификаторы выбираются.
Модификация, описанная выше, немного утомительна, так как вы должны охватить все DAI-интерфейсы MultiMedia
для всех соответствующих глаголов и модификаторов.
IIRC, я смог упростить это только в одной строке на глагол/модификатор:
'AFE_PCM_RX Port Mixer SLIM_0_RX':1:1
Если вы посмотрите на глаголы "HiFi
", "HiFi Low Power
", "HiFi Lowlatency"
, вы увидите, что все они используют DAI конца SLIMBUS_0_RX
, поэтому я пользуюсь этим, используя AFE_PCM_RX Port Mixer
, который позволяет мне установить соединение с DAI заднего конца на другой DAI задней части. Если вы посмотрите таблицы afe_pcm_rx_port_mixer_controls
и intercon
в msm-pcm-routing.c
, вы заметите, что нет записи SLIM_0_RX
для AFE_PCM_RX Port Mixer
, поэтому вам придется добавить их сами (это просто вопрос копирования- вставка некоторых существующих строк и изменение имен).
Некоторые другие изменения, которые вам, вероятно, придется сделать:
-
В frameworks/base и frameworks/av (например,
AudioManager
,AudioService
,AudioSystem
) вам нужно будет добавить новую константуAudioSource
и убедиться, что она распознается во всех необходимых местах. -
В файле настроек UCM вам нужно добавить несколько новых глаголов/модификаторов, чтобы правильно настроить элементы управления ALSA, когда используется ваш новый
AudioSource
. -
В аудио HAL вам придется внести некоторые изменения, чтобы ваши новые глаголы/модификаторы выбирались при использовании нового
AudioSource
. Обратите внимание, что существует базовый классAudioPolicyManagerALSA
, называемыйAudioPolicyManagerBase
, который также может потребоваться изменить (он расположенный в другом месте в исходном дереве).