Tuesday, October 25, 2016

Teensy Audio over USB

In my last post, where I sent my first analog audio through a Teensy, I also discovered that it has the ability to exchange digital audio over its USB link.  Whoa.  This means that, if I'm developing some snazzy new audio-processing algorithm, I can test it 100% digitally without adding any complications of converting back and forth through analog signals.  That is a really powerful capability that'll greatly simplify my audio development.  Let's see if it really works!


Discovering USB Audio:  I only discovered that the Teensy might be able to do USB Audio while using their web-based graphical tool.  This is a tool that the Teensy folks ahve created to help people work with their Audio Library.  While using that tool, I noticed that there were input/output blocks named "USB".  Does this mean that Teensy can exchange audio over USB?!?  Really?  That's a pretty advanced feature for an electronics board aimed at hobbyists!  Does it work?

A Simple USB Audio Chain:  To give it a try, I configured an audio chain as shown below: one stereo USB input connected to one stereo USB output.  The left channel is just connected straight across -- no processing.  For the right channel, though, I've inserted a Biquad filter block just so that I can confirm that the Teensy is indeed doing something to the audio.  It's a pretty simple setup.


It Didn't Work:  When I exported the audio chain above, loaded it onto the Teensy, and gave it a try, it didn't work.  I got silence.  I don't know why.  So I started messing around...

Making it Work:  To get the USB Audio to work, I found that I had to engage the audio board's hardware in some way.  One way to make it work is shown below: add a SGTL5000 block for the Audio Board, and add an I2S block to be the output of the Audio Board.  I connected the I2S output to be just like the USB output.  Now, whatever the Teensy is sending out via USB will also be present at the headphone jack.  Sure, it seems like an unnecessary complication if I just want to use USB for my audio, but it's kinda cool that it's so easy to output to multiple targets simultaneously.


Completing the Arduino Code:  The graphical web-based tool shown above doesn't produce a complete program to load onto the Teensy -- it just gets you started.  When I hit the "Export" button, it gave me all of the code to setup the hardware and make the connections, but I still needed to write the last bit of code to make it run.  As usual, I did my coding in the Arduino IDE because it's easiest.

My Code:  The screenshot below shows the Arduino sketch that I used for this demo (it's on my GitHub here).  At the top is the big block of code that was exported from the web-based tool.  Easy.  Then, at the bottom, I added the setup() and loop() functions.  As you can see, the setup() function configures the SGTL5000 audio board and it sets the biquad filter to be a low-pass filter at 500 Hz.  The loop() function does nothing.


Tell the Compiler about USB Audio!  The only trick to using the USB audio is that you need to tell the compiler that you want the Teensy to run in USB Audio mode.  So, prior to compiling and uploading this Arduino sketch, go under the "Tools" menu, click on "USB Type" and select "Audio".  Notice that there are many other choices, including "Serial", "Keyboard, "MIDI", "Audio" and "No USB".   Normally, one uses "Serial" so that Serial.println() is able to print messages to the Serial Monitor.  But, for this demo, I want "Audio".


Loading onto the Teensy:  Once you change the USB setting to Audio, you can compile and upload to the Teensy.  The first time you do it, it'll probably upload to the Teensy without any issue.  Great!  But, once it is in USB Audio mode, future programs won't appear to upload automatically.  Why?  Well, once the USB link set for Audio, the Teensy can't get reprogramming commands over that same USB link.  What's the solution?  After the Arduino IDE has finished compiling, simply press the Teensy's reset button (picture below).  After a reset, the Teensy knows to check in with the PC prior to switching over to Audio mode.  It will automatically get any new program waiting for it.  It's a small extra step, but I didn't find it to be a problem at all.


Testing Using Audacity:  Once the Teensy is in USB Audio mode, the Teensy appears to your PC as if it is a soundcard.  So, you can now send and receive audio data to it using any audio recording program.  For this demo, I used Audacity because it is free.

Configuring Audacity:  With the Teensy attached, my computer now has two soundcards: (1) its built-in soundcard and (2) the Teensy.  Once Audacity launches, I configured Audacity to use the Teensy as the soundcard instead of the built-in one.  The screenshot below shows the five settings that I changed in Audacity.  On my computer (Windows 7), the Teensy cryptically appeared as "Digital Audio Interface (2-Tee" [sic], which wasn't as quite helpful as informative as it could have been, but it was good enough for me to choose the right item.


First USB Audio:  For this test, I'm want to send audio out over USB (to the Teensy) and record audio coming from USB (from the Teensy).  So, I need to start by creating a test signal to send out over USB.  Under the "Generate" menu, I chose "Chirp" and made a linear frequency sweep from 100 Hz to 4000 Hz.  This appeared as a single mono track in Audacity.  That's all the preparation that I needed to do.  Now, I simply hit the red record button.  Audacity started playing out the chirp audio to the Teensy while recording the audio coming back from the Teensy.  The result is shown in the screenshot below.


Success!  The screen shot shows two audio files.  Both files are shown in "spectrogram" view (60 dB dynamic range).  The top file contains the original (mono) frequency sweep generated by Audacity.  This is what was sent to the Teensy over the USB Audio link.  The bottom file shows the stereo audio recorded from the Teensy.  The left channel had no processing being performed by the Teensy and it does indeed appear to be a copy of the original signal.  The right channel, though, was being processed by the Teensy by its 500 Hz low-pass biquad filter.  As can be seen, the high frequencies are attenuated -- the gentle roll-off is as expected from a biquad filter.  This was amazingly easy!

Future Use:  While I'm very impressed that this capability exists at all, it's not perfect.  In additional testing, I occasionally found hiccups or other artifacts in the audio stream coming back from the Teensy.  But, most of the time, this USB Audio link worked really well.  It'll be great for debugging my audio projects.  Anytime I have any question about the negative effects of my analog components, I can simply switch over to USB Audio to avoid the whole problem.  It'll be a great tool to have in my audio hacking toolbox.

10 comments:

  1. Thanks Chip~~~!!
    This is exact what I was looking for.
    I am gonna check it out.. waiting for the shipping to arrive.

    ReplyDelete
  2. This comment has been removed by a blog administrator.

    ReplyDelete
  3. This comment has been removed by a blog administrator.

    ReplyDelete
  4. This comment has been removed by a blog administrator.

    ReplyDelete
  5. This comment has been removed by a blog administrator.

    ReplyDelete
  6. This comment has been removed by a blog administrator.

    ReplyDelete
  7. Hello did you also try to send an audio signal through line in to USB and listening it from usb to headphone ? I tried and the sound is very distorted and with also some vibrato effect in it.
    thanks,
    Dom

    ReplyDelete
    Replies
    1. This comment has been removed by a blog administrator.

      Delete
  8. I haven't yet tried USB as input to my Teensy 4.0 board & shield. I used the SD card and AudioPlaySDWav option instead. The Audacity was only on the Teensy USB output. No hiccups found. I saw a very slight degradation caused by async sample rate conversions on the Teensy USB output->Audacity input path.

    ReplyDelete
  9. Hello, stumbling across this years late, but, may I ask what the sample rate of the USB input from the Teensy appears as in Windows? Looking for 96 / 192kHz to reduce latency in a kinda-hacky system

    ReplyDelete