Cómo probamos los sistemas de micrófonos en STM32: la experiencia de los desarrolladores de dispositivos Yandex



Hola, soy Gennady "Crail" Kruglov del equipo de soluciones de hardware de Yandex.

La selección de micrófonos para la matriz de micrófonos es una parte compleja e interesante de nuestro trabajo: probamos modelos con varios parámetros, experimentamos con varias configuraciones de matriz y mejoramos los algoritmos de procesamiento de sonido.

Es conveniente que los desarrolladores que crean algoritmos de reducción de ruido y eco no solo procesen datos sin procesar que se tomaron previamente de un dispositivo en el laboratorio, sino que también interactúen, por ejemplo, con una nueva matriz de micrófono en tiempo real conectándola a su computadora portátil.

Parece simple solo a primera vista. En este artículo explicaré cómo resolvimos el problema de transferir el sonido de siete micrófonos con una interfaz PDM a una computadora a través de USB, qué matices de hardware y software encontramos y cómo superarlos (spoiler: este enfoque puede adaptarse para matrices con la cantidad de micrófonos ≤ 8 ) Al final de la publicación, compartiré un enlace a la transmisión, donde mostraré el proceso de desarrollo en el microcontrolador STM32 y hablaré sobre la próxima serie.

Formulación del problema


Un poco de historia: para crear un haz controlado de sensibilidad, para el primer Yandex.Station, se seleccionó un circuito con siete micrófonos (analógicos), para la versión Mini, con cuatro (ya digitales). Para otros productos, se consideran varias configuraciones, pero aún así la matriz de siete micrófonos para nosotros es básica, clásica.

Entonces, dado: siete micrófonos digitales, la necesidad de probarlos. Encontrar: no es demasiado difícil de implementar y una forma flexible de interactuar con ellos. Es lógico dividir la tarea en dos:

1. Obtener datos de los micrófonos.

2. Enviarlos a una computadora.

En el dispositivo terminado, cuando el usuario contacta a Alice, las señales de los micrófonos digitales se envían directamente al procesador central (es más correcto llamarlo SoC - System-on-Chip, pero el "procesador" es más familiar y conveniente), tiene suficiente potencia para procesarlas. Pero para los algoritmos de depuración es mucho más conveniente llevar estos datos directamente a la computadora del desarrollador. La forma más fácil es conectarse a través de USB: por lo tanto, la placa debe tener un microcontrolador con la unidad adecuada. Nos encanta el controlador STM32, pero es imposible enviar el flujo de sonido desde los micrófonos directamente a él: no hay una unidad de recepción de señal PDM (modulación de densidad de pulso), la interfaz de salida de los micrófonos digitales.

Otra opción es conectar la placa del micrófono a la placa de depuración del fabricante del SoC utilizado. Pero esta decisión está vinculada a Linux alsamixer, y sus parámetros afectan fuertemente el resultado de convertir PDM a PCM. Estos bloques pueden diferir no solo para procesadores de diferentes fabricantes, sino incluso para dos modelos del mismo proveedor. Les recuerdo que necesitábamos una solución simple, transparente y predecible.

Solución de hardware


Acepte la incapacidad del STM32 para aceptar PDM multicanal. Se podría usar el bloque SPI para recibir una señal PDM, pero solo se puede conectar un micrófono a un bus SPI. Trabajamos con el controlador STM32L476RC, donde solo hay tres de estos buses. Complejidad adicional: la señal PDM es de bastante alta frecuencia, es necesario hacer su diezmado, promediación, procesamiento, filtrado; para siete micrófonos esta tarea es bastante complicada.

Como estamos hablando de una placa de depuración, y no de un prototipo para la producción en masa, nos centraremos en un chip especializado TSDP18xx. Hace todo lo necesario: genera las frecuencias y señales necesarias para PDM, promedia y procesa la señal PDM, la convierte en una señal I2S. Más precisamente, TDM (multiplexación por división de tiempo), porque el bus I2S asume dos canales, y si conduce más a través de los mismos cables, ya no es correcto llamarlo I2S.

La ventaja de este enfoque es que todo el trabajo de preparación y promediación es realizado por TSDP. Menos: todos los algoritmos están estrechamente conectados dentro de este microcircuito, y no se pueden cambiar. En particular, no puede ajustar el volumen modificando los parámetros de promedio. Pero para la depuración, esto no es crítico.

Mire sus manos: hay siete micrófonos, ocho canales en el microcircuito. El que no se usa, la salida todavía está allí, por lo que en el futuro por simplicidad hablaré sobre la transmisión de audio de ocho canales.

Entonces, elevamos el TDM de ocho canales a STM32, obtenemos una transmisión de audio de ocho canales. Cómo se mueven los datos:



SAI - Unidad de hardware STM32 para trabajar con I2S / TDM. Es muy flexible y le permite implementar muchas opciones de protocolo. Pero debido a esto, es fácil confundirse con los requisitos para las frecuencias.

El árbol del reloj merece una mirada más cercana. Un resonador de cuarzo de 12 MHz está conectado al microcontrolador. Dividimos esta frecuencia antes de aplicar a los bloques PLL por 3 y obtenemos 4 MHz. Entonces funciona así:

1. Sería bueno aumentar la frecuencia del núcleo para mantenerse al día con todo: por ejemplo, el máximo para este controlador es 80 MHz. Usamos el primer bloque PLL: multiplicamos 4 MHz por 40 y dividimos entre 2.

2. USB requiere 48 MHz. Para hacer esto, use el segundo bloque PLL: multiplique 4 MHz por 24 y divida entre 2.

3. Acerca de los micrófonos. Nuestros tableros de prueba utilizan una frecuencia de muestreo de Fs = 16 kHz, un estándar adoptado en el campo del reconocimiento de voz. Desde la frecuencia inicial de 4 MHz, debe obtener algo que se pueda convertir en frecuencias de trama de bus TDM de 16 kHz (también conocido como LRCK, también conocido como FCK, también conocido como FrameSync). En este caso:

[frecuencia de sincronización de bits (BCLK, BitClk, Sync, SCK)] = Fs ∙ [número de canales] ∙ [número de bits por canal]

Es decir: SCK = 16 kHz ∙ 8 ∙ 16 = 2048 kHz.

4. La hoja de datos indica que la relación entre el reloj maestro y la frecuencia de muestreo Fs es la siguiente: MasterClock = 16 kHz ∙ Divisor MCLK ∙ 256. Aquí 256 es una constante, y el divisor se puede establecer en el registro. Verifiquemos el esquema: para la funcionalidad necesaria, existen coeficientes para dividir la frecuencia PLL entre 7 o 17:



para resumir el problema: debe seleccionar un conjunto de factores y divisores PLL y SAI para obtener una frecuencia de muestreo de 16 kHz y una frecuencia de bits de 128 veces más. Como el conjunto tenía un divisor obligatorio por 7 (o 17), no funcionó para obtener exactamente el resultado deseado. Tuve que construir una tabla de multiplicadores y divisores para obtener 24.571 MHz. Dividiendo esta frecuencia por 6 (MCLK Divider), y luego por 256 (constante), finalmente, obtenemos un número lo suficientemente cercano a 16 kHz. Ahora explicaré por qué esto es tan importante.

Operación USB


USB utiliza un tipo de transferencia isócrono para trabajar con datos multimedia: en este caso, se garantiza un cierto ancho de banda y un valor de retraso en el bus USB. La entrega de datos no está garantizada: si un paquete llega con una falla, se considerará perdido. Esto se debe a límites de tiempo estrictos: no hay forma de volver a preguntar.

Con el tipo de transferencia isócrona a velocidad USB FullSpeed ​​(es de 12 Mbit / s; es a esta velocidad que el bloque USB STM32 puede funcionar) la computadora llega al dispositivo para obtener datos cada milisegundo: después de este período de tiempo, debe recopilar los datos acumulados. Permítanme recordarles los introductorios: la frecuencia de muestreo es de 16 kHz, 8 canales, cada canal requiere dos bytes, porque el sonido es de dieciséis bits. Total 16000 ∙ 2 ∙ 8/1000 = 256 bytes por milisegundo. El tamaño de un paquete para un tipo de transmisión isócrono puede alcanzar 1023 bytes, por lo que no hay problemas en este momento.

Entonces, el tamaño del paquete es de 256 bytes. Parece que todo está bien. Dieciséis veces recibimos datos en TDM, los colocamos en el búfer, llegó USB, le damos un paquete, repetimos ... Pero esto solo sucede en un mundo ideal. El problema es que, por un lado, tenemos 16 kHz imperfectos (un poco menos), y como resultado, los datos llegan en un poco menos de una vez cada milisegundo. Por otro lado, el milisegundo de la computadora también flota, ya que está ocupada: cuando pudo, entonces vino. Es decir, la frecuencia de sondeo del micrófono difiere de 16 kHz (pero siempre la misma), y el milisegundo USB también difiere en longitud (la diferencia, lo más probable, es flotante: resulta un poco más, luego un poco menos que un milisegundo ideal).

¿Por qué es esto un problema? Puedes perder el paquete. Probablemente sea innecesario explicar que los datos completos son necesarios para la depuración correcta de los algoritmos. Cómo se pierde el paquete: acumularon 256 bytes de resultados, los pusieron en el búfer y continuaron la medición. Llegó una computadora, tomó los primeros 256, todavía seguimos midiendo. La computadora volvió a aparecer, pero la medición aún no se ha completado: la computadora se fue con un paquete vacío. Luego terminamos de llenar el búfer y comenzamos a llenar otro, el siguiente, hasta que la computadora vuelva a llegar. La computadora toma solo el último paquete; como resultado, se pierde un paquete.



El problema es, de hecho, conocido. Hay tres enfoques para tratarlo:

  • . USB. — . «» — . USB . , , ( , 16 ), . , .
  • . .
  • Asíncrono es lo mejor para esta tarea. El dispositivo tiene un generador de frecuencia estable. La frecuencia de muestreo se mantiene exactamente igual sin referencia a USB. En este caso, debe transferir datos al dispositivo para que no haya discrepancias significativas.

Todo esto se ha discutido más de una vez en Internet para el caso de la reproducción desde una computadora al altavoz a través de un dispositivo con un codificador digital a analógico, donde el dispositivo como retroalimentación le indica cuántos períodos de muestreo han llegado desde que se recibió el último paquete.



Pero nuestra tarea es lo contrario, la depuración requiere recibir datos de los micrófonos a una computadora, y la cuestión de grabar una señal de los micrófonos a una computadora solo se menciona en el mejor de los casos. ¿Por qué no hacer lo mismo: introducir comentarios de la computadora? Hay una opción más fácil.

Ahi esta


Utilizamos la adición frecuente de muestras y dos memorias intermedias para almacenar datos para enviar. 16 veces por milisegundo agregamos al búfer seleccionado la siguiente muestra. En algún momento, se produce una interrupción: USB tomó el paquete anterior. Si el búfer n. ° 1 está lleno, cambia al búfer n. ° 2. Cuando llega el USB para el siguiente paquete, ya está preparado. Envíe el búfer número 2 y vuelva al número 1.



USB viene para datos en diferentes momentos, el paquete incluye un número diferente de muestras. Puede llegar a ser más o menos de dieciséis, por lo que existe la posibilidad de superar un paquete de 256 bytes de tamaño, es mejor dejar espacio para maniobrar. Sea 384 = 256 + 128: esto dará un margen de medio milisegundo, es decir, perdonará la fase de nado de la señal USB en un 50%; dicho margen debería ser más que suficiente. Total: a veces se envían más o menos 256 bytes, pero nunca un paquete vacío, lo que evita la pérdida de datos. Es decir, el problema de las irregularidades se resolvió aumentando el paquete, a costa de aumentar parte del ancho de banda del bus asignado para nuestro dispositivo y reducir esta parte para otros dispositivos.

Con esto, la entrega de datos a la computadora llegó a su fin. Los desarrolladores pueden depurarse, y puede hacer preguntas en los comentarios si algún tipo de paquete de datos no fue suficiente para una comprensión completa.

Mis transmisiones y el próximo episodio.


Últimamente fluí dos veces desde el laboratorio de soldadura de mi casa. Al principio solo mostré el proceso de soldadura y dije qué dispositivos uso. La segunda serie se dedicó al desarrollo en el STM32.

Las corrientes continúan. Este viernes a las 19:00, mi colega del equipo de desarrollo de soluciones de hardware Andrey Laptev organizará un análisis en línea de Yandex.Stations Mini: muestre el interior y comparta historias de producción. Para más diversión, Andrey atornillará la batería a la columna; no todo es lo mismo, funciona desde el cable. En la final, recibirá una guía que le permitirá repetir esta experiencia usted mismo o crear un diseño más interesante.

Regístratepara ver la corriente Recibirá una carta con un archivo para el calendario y un recordatorio en el día de emisión. ¡Gracias por leer!

All Articles