Intersección de entrada de audio USB (?)

1

Esperemos que este es el sub derecho para hacer esta pregunta. De todos modos, estoy trabajando en un dispositivo de audio USB en un microcontrolador y tengo problemas para obtener una entrada de audio consistente.

Algunos prefacio:

En este momento, he conectado el mcu y el códec a través de I2S (el códec es esclavo) con las siguientes configuraciones:

MCLK = 11.2896 MHz
BCLK = 2.8224 MHz
LRCLK = 44.1 kHz
USB CLK = 12 MHz

Cuando hago una derivación DSP simple (entrada de códec - > mcu - > salida de códec), el audio está libre de fallas y es impresionante. Sin embargo, cuando habilito USB, es cuando las cosas se ponen extrañas. Voy a tener fallos ocasionales y la señal a veces se repite. No estoy totalmente seguro de si esto se debe a que no estoy utilizando suficientes búferes cuando escribo en USB.

En este momento, mis lecturas de códecs y escrituras USB se realizan por separado:

Codec Flow: Codec Input -> MCU I2S RX -> DMA Interrupt when I2S RX buffer is full 
            -> Write this buffer into USB buffers -> Calculate next input frame len

USB: USB initiates input -> Write buffer to USB endpoint -> USB Write Callback 
     called when USB transfer is complete -> Start reading next buffer

Cómo estoy calculando las longitudes de mis cuadros:

#define AUDIO_POLL_INT     4
#define FRAME_BYTES        3
#define NUM_CHANNELS       STEREO

// Calculate the frame length
uint16_t frame_len = 44 (44.1kHz/1000 samples) * NUM_CHANNELS * FRAME_BYTES;
// Every 10 ms, calculate frame length with additional frame (only applies to 44.1kHz sample rate)
if (!(frame_pos % 9)) frame_len += (1 * NUM_CHANNELS * FRAME_BYTES)

// Increment frame position per usb call
frame_pos = (((frame_pos + 1) / 8) * (2 << (AUDIO_POLL_INT-1))) % 10;
frame_pos = (frame_pos + 1) % 10;

Pregunta real / ¿Qué creo que va mal (?)

Supongo que hay algunos problemas de inestabilidad debido a que las tasas del códec MCLK y USB CLK son diferentes (11.2896 vs 12). Solo estoy adivinando esto porque las interrupciones / fallas ocurren bastante periódicamente. También me he dado cuenta de que los búferes del códec se "alcanzarán" a los búferes de USB de vez en cuando (el búfer del códec sobrescribirá un búfer USB aunque el búfer USB esté marcado como "lleno"). Sin embargo, no estoy seguro de cómo evitar que esto suceda porque el códec se desincronizaría y perdería los datos de audio. Tampoco puedo acelerar las transferencias USB ... obviamente, estoy transfiriendo un máximo de 270 bytes por escritura USB para una frecuencia de muestreo de 44.1 kHz.

¡Si alguien ha tenido experiencia con el audio y la sincronización USB, agradeceríamos su ayuda! No estoy seguro de cómo abordar el problema desde aquí con honestidad. Si te estás preguntando, la salida de audio USB está bien aunque (con la excepción de algunos canales que no están sincronizados).

    
pregunta yun.cloud

1 respuesta

3

Es difícil estar seguro (ya que obviamente este no es su código real), pero parece que ha codificado el patrón de longitudes de trama en el lado USB, suponiendo que la frecuencia de muestreo de audio (es decir, la El reloj de códec de 11.2896 MHz) está estrictamente bloqueado a la velocidad de datos USB (es decir, el reloj USB de 12.000 MHz). Esto solo sería cierto si el reloj del códec estuviera controlado por un PLL al que se hace referencia al reloj USB. De hecho, pueden ser diferentes en 10 o incluso en 100 ppm, dadas las tolerancias habituales asociadas con los cristales de uso general.

En su lugar, debe elegir dinámicamente la longitud del marco USB, en función de la cantidad real de datos que tiene en los buffers locales que ha recibido del códec. Si este total está por encima de algún umbral, debe enviar el marco USB más largo; De lo contrario, envíe el marco USB más corto. Esto permite que la velocidad promedio de las transferencias USB rastree la frecuencia de muestreo actual definida por el reloj del códec.

    
respondido por el Dave Tweed

Lea otras preguntas en las etiquetas