Este artigo descreve algumas dicas e truques para depurar o áudio do Android.
Pia de tee
A "pia da camiseta" é um recurso de depuração do AudioFlinger, disponível apenas em builds personalizados, para reter um fragmento curto de áudio recente para análise posterior. Isso permite comparar o que foi realmente reproduzido ou gravado em relação ao que era esperado.
Por questões de privacidade, o coletor de tee é desativado por padrão no tempo de compilação e no ambiente de execução. Para usar o coletor de tee, você precisará ativá-lo recompilando, e também definindo uma propriedade. Lembre-se de desativar esse recurso depuração concluída; o coletor de tee não deve ficar ativado em builds de produção.
As instruções nesta seção são para o Android 7.x e versões mais recentes. Para Android
5.x e 6.x, substitua /data/misc/audioserver
por
/data/misc/media
. Além disso, é necessário usar um parâmetro userdebug
eng. Se você usar um build userdebug, desative a verity com:
adb root && adb disable-verity && adb reboot
Configuração durante a compilação
cd frameworks/av/services/audioflinger
- Edite
Configuration.h
. - Remova a marca de comentário de
#define TEE_SINK
. - Recrie
libaudioflinger.so
. adb root
adb remount
- Envie ou sincronize o novo
libaudioflinger.so
com o/system/lib
do dispositivo.
Configuração do ambiente de execução
adb shell getprop | grep ro.debuggable
Confirme se a saída é:[ro.debuggable]: [1]
adb shell
ls -ld /data/misc/audioserver
Confirme se a saída é:
drwx------ media media ... media
Se o diretório não existir, crie-o da seguinte maneira:
mkdir /data/misc/audioserver
chown media:media /data/misc/audioserver
echo af.tee=# > /data/local.prop
Em que o valoraf.tee
é um número descrito abaixo.chmod 644 /data/local.prop
reboot
Valores para a propriedade af.tee
O valor de af.tee
é um número entre 0 e 7, expressando
a soma de vários bits, um por atributo.
Confira o código em AudioFlinger::AudioFlinger()
no app AudioFlinger.cpp
para uma explicação de cada bit, mas brevemente:
- 1 = entrada
- 2 = saída do FastMixer
- 4 = registro de áudio e faixa de áudio por faixa
Ainda não há nada para buffer profundo ou mixer normal, mas você pode obter resultados semelhantes usando "4".
Testar e adquirir dados
- Execute o teste de áudio.
adb shell dumpsys media.audio_flinger
- Procure uma linha no resultado de
dumpsys
como esta:
tee copied to /data/misc/audioserver/20131010101147_2.wav
É um arquivo PCM .wav. - Em seguida, selecione
adb pull
todos os arquivos/data/misc/audioserver/*.wav
de interesse. observe que os nomes de arquivo dump específicos da faixa não aparecemdumpsys
saída, mas ainda serão salvos em/data/misc/audioserver
após a interdição da faixa. - Verifique os arquivos dump para verificar a privacidade antes de compartilhar com outras pessoas.
Sugestões
Use estas ideias para ter resultados mais úteis:
- Desative os sons de toque e os cliques nas teclas para reduzir as interrupções no resultado do teste.
- Maximize todos os volumes.
- Desativar apps que emitem som ou gravam usando o microfone caso não sejam interessantes para o seu teste.
- Os despejos específicos da faixa são salvos apenas quando a faixa é fechada. pode ser necessário forçar o fechamento do app para despejar os dados específicos da faixa.
- Faça o
dumpsys
imediatamente após o teste. há uma quantidade limitada de espaço de gravação disponível. - Para não perder seus arquivos dump, fazer o upload deles para o host periodicamente. Apenas um número limitado de arquivos dump é preservado. os despejos antigos são removidos depois que esse limite é atingido.
Restaurar
Como mencionado acima, o recurso de coletor de tee não deve ficar ativado. Restaure o build e o dispositivo da seguinte maneira:
- Reverta as mudanças do código-fonte para
Configuration.h
. - Recrie
libaudioflinger.so
. - Enviar ou sincronizar o
libaudioflinger.so
restaurado ao/system/lib
do dispositivo. adb shell
rm /data/local.prop
rm /data/misc/audioserver/*.wav
reboot
media.log
Macros ALOGx
A API de geração de registros da linguagem Java padrão no SDK do Android é android.util.Log:
A API da linguagem C correspondente no Android NDK é
__android_log_print
declarado em <android/log.h>
.
Dentro da parte nativa do framework do Android,
preferem macros chamadas ALOGE
, ALOGW
,
ALOGI
, ALOGV
etc. Elas são declaradas em
<utils/Log.h>
. Além disso, para os fins deste artigo,
Vamos nos referir a eles coletivamente como ALOGx
.
Todas essas APIs são fáceis de usar e bem compreendidas, por isso são abrangentes
em toda a plataforma Android. Mais especificamente, mediaserver
.
que inclui o servidor de som AudioFlinger, usa
ALOGx
bastante.
No entanto, existem algumas limitações para ALOGx
e amigos:
-
Eles são suscetíveis a "spam de registros": o buffer de registros é um recurso compartilhado
para que ele possa transbordar facilmente devido a entradas de registro não relacionadas, resultando em
informações que você perdeu. A variante
ALOGV
está desativada em o tempo de compilação por padrão. Mas, claro, isso pode resultar em spam de registro caso esteja ativada. -
As chamadas subjacentes do sistema de kernel podem ser bloqueadas, possivelmente resultando em
a inversão de prioridades e, consequentemente, as perturbações de medição e
equívocos. Isso é de
preocupação especial com linhas de execução urgentes, como
FastMixer
eFastCapture
. - Se um registro específico estiver desativado para reduzir o spam de registros, então todas as informações que teriam sido capturadas por esse registro serão perdidas. Não é possível ativar um registro específico retroativamente, depois, fica claro que o registro seria interessante.
NBLOG, media.log e MediaLogService
As APIs NBLOG
e o media.log
associado
processo e MediaLogService
serviço juntos formam um novo sistema de geração de registros para mídia e são especificamente
criada para resolver os problemas acima. Usaremos vagamente o termo
“media.log” para se referir aos três, mas, falando estritamente, NBLOG
é o
API C++ Logging, media.log
é um nome de processo do Linux e MediaLogService
é um serviço de vinculação do Android para examinar registros.
Uma "linha do tempo" de media.log
é uma série
de entradas de registro cuja ordem relativa é preservada.
Por convenção, cada linha de execução precisa usar a própria linha do tempo.
Vantagens
Os benefícios do sistema media.log
são:
- Não envia spam ao registro principal, a menos e até que seja necessário.
- Pode ser examinado mesmo quando o
mediaserver
falha ou trava. - Não bloqueia por linha do tempo.
- Oferece menos interrupções ao desempenho. É claro que nenhuma forma de geração de registros é completamente não intrusiva.
Arquitetura
O diagrama abaixo mostra a relação do processo mediaserver
e o processo init
, antes da introdução de media.log
:
Pontos importantes:
init
bifurca e executamediaserver
.- O
init
detecta a morte demediaserver
e faz uma nova bifurcação conforme necessário. - A geração de registros
ALOGx
não é exibida.
O diagrama abaixo mostra a nova relação dos componentes,
após a adição de media.log
à arquitetura:
Mudanças importantes:
-
Os clientes usam a API
NBLOG
para criar entradas de registro e anexá-las ao um buffer circular na memória compartilhada. -
O
MediaLogService
pode despejar o conteúdo do buffer circular a qualquer momento. -
O buffer circular é projetado de modo que qualquer corrupção do
a memória compartilhada não falhará
MediaLogService
, e ainda poderá para despejar o máximo do buffer não afetado pela corrupção. - O buffer circular não bloqueia nem bloqueia a gravação novas entradas e a leitura de entradas existentes.
- Nenhuma chamada do sistema do kernel é necessária para gravar ou ler no buffer circular (exceto as marcações de tempo opcionais).
Onde usar
A partir do Android 4.4, há apenas alguns pontos de registro no AudioFlinger
que usam o sistema media.log
. Embora as novas APIs não sejam tão
fáceis de usar como ALOGx
, mas também não são extremamente difíceis.
Incentivamos você a conhecer o novo sistema de geração de registros
em ocasiões em que é indispensável.
Em particular, é recomendado para encadeamentos do AudioFlinger que precisam
são executadas com frequência, periodicamente e sem bloqueios, como
Linhas de execução FastMixer
e FastCapture
.
Como usar
Adicionar registros
Primeiro, você precisa adicionar registros ao seu código.
Nas linhas de execução FastMixer
e FastCapture
, use um código como este:
logWriter->log("string"); logWriter->logf("format", parameters); logWriter->logTimestamp();
Como a linha do tempo NBLog
é usada apenas pelas APIs FastMixer
e
FastCapture
linhas de execução,
não há necessidade de exclusão mútua.
Em outras linhas de execução do AudioFlinger, use mNBLogWriter
:
mNBLogWriter->log("string"); mNBLogWriter->logf("format", parameters); mNBLogWriter->logTimestamp();
Para linhas de execução diferentes de FastMixer
e FastCapture
,
a linha do tempo NBLog
da linha de execução pode ser usada pela própria linha de execução e
por operações de vinculação. NBLog::Writer
não fornece nenhum
exclusão mútua implícita por cronograma. Portanto, verifique se todos os registros ocorrem
em um contexto em que o mutex mLock
da linha de execução é mantido.
Depois de adicionar os registros, recrie o AudioFlinger.
Atenção:
É necessário ter uma linha do tempo NBLog::Writer
separada por linha de execução,
para garantir a segurança da linha de execução, uma vez que as linhas do tempo omitem exclusões múltiplas por design. Se você
quiser que mais de uma linha de execução use a mesma linha do tempo, é possível proteger com uma
exclusões múltiplas existentes (conforme descrito acima para mLock
). Ou pode
use o wrapper NBLog::LockedWriter
em vez de NBLog::Writer
.
No entanto, isso invalida um dos principais benefícios da API: a função não bloqueadora
do seu modelo.
A API NBLog
completa está em frameworks/av/include/media/nbaio/NBLog.h
.
Ativar media.log
media.log
está desativado por padrão. Ele só fica ativo quando a propriedade
ro.test_harness
é 1
. Para ativar, faça o seguinte:
adb root
adb shell
echo ro.test_harness=1 > /data/local.prop
chmod 644 /data/local.prop
reboot
A conexão é perdida durante a reinicialização, portanto:
adb shell
ps media
agora vai mostrar dois processos:
- media.log
- servidor de mídia
Anote o ID do processo mediaserver
para mais tarde.
Mostrar as linhas do tempo
É possível solicitar um despejo de registros manualmente a qualquer momento. Este comando mostra os registros de todas as linhas do tempo ativas e recentes e os limpa:
dumpsys media.log
Por design, os cronogramas são independentes, e não é fácil mesclar linhas de tempo.
Recuperar registros após a interrupção do mediaserver
Agora tente encerrar o processo mediaserver
: kill -9 #
, em que # é
o ID do processo que você anotou anteriormente. Um despejo de media.log
vai aparecer.
na logcat
principal, mostrando todos os registros que levaram à falha.
dumpsys media.log