Esperemos que este sea el subtítulo correcto 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.
Algún prólogo:
A partir de ahora, 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 un bypass de DSP simple (entrada de códec -> mcu -> salida de códec), el audio está libre de fallas y es increíble. Sin embargo, cuando habilito USB, es cuando las cosas se ponen raras. Obtendré fallas ocasionales y la señal a veces se repite. No estoy totalmente seguro de si esto se debe a que no estoy usando suficientes búferes cuando escribo en USB.
En este momento, mis lecturas de códec y las 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 calculo las longitudes de mis fotogramas:
#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 fluctuación debido a que las tasas de códec MCLK y USB CLK son diferentes (11.2896 frente a 12). Solo adivino esto porque las interrupciones/problemas ocurren periódicamente. También he notado que los búferes de códec "alcanzan" a los búferes USB de vez en cuando (el búfer de 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. Obviamente, tampoco puedo acelerar las transferencias USB... 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 audio USB y sincronización, ¡se agradecería su ayuda! No estoy seguro de cómo abordar el problema desde aquí honestamente. Sin embargo, si se lo pregunta, la salida de audio USB está bien (con la excepción de algunos canales que no están sincronizados).
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 fotogramas en el lado USB, suponiendo que la frecuencia de muestreo de audio (es decir, el códec de 11,2896 MHz reloj) 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 que hace referencia al reloj USB. De hecho, pueden ser diferentes en decenas o incluso en centenas de ppm, dadas las tolerancias habituales asociadas con los cristales de uso general.
En su lugar, debe elegir la longitud del marco USB de forma dinámica, en función de la cantidad real de datos que tiene en los búferes 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 real definida por el reloj del códec.
pjc50
Yun
rdtsc
Yun
pjc50