AnsweredAssumed Answered

USB Audio Asynchronous Source endpoint won't sync...

Question asked by bassmati on Jul 25, 2013
Latest reply on Jul 31, 2013 by bassmati
Hello everyone,

I'm currently working on a USB application on a STM32F103, using the Audio Class, and after some work and extensive reading (USB specification and Audio Class specification of course, + several examples and discussions), I am stuck.

First, my system : it's a custom board, with an ADC/DAC, a DSP and an MCU (STM32F103). The analog audio is converted by the ADC (clocked by a local oscillator on the board), treated by the DSP, and sent to the DAC and the MCU. The audio format is 48 kHz, 24 bits, single channel (mono).

All of this works fine. In fact, all of this has been working fine for a few years now, this is an old board already in production. The USB audio will be a new feature on an old product.

What I want is to source this audio stream into my computer. I want my board to be recognized as a standard soundcard by my OS (Windows on my workstation, but Mac OS compatibility will be needed in the future), using the standard audio class driver.

I programmed a set of descriptors that seems ok. The device is recognized by Windows, the driver installs nicely, and I can listen to the audio stream on my speakers. I experimented a little with alternate settings, a few different bit reslution, sample rate, everything went ok.

I started with a synchronous endpoint, and I got the sound right. But of course the drift between the USB clock and my local clock resulted in audio clicks every few seconds. So I tried setting the endpoint as asynchronous. But so far, without success.

My endpoint is an "asynchonous source", so I should provide "implicit feedforward" by dynamically changing the number of samples I send to the host. That's what I'm currently trying to do.

Using 2 timers, I'm getting the period of the the local and USB (SOF) clock. By comparing them, I know if the local clock is late or early with respect to the USB SOF clock. I implemented a mechanism that usually sends 48 samples, and, depending on the clock relationship, sometimes send 47 or 49 samples. This mechanism seems to work, I observed the "47 samples" or "49 samples" event occuring more or less frequently as I moved the local clock around the USB clock. But that's it : the audio is still the same, drifting slowly until I get clicks.

----

From my point of view, this asynchronous behaviour requests an "asynchronous sample rate converter" (ASRC) to be dealt with correctly, and on some level, I doubt there's such a thing in the windows driver. But it seems the usbaudio.sys driver actually does support this.

Would it be of any help if I tried the explicit feedback approach, which is needed for an async sink ?

Does anyone have a code example (not necessarily on a ST chip) implementing such a function ? I only found sink examples (USB Speakers usually, including the one provided by ST), or source example working with synchronous endpoint (or claiming to be asynchronous but really working as synchronous).

Do you know a small software that would allow me to check my descriptors from my computer ? To check the host does get them right.

Anyway, I would be thankful for any input on the subject. I can provide specific parts of my code if needed.

Outcomes