Áudio digital USB

Este artigo analisa o suporte do Android para áudio digital USB e protocolos com base em USB relacionados.

Público-alvo

O público-alvo deste artigo são OEMs de dispositivos Android, fornecedores de SoC, fornecedores de periféricos de áudio USB, desenvolvedores de aplicativos de áudio avançados e outros que buscam entender em detalhes o funcionamento interno do áudio digital USB no Android.

Os usuários finais de dispositivos Nexus devem consultar o artigo Gravar e reproduzir áudio usando o modo host USB na Central de Ajuda do Nexus. Embora este artigo não seja voltado para usuários finais, alguns consumidores de áudio podem encontrar partes de interesse.

Visão geral do USB

O Universal Serial Bus (USB) é descrito informalmente no artigo da Wikipedia USB, e é formalmente definido pelos padrões publicados pelo USB Implementers Forum, Inc. Para sua conveniência, resumimos os principais conceitos do USB aqui, mas os padrões são a referência oficial.

Conceitos e terminologia básicos

O USB é um barramento com um único iniciador de operações de transferência de dados, chamado de host. O host se comunica com periféricos pelo barramento.

Observação:os termos dispositivo e acessório são sinônimos comuns de periférico. Evitamos esses termos aqui, porque eles podem ser confundidos com o dispositivo do Android ou o conceito específico do Android chamado modo acessório.

Uma função crítica do host é a enumeração: o processo de detectar quais periféricos estão conectados ao barramento e consultar as propriedades deles expressas por descrições.

Um periférico pode ser um objeto físico, mas implementar várias funções lógicas. Por exemplo, um periférico de webcam pode ter uma função de câmera e uma função de áudio de microfone.

Cada função periférica tem uma interface que define o protocolo para se comunicar com essa função.

O host se comunica com um periférico por um pipe para um endpoint, uma fonte de dados ou um destino fornecido por uma das funções do periférico.

Há dois tipos de pipes: message e stream. Um pipe de mensagem é usado para controle e status bidirecionais. Um tubo de fluxo é usado para transferência de dados unidirecional.

O host inicia todas as transferências de dados. Portanto, os termos entrada e saída são expressos em relação ao host. Uma operação de entrada transfere dados do periférico para o host, enquanto uma operação de saída transfere dados do host para o periférico.

Há três modos principais de transferência de dados: interrupto, em massa e isocrono. Vamos falar mais sobre o modo isócrono no contexto do áudio.

O periférico pode ter terminais que se conectam ao mundo externo, além do próprio periférico. Dessa forma, o periférico serve para traduzir entre o protocolo USB e os sinais do "mundo real". Os terminais são objetos lógicos da função.

Modos USB do Android

Modo de desenvolvimento

O modo de desenvolvimento está presente desde a versão inicial do Android. O dispositivo Android aparece como um periférico USB para um PC host com um sistema operacional de computador, como Linux, Mac OS X ou Windows. A única função periférica visível é o Android Fastboot ou a Android Debug Bridge (adb). Os protocolos fastboot e adb são sobrepostos ao modo de transferência de dados em massa do USB.

Modo host

O modo host foi introduzido no Android 3.1 (nível 12 da API).

Como o dispositivo Android precisa atuar como host e a maioria dos dispositivos Android inclui um conector micro-USB que não permite a operação do host, um adaptador on-the-go (OTG) como este geralmente é necessário:

OTG

Figura 1. Adaptador OTG

Um dispositivo Android pode não fornecer energia suficiente para operar um periférico específico, dependendo da quantidade de energia necessária e da capacidade do dispositivo Android de fornecer energia. Mesmo que a energia adequada esteja disponível, a carga da bateria do dispositivo Android pode ser significativamente reduzida. Para essas situações, use um hub alimentado, como este:

Hub com energia

Figura 2. Hub com alimentação

Modo de acessório

O modo de acessório foi introduzido no Android 3.1 (nível 12 da API) e portado para o Android 2.3.4. Nesse modo, o dispositivo Android funciona como um periférico USB, sob o controle de outro dispositivo, como uma base que serve como host. A diferença entre o modo de desenvolvimento e o modo de acessório é que outras funções USB ficam visíveis para o host, além do adb. O dispositivo Android começa no modo de desenvolvimento e, em seguida, faz a transição para o modo de acessório por meio de um processo de renegociação.

O modo acessório foi estendido com recursos adicionais no Android 4.1, em particular o áudio descrito abaixo.

Áudio USB

Classes USB

Cada função periférica tem um documento de classe de dispositivo associado que especifica o protocolo padrão para essa função. Isso permite que hosts compatíveis com a classe e funções periféricas interajam sem conhecimento detalhado do funcionamento de cada um. A conformidade de classe é essencial se o host e o periférico forem fornecidos por entidades diferentes.

O termo sem driver é um sinônimo comum de compatível com a classe, indicando que é possível usar os recursos padrão de um periférico sem exigir a instalação de um driver específico do sistema operacional. É possível presumir que um periférico anunciado como "sem necessidade de driver" para os principais sistemas operacionais de computador será compatível com a classe, embora possa haver exceções.

Classe de áudio USB

Aqui, nos preocupamos apenas com os periféricos que implementam funções de áudio e, portanto, aderem à classe de dispositivo de áudio. Há duas edições da especificação de classe de áudio USB: classe 1 (UAC1) e 2 (UAC2).

Comparação com outras classes

O USB inclui muitas outras classes de dispositivos, algumas das quais podem ser confundidas com a classe de áudio. A classe de armazenamento em massa (MSC) é usada para acesso orientado a setores à mídia, enquanto o protocolo de transferência de mídia (MTP) é para acesso de arquivo completo à mídia. Tanto o MSC quanto o MTP podem ser usados para transferir arquivos de áudio, mas apenas a classe de áudio USB é adequada para streaming em tempo real.

Terminais de áudio

Os terminais de um periférico de áudio geralmente são analógicos. O sinal analógico apresentado no terminal de entrada do periférico é convertido em digital por um conversor analógico-digital (ADC, na sigla em inglês) e é transmitido pelo protocolo USB para ser consumido pelo host. O ADC é uma fonte de dados para o host. Da mesma forma, o host envia um sinal de áudio digital pelo protocolo USB para o periférico, em que um conversor digital-analógico (DAC, na sigla em inglês) converte e apresenta para um terminal de saída analógica. O DAC é um sink para o host.

Canais

Um periférico com função de áudio pode incluir um terminal de origem, um terminal de destino ou ambos. Cada direção pode ter um canal (mono), dois canais (estéreo) ou mais. Os periféricos com mais de dois canais são chamados de multicanais. É comum interpretar um stream estéreo como composto de canais esquerdo e direito e, por extensão, interpretar um stream multicanal como tendo localizações espaciais correspondentes a cada canal. No entanto, também é bastante apropriado (especialmente para áudio USB, mais do que HDMI) não atribuir nenhum significado espacial padrão a cada canal. Nesse caso, cabe ao aplicativo e ao usuário definir como cada canal é usado. Por exemplo, uma stream de entrada USB de quatro canais pode ter os três primeiros canais conectados a vários microfones em uma sala, e o canal final recebe a entrada de uma rádio AM.

Modo de transferência isócrona

O áudio USB usa o modo de transferência isocrono para as características em tempo real, à custa da recuperação de erros. No modo isocrônico, a largura de banda é garantida e os erros de transmissão de dados são detectados usando uma verificação de redundância cíclica (CRC). Mas não há confirmação de pacote nem retransmissão em caso de erro.

As transmissões isocrônicas ocorrem em cada período de início do frame (SOF). O período de SOF é de um milissegundo para velocidade total e de 125 microssegundos para velocidade alta. Cada frame de velocidade total transporta até 1.023 bytes de payload, e um frame de alta velocidade transporta até 1.024 bytes. Juntando essas informações, calculamos a taxa de transferência máxima como 1.023.000 ou 8.192.000 bytes por segundo. Isso define um limite superior teórico na taxa de amostragem, na contagem de canais e na profundidade de bits do áudio combinado. O limite prático é menor.

No modo isocrono, há três submodos:

  • Adaptativo
  • Assíncrono
  • Síncrono

No submodo adaptável, a origem ou o destino periférico se adapta a uma taxa de amostragem potencialmente variável do host.

No submodo assíncrono (também chamado de feedback implícito), a origem ou o destino determinam a taxa de amostragem, e o host os acomoda. A principal vantagem teórica do submodo assíncrono é que o relógio USB de origem ou de destino está fisicamente e eletricamente mais próximo (e pode ser igual ou derivado) do relógio que aciona o DAC ou o ADC. Essa proximidade significa que o submodo assíncrono é menos suscetível a jitter de relógio. Além disso, o relógio usado pelo DAC ou ADC pode ser projetado para maior precisão e menor deriva do que o relógio do host.

No submodo síncrono, um número fixo de bytes é transferido a cada período de SOF. A taxa de amostragem de áudio é derivada do relógio USB. O submodo síncrono não é comumente usado com áudio porque o host e o periférico estão à mercê do relógio USB.

A tabela abaixo resume os submodos isocrônicos:

Submodo Contagem de bytes
por pacote
Taxa de amostragem
determinada por
Usado para áudio
adaptável variável anfitrião sim
assíncrona variável periférico sim
síncrono fixo Relógio USB não

Na prática, o submodo é importante, mas outros fatores também precisam ser considerados.

Suporte do Android para classe de áudio USB

Modo de desenvolvimento

O áudio USB não é compatível com o modo de desenvolvimento.

Modo host

O Android 5.0 (nível 21 da API) e versões mais recentes oferecem suporte a um subconjunto de recursos de áudio USB de classe 1 (UAC1):

  • O dispositivo Android precisa atuar como host
  • O formato de áudio precisa ser PCM (tipo de interface I)
  • A profundidade de bits precisa ser de 16, 24 ou 32 bits, em que 24 bits de dados de áudio úteis são justificados à esquerda nos bits mais significativos da palavra de 32 bits.
  • A taxa de amostragem precisa ser de 48, 44,1, 32, 24, 22,05, 16, 12, 11,025 ou 8 kHz
  • O número de canais precisa ser 1 (mono) ou 2 (estéreo)

A leitura do código-fonte do framework do Android pode mostrar código adicional além do mínimo necessário para oferecer suporte a esses recursos. No entanto, esse código não foi validado, então os recursos mais avançados ainda não foram reivindicados.

Modo de acessório

O Android 4.1 (nível 16 da API) adicionou suporte limitado à reprodução de áudio para o host. No modo de acessório, o Android roteia automaticamente a saída de áudio para o USB. Ou seja, o dispositivo Android serve como uma fonte de dados para o host, por exemplo, uma base.

O áudio no modo acessório tem os seguintes recursos:

  • O dispositivo Android precisa ser controlado por um host experiente que possa fazer a transição do modo de desenvolvimento para o modo de acessório e, em seguida, transferir dados de áudio do endpoint apropriado. Assim, o dispositivo Android não aparece como "sem driver" para o host.
  • A direção precisa ser entrada, expressa em relação ao host
  • O formato de áudio precisa ser PCM de 16 bits
  • A taxa de amostragem precisa ser de 44,1 kHz
  • A contagem de canais precisa ser 2 (estéreo)

O áudio do modo de acessório não foi amplamente adotado e não é recomendado para novos designs no momento.

Aplicações de áudio digital USB

Como o nome indica, o sinal de áudio digital USB é representado por um fluxo de dados digital em vez do sinal analógico usado pelo mini conector de fone de ouvido TRS comum. Eventualmente, qualquer sinal digital precisa ser convertido em analógico antes de ser ouvido. Há vantagens e desvantagens em escolher onde colocar essa conversão.

Uma história sobre dois DACs

No diagrama de exemplo abaixo, comparamos dois designs. Primeiro, temos um dispositivo móvel com processador de aplicativos (AP), DAC integrado, amplificador e conector TRS analógico conectado aos fones de ouvido. Também consideramos um dispositivo móvel com USB conectado a um DAC e amplificador USB externos, também com fones de ouvido.

Comparação de DAC

Figura 3. Comparação de dois DACs

Qual design é melhor? A resposta depende das suas necessidades. Cada uma tem vantagens e desvantagens.

Observação:essa é uma comparação artificial, já que um dispositivo Android real provavelmente teria as duas opções disponíveis.

O primeiro design A é mais simples, menos caro, usa menos energia e será um design mais confiável, considerando componentes igualmente confiáveis. No entanto, geralmente há compensações na qualidade do áudio em relação a outros requisitos. Por exemplo, se for um dispositivo de mercado de massa, ele pode ser projetado para atender às necessidades do consumidor geral, não do audiófilo.

No segundo design, o periférico de áudio externo C pode ser projetado para maior qualidade de áudio e maior potência de saída sem afetar o custo do dispositivo Android B básico para o mercado de massa. Sim, é um design mais caro, mas o custo é absorvido apenas por quem quer.

Os dispositivos móveis são conhecidos por ter placas de circuito de alta densidade, o que pode resultar em mais oportunidades de crosstalk, que degrada os sinais analógicos adjacentes. A comunicação digital é menos suscetível a ruídos, portanto, mover o DAC do dispositivo Android A para uma placa de circuito externo C permite que as etapas analógicas finais sejam fisicamente e eletricamente isoladas da placa de circuito densa e barulhenta, resultando em áudio de maior fidelidade.

Por outro lado, o segundo design é mais complexo, e com a complexidade adicionada, há mais oportunidades de falha. Há também uma latência extra dos controladores USB.

Aplicativos no modo host

Os aplicativos de áudio típicos no modo de host USB incluem:

  • ouvir música
  • telefonia
  • mensagens instantâneas e bate-papo por voz
  • gravando

Para todos esses aplicativos, o Android detecta um periférico de áudio digital USB compatível e encaminha automaticamente a reprodução e a captura de áudio de maneira adequada, com base nas regras da política de áudio. O conteúdo estéreo é reproduzido nos dois primeiros canais do periférico.

Não há APIs específicas para áudio digital USB. Para uso avançado, o roteamento automático pode interferir em aplicativos que reconhecem USB. Para esses aplicativos, desative o roteamento automático usando o controle correspondente na seção "Mídia" de Configurações / Opções do desenvolvedor.

Depurar no modo host

No modo de host USB, a depuração adb por USB não está disponível. Consulte a seção Uso sem fio da Android Debug Bridge para conferir uma alternativa.

Implementar áudio USB

Recomendações para fornecedores de periféricos de áudio

Para interagir com dispositivos Android, os fornecedores de periféricos de áudio precisam:

  • design para conformidade com a classe de áudio; atualmente, o Android é direcionado à classe 1, mas é recomendável planejar para a classe 2
  • evitar bugs
  • teste de interoperabilidade com dispositivos Android de referência e populares
  • documentar claramente os recursos com suporte, a conformidade com a classe de áudio, os requisitos de energia etc., para que os consumidores possam tomar decisões informadas

Recomendações para OEMs de dispositivos Android e fornecedores de SoC

Para oferecer suporte a áudio digital USB, os OEMs de dispositivos e os fornecedores de SoC precisam:

  • projetar hardware para oferecer suporte ao modo de host USB
  • Ativação do suporte a host USB genérico no nível do framework com a flag de recurso android.hardware.usb.host.xml
  • Ative todos os recursos do kernel necessários: modo host USB, áudio USB, modo de transferência isocrono
  • manter-se atualizado com as versões e os patches recentes do kernel; apesar do objetivo nobre de conformidade de classe, há periféricos de áudio existentes com peculiaridades, e os kernels recentes têm soluções alternativas para essas peculiaridades.
  • Ative a política de áudio USB conforme descrito abaixo
  • Adicionar audio.usb.default a PRODUCT_PACKAGES em device.mk
  • Testar a interoperabilidade com periféricos de áudio USB comuns

Ativar a política de áudio USB

Para ativar o áudio USB, adicione uma entrada ao arquivo de configuração da política de áudio. Ele geralmente está localizado aqui:

device/oem/codename/audio_policy.conf

O componente de caminho "oem" precisa ser substituído pelo nome do OEM que fabrica o dispositivo Android, e "codename" precisa ser substituído pelo nome de código do dispositivo.

Confira um exemplo de entrada:

audio_hw_modules {
  ...
  usb {
    outputs {
      usb_accessory {
        sampling_rates 44100
        channel_masks AUDIO_CHANNEL_OUT_STEREO
        formats AUDIO_FORMAT_PCM_16_BIT
        devices AUDIO_DEVICE_OUT_USB_ACCESSORY
      }
      usb_device {
        sampling_rates dynamic
        channel_masks dynamic
        formats dynamic
        devices AUDIO_DEVICE_OUT_USB_DEVICE
      }
    }
    inputs {
      usb_device {
        sampling_rates dynamic
        channel_masks AUDIO_CHANNEL_IN_STEREO
        formats AUDIO_FORMAT_PCM_16_BIT
        devices AUDIO_DEVICE_IN_USB_DEVICE
      }
    }
  }
  ...
}

Código-fonte

A implementação da camada de abstração de hardware (HAL) para áudio USB está localizada aqui:

hardware/libhardware/modules/usbaudio/

A HAL de áudio USB depende muito do tinyalsa, descrito em Terminologia de áudio. Embora o áudio USB dependa de transferências isocrônicas, isso é abstraido pela implementação do ALSA. Portanto, o HAL de áudio USB e o tinyalsa não precisam se preocupar com essa parte do protocolo USB.

Testar áudio USB

Para informações sobre os testes do CTS para áudio USB, consulte Testes do verificador CTS de áudio USB.