Formatos de dados

O Android usa uma ampla variedade de formatos de dados de áudio internamente e expõe um subconjunto deles em APIs públicas, formatos de arquivo e HAL ( Hardware Abstraction Layer ).

Propriedades

Os formatos de dados de áudio são classificados por suas propriedades:

Compressão
Não compactado , compactado sem perdas ou compactado com perdas . PCM é o formato de áudio não comprimido mais comum. FLAC é um formato compactado sem perdas, enquanto MP3 e AAC são formatos compactados com perdas.
Profundidade de bits
Número de bits significativos por amostra de áudio.
Tamanho do contêiner
Número de bits usados ​​para armazenar ou transmitir uma amostra. Normalmente, isso é o mesmo que a profundidade de bits, mas às vezes são alocados bits de preenchimento adicionais para alinhamento. Por exemplo, uma amostra de 24 bits pode estar contida em uma palavra de 32 bits.
Alinhamento
Se o tamanho do contêiner for exatamente igual à profundidade de bits, a representação é chamada de empacotada . Caso contrário, a representação é descompactada . Os bits significativos da amostra são normalmente alinhados com o bit mais à esquerda (mais significativo) ou mais à direita (menos significativo) do contêiner. É convencional usar os termos compactado e descompactado somente quando a profundidade de bits não for uma potência de dois .
Assinatura
Se as amostras são assinadas ou não.
Representação
Ponto fixo ou ponto flutuante; Veja abaixo.

Representação de ponto fixo

Ponto fixo é a representação mais comum para dados de áudio PCM não compactados, especialmente em interfaces de hardware.

Um número de ponto fixo tem um número fixo (constante) de dígitos antes e depois do ponto de base . Todas as nossas representações usam base 2 , então substituímos bit por dígito e ponto binário ou simplesmente ponto por ponto base . Os bits à esquerda do ponto são a parte inteira, e os bits à direita do ponto são a parte fracionária .

Falamos de PCM inteiro , porque os valores de ponto fixo geralmente são armazenados e manipulados como valores inteiros. A interpretação como ponto fixo está implícita.

Usamos o complemento de dois para todas as representações de ponto fixo com sinal, então o seguinte vale onde todos os valores estão em unidades de um LSB :

|largest negative value| = |largest positive value| + 1

Notação Q e U

Existem várias notações para representação de ponto fixo em um inteiro. Usamos a notação Q : Q m . n significa m bits inteiros e n bits fracionários. O "Q" conta como um bit, embora o valor seja expresso em complemento de dois. O número total de bits é m + n + 1.

Um . n é para números sem sinal: m bits inteiros e n bits fracionários, e o "U" conta como bits zero. O número total de bits é m + n .

A parte inteira pode ser utilizada no resultado final, ou ser temporária. Neste último caso, os bits que compõem a parte inteira são chamados de bits de guarda . Os bits de guarda permitem que um cálculo intermediário transborde, desde que o valor final esteja dentro da faixa ou possa ser fixado dentro da faixa. Observe que os bits de guarda de ponto fixo estão à esquerda, enquanto os dígitos de guarda de unidade de ponto flutuante são usados ​​para reduzir o erro de arredondamento e estão à direita.

Representação de ponto flutuante

O ponto flutuante é uma alternativa ao ponto fixo, no qual a localização do ponto pode variar. As principais vantagens do ponto flutuante incluem:

  • Maior headroom e faixa dinâmica ; A aritmética de ponto flutuante tolera faixas nominais superiores durante o cálculo intermediário e apenas fixa os valores no final
  • Suporte para valores especiais como infinitos e NaN
  • Mais fácil de usar em muitos casos

Historicamente, a aritmética de ponto flutuante era mais lenta que a aritmética inteira ou de ponto fixo, mas agora é comum que a aritmética de ponto flutuante seja mais rápida, desde que as decisões de fluxo de controle não sejam baseadas no valor de uma computação.

Formatos Android para áudio

Os principais formatos Android para áudio estão listados na tabela abaixo:

Notação
Propriedade Q0.15 Q0.7 1 Q0.23 Q0.31 flutuador
Recipiente
bits
16 8 24 ou 32 2 32 32
Bits significativos
incluindo sinal
16 8 24 24 ou 32 2 25 3
Altura
em dB
0 0 0 0 126 4
Faixa dinâmica
em dB
90 42 138 138 a 186 900 5

Todos os formatos de ponto fixo acima têm uma faixa nominal de -1,0 a +1,0 menos um LSB. Há mais um valor negativo do que positivo devido à representação do complemento de dois.

Notas de rodapé:

  1. Todos os formatos acima expressam valores de amostra assinados. O formato de 8 bits é comumente chamado de "sem sinal", mas na verdade é um valor com sinal com viés de 0.10000000 .
  2. Q0.23 pode ser empacotado em 24 bits (três bytes de 8 bits, little-endian), ou desempacotado em 32 bits. Se desempacotados, os bits significativos são justificados à direita em direção ao LSB com preenchimento de extensão de sinal em direção ao MSB (Q8.23), ou justificados à esquerda em direção ao MSB com preenchimento zero em direção ao LSB (Q0.31). Q0.31 teoricamente permite até 32 bits significativos, mas as interfaces de hardware que aceitam Q0.31 raramente usam todos os bits.
  3. O ponto flutuante de precisão simples tem 23 bits explícitos mais um bit oculto e um bit de sinal, resultando em um total de 25 bits significativos. Números desnormais têm menos bits significativos.
  4. O ponto flutuante de precisão simples pode expressar valores de até ±1,7e+38, o que explica o grande headroom.
  5. A faixa dinâmica mostrada é para denormais até o valor nominal máximo ±1,0. Observe que algumas implementações de ponto flutuante específicas da arquitetura, como NEON , não suportam denormais.

Conversões

Esta seção discute as conversões de dados entre várias representações.

Conversões de ponto flutuante

Para converter um valor de Q m . n formato para ponto flutuante:

  1. Converta o valor em ponto flutuante como se fosse um inteiro (ignorando o ponto).
  2. Multiplique por 2 - n .

Por exemplo, para converter um valor interno Q4.27 em ponto flutuante, use:

float = integer * (2 ^ -27)

As conversões de ponto flutuante para ponto fixo seguem estas regras:

  • O ponto flutuante de precisão simples tem uma faixa nominal de ±1,0, mas a faixa completa para valores intermediários é ±1,7e+38. A conversão entre ponto flutuante e ponto fixo para representação externa (como saída para dispositivos de áudio) considerará apenas a faixa nominal, com fixação para valores que ultrapassem essa faixa. Em particular, quando +1,0 é convertido para um formato de ponto fixo, ele é fixado em +1,0 menos um LSB.
  • Denormals (subnormais) e ambos +/- 0,0 são permitidos na representação, mas podem ser convertidos silenciosamente para 0,0 durante o processamento.
  • Os infinitos passarão por operações ou serão silenciosamente limitados a +/- 1,0. Geralmente o último é para conversão para um formato de ponto fixo.
  • O comportamento do NaN é indefinido: um NaN pode se propagar como um NaN idêntico ou pode ser convertido em um NaN padrão, pode ser silenciosamente limitado a +/- 1,0 ou convertido silenciosamente em 0,0 ou resultar em um erro.

Conversões de ponto fixo

Conversões entre diferentes Q m . n formatos seguem estas regras:

  • Quando m é aumentado, o sinal estende a parte inteira à esquerda.
  • Quando m é diminuído, prenda a parte inteira.
  • Quando n é aumentado, zero estende a parte fracionária à direita.
  • Quando n é diminuído, pontilhar, arredondar ou truncar os bits fracionários em excesso à direita.

Por exemplo, para converter um valor Q4.27 em Q0.15 (sem pontilhamento ou arredondamento), desloque para a direita o valor Q4.27 em 12 bits e fixe quaisquer resultados que excedam o intervalo com sinal de 16 bits. Isso alinha o ponto da representação Q.

Para converter Q7.24 em Q7.23, faça uma divisão com sinal por 2 ou, de forma equivalente, adicione o bit de sinal à quantidade inteira Q7.24 e, em seguida, sinalize o deslocamento à direita por 1. Observe que um simples deslocamento à direita com sinal não é equivalente a uma divisão assinada por 2.

Conversões com e sem perdas

Uma conversão é sem perdas se for invertível : uma conversão de A para B para C resulta em A = C Caso contrário, a conversão é com perdas .

As conversões sem perdas permitem a conversão de formato de ida e volta .

As conversões da representação de ponto fixo com 25 ou menos bits significativos para ponto flutuante são sem perdas. As conversões de ponto flutuante para qualquer representação de ponto fixo comum têm perdas.