Muestreo de audio

A partir de Android 5.0 (Lollipop), los reproductores de muestras de audio ahora se basan completamente en filtros FIR derivados de una función de Kaiser de sincronización en ventana. Esta función ofrece las siguientes propiedades:

  • Es fácil de calcular para sus parámetros de diseño (banda de detención, ondulación, ancho de banda de transición, frecuencia de corte, longitud del filtro).
  • Es prácticamente óptima para la reducción de energía de la banda de detención, en comparación con la energía general.

Consulta la página 50 de Multirate Systems and Filter Banks (Sistemas de tasa múltiple y bancos de filtros), de P.P. Vaidyanathan, para leer debates sobre la ventana de Kaiser y su optimalidad y relación con las ventanas esferoidales alargadas.

Los parámetros de diseño se computan automáticamente en función de la determinación de calidad interna y de las relaciones de muestreo deseadas. En función a los parámetros de diseño, se genera el filtro de sincronización en ventana. A fin de aplicarlo en música, el reproductor de muestras para 44.1 a 48 kHz y viceversa se genera con una calidad más alta que para la conversión de frecuencia arbitraria.

Los reproductores de muestras de audio proporcionan una mayor calidad y también más velocidad para lograr esa calidad. Sin embargo, los reproductores de muestras pueden introducir pequeñas cantidades de ondulaciones de banda de paso y ruido armónico de suavizado, y pueden provocar pérdida de alta frecuencia en la banda de transición, por lo que debes evitar usarlos si no los necesitas.

Prácticas recomendadas para el muestreo y la reproducción de muestras

En esta sección, se describen algunas de las prácticas recomendadas para ayudarte a evitar problemas con las frecuencias de muestreo.

Cómo seleccionar la frecuencia de muestreo que mejor se adapte al dispositivo

En general, se recomienda seleccionar la frecuencia de muestreo que se adapte al dispositivo, que normalmente es de 44.1 kHz o 48 kHz. El uso de una tasa de muestreo mayor que 48 kHz generalmente da como resultado una menor calidad, ya que se debe usar el reproductor de muestras para volver a reproducir el archivo.

Cómo usar relaciones de reproducción de muestras sencillas (polifases fijas en comparación con interpoladas)

El reproductor de muestras funciona en uno de los siguientes modos:

  • Modo polifásico fijo. Los coeficientes del filtro para cada fase están computados previamente.
  • Modo polifásico interpolado. Los coeficientes del filtro para cada polifase deben interpolarse a partir de las dos polifases más cercanas computadas previamente.

El reproductor de muestras es más rápido en el modo polifásico fijo, cuando, en la relación entre la velocidad de entrada y la velocidad de salida L/M (quitando el máximo común divisor), M es inferior a 256. Por ejemplo, para una conversión de 44,100 a 48,000, L = 147, M = 160.

En el modo polifásico fijo, la tasa de muestreo está bloqueada y no cambia. En el modo polifásico interpolado, la tasa de muestreo es aproximada. Al reproducir audio en un dispositivo de 48 kHz, la desviación de la tasa de muestreo generalmente es de una muestra cada pocas horas. Esto no suele ser un problema, ya que el error de aproximación es mucho menor que el de frecuencia que aportan los osciladores de cuarzo internos, la desviación térmica o el jitter (generalmente, decenas de ppm).

Elige tasas de muestreo de relación sencilla, como 24 kHz (1:2) y 32 kHz (2:3) al reproducir audio en un dispositivo de 48 kHz, aunque se permitan otras tasas y relaciones de muestreo a través de AudioTrack.

Cómo usar el sobremuestreo en lugar de la reducción de muestreo para cambiar las tasas de muestreo

Las tasas de muestreo pueden cambiarse en el momento. La granularidad de ese cambio se basa en el almacenamiento en el búfer interno (generalmente unos pocos cientos de muestras), no en la modalidad muestra por muestra. Esto se puede usar para los efectos.

No cambies dinámicamente las tasas de muestreo cuando apliques la reducción de muestreo. Cuando cambies las tasas de muestreo y se cree una pista de audio, las diferencias del 5% al 10% respecto de la tasa original pueden generar una repetición del cómputo del filtro cuando realizan la reducción de muestreo (para suprimir de forma correcta el suavizado). Esto puede consumir recursos de cómputos y provocar un clic audible si el filtro se reemplaza en tiempo real.

Limita el submuestreo a no más de 6:1

El submuestreo generalmente se activa por requisitos de dispositivos de hardware. Cuando el convertidor de tasa de muestreo se usa para la reducción de muestreo, intenta limitar la relación de la reducción de muestreo a no más de 6:1 a fin de lograr una buena supresión del suavizado (por ejemplo, esta debe ser de 48,000 a 8,000; no superior). Las longitudes del filtro se ajustan a fin de que coincidan con la proporción de la reducción de muestreo, pero se sacrifica más ancho de banda de transición con proporciones de reducción de muestreo más altas para evitar un incremento excesivo de la longitud del filtro. No hay inquietudes de suavizado similares para la reducción de muestreo. Ten en cuenta que algunas partes de la canalización de audio pueden evitar una reducción de muestreo superior a 2:1.

Si te preocupa la latencia, no reproduzcas muestras

La reproducción de muestras no permite que se ubique la pista en la ruta de acceso del FastMixer, lo cual significa que se produce una latencia mucho más alta debido al búfer adicional mayor en la ruta de acceso común del mezclador. Además, hay una demora implícita producida por la longitud del filtro del reproductor de muestras, aunque generalmente se encuentra cerca de un milisegundo o un valor inferior, que no es tan grande como el almacenamiento en búfer adicional para la ruta de acceso común del mezclador (normalmente, 20 milisegundos).

Uso del audio de punto flotante

El uso de números de punto flotante para representar datos de audio puede mejorar notablemente la calidad del audio en apps de audio de alto rendimiento. El punto flotante ofrece las siguientes ventajas:

  • Rango dinámico más amplio.
  • Precisión uniforme en todo el rango dinámico.
  • Mayor capacidad de aumento para evitar recortes durante cálculos intermedios y transitorios.

Si bien el punto flotante puede mejorar la calidad del audio, también presenta algunas desventajas:

  • Los números de punto flotante usan más memoria.
  • Las operaciones de punto flotante emplean propiedades inesperadas; por ejemplo, la suma no es asociativa.
  • Los cálculos de punto flotante pueden perder precisión aritmética debido al redondeo o a algoritmos numéricamente inestables.
  • El uso eficaz del punto flotante requiere una mayor comprensión para lograr resultados precisos y reproducibles.

Antes, el punto flotante tenía mala fama por ser lento o no estar disponible. Esto aún se aplica a procesadores incorporados y de gama baja. Sin embargo, los procesadores de los dispositivos móviles modernos ahora cuentan con punto flotante asistido por hardware con un rendimiento similar a los valores enteros o, en algunos casos, más rápido que ellos. Las CPU modernas también admiten SIMD (una instrucción única, varios datos) que puede mejorar aún más el rendimiento.

Prácticas recomendadas para el audio de punto flotante

Las siguientes prácticas recomendadas te ayudan a evitar problemas con los cálculos de punto flotante:

  • Usa punto flotante de precisión doble para los cálculos poco frecuentes, como el cómputo de coeficientes del filtro.
  • Presta atención al orden de las operaciones.
  • Declara variables explícitas para valores intermedios.
  • Usa paréntesis sin restricciones.
  • Si obtienes un resultado NaN o infinity, usa la búsqueda de objetos binarios para detectar el punto en el cual se introdujo.

Para el audio de punto flotante, se usa la codificación de formato de audio AudioFormat.ENCODING_PCM_FLOAT, de la misma manera que ENCODING_PCM_16_BIT o ENCODING_PCM_8_BIT, para especificar formatos de datos de AudioTrack. El método AudioTrack.write() con sobrecarga correspondiente incorpora un arreglo flotante para entregar datos.

Kotlin

fun write(
        audioData: FloatArray,
        offsetInFloats: Int,
        sizeInFloats: Int,
        writeMode: Int
): Int

Java

public int write(float[] audioData,
        int offsetInFloats,
        int sizeInFloats,
        int writeMode)

Más información

En esta sección se proporcionan algunos recursos adicionales sobre el muestreo y el punto flotante.

Muestreo

Tasas de muestreo

Reproducción de muestras

La controversia de la gran profundidad de bits y una cantidad de kHz elevada

Punto flotante

Las siguientes páginas de Wikipedia son útiles para comprender el audio de punto flotante:

En el siguiente artículo, se proporciona información sobre estos aspectos del punto flotante, que afectan directamente a los diseñadores de sistemas informáticos: