Close

USB

A project log for Cortex Guitar Board

Audio DSP board based on a Cortex-M4 microcontroller for experimenting with things like guitar effects and sound synthesis.

jonas-norlingJonas Norling 08/20/2016 at 16:223 Comments

It turned out to be a bit tricky to get a stable and working USB connection, but I think I've got it now. There have been issues with interrupt priorities, device descriptors, buffer sizes, …
I have implemented an ACM "serial port", where log messages can be sent to the host, and an audio interface that essentially presents a stereo microphone to the host. This works well and stable when talking to a Linux computer, and I have had the chance to test the ACM serial port on MacOS (where it turns out to be hard to find a program that is happy to handle lines with a simple \n ending from a serial port).

One tricky thing that I haven't solved yet is synchronisation between the two clock domains (USB host and audio sampling clock), which shows up as glitches in the audio stream at regular intervals.

Code at GitHub, as usual.

Baudline showing audio stream received over USB

Discussions

Michele Perla wrote 08/26/2016 at 15:11 point

This project is gettin better and better, kudos to you.

For the clock sync, you should check out the sync endpoints specified in the USB audio device class specs; though bear in mind that it is simply not supported by mac os. for more info, you might want to check out the USB audio implementation on the Teensy. @Paul Stoffregen did an amazing job on that, as always.

  Are you sure? yes | no

Paul Stoffregen wrote 08/26/2016 at 15:36 point

The sync feedback has been sort-of fixed.  It now correctly "works" on macintosh.

However, it turns out Apple's driver code can't adapt to more than 10 Hz deviation, for 44.1 kHz.  Our nominal sample rate (plus or minor slight variation from the crystal's tolerance) on Teensy is 44117 Hz, which is just 7 Hz too much for Apple's driver to manage.

Eventually I will redo it all to switch from async to adaptive mode, and do the sample rate adjustment on the Teensy side.  But that's a big project that won't happen in 2016.  Maybe next year?

In the meantime there's a ugly kludge in the code which can be enabled by editing a #define.  It restricts Teensy from reporting more than Apple's driver can handle.  The result is occasional buffer underruns which result in minor audio glitches, but nothing so horrible as how Apple's driver butchers the sound (after a few minutes) when asked to adapt by more than 10 Hz.

  Are you sure? yes | no

Jonas Norling wrote 09/03/2016 at 11:52 point

Thanks for the pointers, guys.

USB audio really is a complex beast, and after reading up on the matter it's clear that making a well behaved implementation would not be a trivial project :-)

That's not really my goal, though. I now have a working "line in" implementation, that can feed sound to the USB host but not the other way around, and I'm pretty content with that. It's running in asynchronous mode, so the device sets the pace (nominally 47991 Hz) and the computer just has to live with that. It works on Linux/ALSA, but MacOS doesn't even seem to like my device descriptors (asserts in the syslog). I hope that can be fixed with some trial and error, and by looking at the Teensy code, but I'm saving that for a rainy day…

  Are you sure? yes | no