Formatos de datos

Android usa una amplia variedad de formatos de datos de audio internamente y expone un subconjunto de estos en API públicas, formatos de archivo y la capa de abstracción de hardware (HAL).

Propiedades

Los formatos de datos de audio se clasifican por sus propiedades:

Compresión
Sin comprimir , comprimido sin pérdida o comprimido con pérdida . PCM es el formato de audio sin comprimir más común. FLAC es un formato comprimido sin pérdida, mientras que MP3 y AAC son formatos comprimidos con pérdida.
Profundidad de bits
Número de bits significativos por muestra de audio.
Tamaño de contenedor
Número de bits utilizados para almacenar o transmitir una muestra. Por lo general, esto es lo mismo que la profundidad de bits, pero a veces se asignan bits de relleno adicionales para la alineación. Por ejemplo, una muestra de 24 bits podría estar contenida dentro de una palabra de 32 bits.
Alineación
Si el tamaño del contenedor es exactamente igual a la profundidad de bits, la representación se llama empaquetada . De lo contrario, la representación se descomprime . Los bits significativos de la muestra generalmente se alinean con el bit más a la izquierda (más significativo) o más a la derecha (menos significativo) del contenedor. Es convencional utilizar los términos empaquetado y desempaquetado sólo cuando la profundidad de bits no es una potencia de dos .
firma
Si las muestras están firmadas o no.
Representación
Ya sea punto fijo o punto flotante; vea abajo.

Representación de punto fijo

El punto fijo es la representación más común para los datos de audio PCM sin comprimir, especialmente en las interfaces de hardware.

Un número de punto fijo tiene un número fijo (constante) de dígitos antes y después del punto de raíz . Todas nuestras representaciones usan base 2 , por lo que sustituimos bit por dígito y punto binario o simplemente punto por punto de base . Los bits a la izquierda del punto son la parte entera y los bits a la derecha del punto son la parte fraccionaria .

Hablamos de PCM entero , porque los valores de punto fijo generalmente se almacenan y manipulan como valores enteros. La interpretación como punto fijo es implícita.

Usamos el complemento a dos para todas las representaciones de punto fijo con signo, por lo que se cumple lo siguiente donde todos los valores están en unidades de un LSB :

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

Notación Q y U

Hay varias notaciones para la representación de punto fijo en un número entero. Usamos la notación Q: Q m . n significa m bits enteros y n bits fraccionarios. La "Q" cuenta como un bit, aunque el valor se expresa en complemento a dos. El número total de bits es m + n + 1.

Um . n es para números sin signo: m bits enteros y n bits fraccionarios, y la "U" cuenta como cero bits. El número total de bits es m + n .

La parte entera puede usarse en el resultado final o ser temporal. En este último caso, los bits que componen la parte entera se denominan bits de guarda . Los bits de protección permiten que se desborde un cálculo intermedio, siempre que el valor final esté dentro del rango o se pueda fijar para que esté dentro del rango. Tenga en cuenta que los bits de protección de punto fijo están a la izquierda, mientras que los dígitos de protección de la unidad de punto flotante se utilizan para reducir el error de redondeo y están a la derecha.

Representación de punto flotante

El punto flotante es una alternativa al punto fijo, en el que la ubicación del punto puede variar. Las principales ventajas del punto flotante incluyen:

  • Mayor headroom y rango dinámico ; la aritmética de coma flotante tolera exceder los rangos nominales durante el cálculo intermedio y solo fija los valores al final
  • Soporte para valores especiales como infinitos y NaN
  • Más fácil de usar en muchos casos.

Históricamente, la aritmética de punto flotante era más lenta que la aritmética de enteros o de punto fijo, pero ahora es común que el punto flotante sea más rápido, siempre que las decisiones de flujo de control no se basen en el valor de un cálculo.

Formatos de Android para audio

Los principales formatos de Android para audio se enumeran en la siguiente tabla:

Notación
Propiedad Q0.15 Q0.7 1 Q0.23 Q0.31 flotar
Envase
pedacitos
dieciséis 8 24 o 32 2 32 32
Bits significativos
incluyendo signo
dieciséis 8 24 24 o 32 2 25 3
Espacio libre
en dB
0 0 0 0 126 4
Gama dinámica
en dB
90 42 138 138 a 186 900 5

Todos los formatos de punto fijo anteriores tienen un rango nominal de -1,0 a +1,0 menos un LSB. Hay un valor negativo más que un valor positivo debido a la representación del complemento a dos.

Notas al pie:

  1. Todos los formatos anteriores expresan valores de muestra con signo. El formato de 8 bits se suele denominar "sin firmar", pero en realidad es un valor con signo con un sesgo de 0.10000000 .
  2. Q0.23 puede empaquetarse en 24 bits (tres bytes de 8 bits, little-endian) o desempaquetarse en 32 bits. Si se desempaquetan, los bits significativos se justifican a la derecha hacia el LSB con relleno de extensión de signo hacia el MSB (Q8.23) o se justifican a la izquierda hacia el MSB con relleno de cero hacia el LSB (Q0.31). Q0.31 teóricamente permite hasta 32 bits significativos, pero las interfaces de hardware que aceptan Q0.31 rara vez usan todos los bits.
  3. El punto flotante de precisión simple tiene 23 bits explícitos más un bit oculto y un bit de signo, lo que da como resultado un total de 25 bits significativos. Los números anormales tienen menos bits significativos.
  4. El punto flotante de precisión simple puede expresar valores de hasta ±1.7e+38, lo que explica el gran headroom.
  5. El rango dinámico que se muestra es para desnormales hasta el valor máximo nominal ±1.0. Tenga en cuenta que algunas implementaciones de coma flotante específicas de la arquitectura, como NEON , no son compatibles con valores anormales.

Conversiones

En esta sección se analizan las conversiones de datos entre varias representaciones.

Conversiones de punto flotante

Para convertir un valor de Q m . n formato a coma flotante:

  1. Convierta el valor a punto flotante como si fuera un número entero (ignorando el punto).
  2. Multiplica por 2 - n .

Por ejemplo, para convertir un valor interno Q4.27 a punto flotante, use:

float = integer * (2 ^ -27)

Las conversiones de punto flotante a punto fijo siguen estas reglas:

  • El punto flotante de precisión simple tiene un rango nominal de ±1,0, pero el rango completo para valores intermedios es de ±1,7e+38. La conversión entre punto flotante y punto fijo para la representación externa (como la salida a dispositivos de audio) considerará solo el rango nominal, con restricciones para los valores que excedan ese rango. En particular, cuando +1,0 se convierte a un formato de punto fijo, se fija a +1,0 menos un LSB.
  • Los denormales (subnormales) y ambos +/- 0.0 están permitidos en la representación, pero pueden convertirse silenciosamente a 0.0 durante el procesamiento.
  • Los infinitos pasarán a través de operaciones o se limitarán silenciosamente a +/- 1.0. Generalmente, este último es para la conversión a un formato de punto fijo.
  • El comportamiento de NaN no está definido: un NaN puede propagarse como un NaN idéntico, o puede convertirse en un NaN predeterminado, puede limitarse silenciosamente a +/- 1.0, o convertirse silenciosamente a 0.0, o generar un error.

Conversiones de punto fijo

Conversiones entre diferentes Q m . n formatos siguen estas reglas:

  • Cuando m aumenta, extienda la parte entera a la izquierda.
  • Cuando se disminuye m , sujete la parte entera.
  • Cuando n aumenta, cero extiende la parte fraccionaria de la derecha.
  • Cuando se reduce n , interpole, redondee o trunque los bits fraccionarios sobrantes a la derecha.

Por ejemplo, para convertir un valor Q4.27 a Q0.15 (sin interpolación ni redondeo), desplace a la derecha el valor Q4.27 en 12 bits y limite cualquier resultado que exceda el rango de 16 bits con signo. Esto alinea el punto de la representación Q.

Para convertir Q7.24 a Q7.23, haga una división con signo por 2, o de manera equivalente agregue el bit de signo a la cantidad entera Q7.24, y luego haga un desplazamiento a la derecha con signo por 1. Tenga en cuenta que un simple desplazamiento a la derecha con signo no es equivalente a una división firmada por 2.

Conversiones con pérdida y sin pérdida

Una conversión no tiene pérdidas si es invertible : una conversión de A a B a C da como resultado A = C De lo contrario, la conversión es con pérdidas .

Las conversiones sin pérdidas permiten la conversión de formato de ida y vuelta .

Las conversiones de representación de punto fijo con 25 o menos bits significativos a punto flotante no tienen pérdidas. Las conversiones de punto flotante a cualquier representación de punto fijo común tienen pérdidas.