USB Audio samplerates added

Would be great if some users test it :)

Edit: Might be that Windows is bitchy and does not recognize the sample rate correctly. In this case, try to remove the teensy usb device from the registry and/or reboot Windows.

How to change the samplerate:
Open AudioStream.h and edit this line:

#define AUDIO_SAMPLE_RATE_EXACT 44100.0f

(keep the "f")
 
Last edited:
Hey Frank,

This is awesome!

Does this change the entire library? Or just the USB Audio?

Jay

Not sure what your question is:)
The #define AUDIO_SAMPLE_RATE_EXACT changes the whole library, yes. But this has always been possible.

USB Audio did not support that. That's what I changed.
There may still be some parts that don't work (these would have to be pretty hidden), but I'm pretty confident that there won't be any major problems.
USBAudio was the last part I know of that didn't work.
Edit: No, the waveplayer will still accept 44.1khz files only.


However, Paul needs to merge my pullrequest - or you have to use my "cores" directory.
 
Last edited:
Now would be a good time to fix the poor control algorithm for samples requested from the PC. Specifically:

> if (f) feedback_accumulator += 3500;

This suffers from integral windup which causes horribly audible problems until the value comes back down. It works well without this line at all, but possibly "if (f && c) ..." would also fix it.

> feedback_accumulator += diff * 1;

This does a poor job of controlling the number of samples in the incoming buffer. And may request a violation of this:

"Section 2.3.1.1 of the Audio Data Formats 2.0 Specification limits variation in the packet size by +/- 1 sample frame"


I've tested with dithering between two moderate values and it maintains tighter control of the number of samples in the incoming buffer.

Code:
if (diff > 0)
                        feedback_accumulator = 44.2 * (1<<24);       // faster
                else
                        feedback_accumulator = 44.0 * (1<<24);       // slower

Of course this would require modification for different sample rates. I think something like:

Code:
if (diff > 0)
                        feedback_accumulator = (rate * 1.0025 / 1000) * (1<<24);       // faster
                else
                        feedback_accumulator = (rate * (1-.0025) / 1000) * (1<<24);       // slower

Where the .0025 is from the USB spec (full speed) for max clock error.
 
Last edited:
Interesting, for me the existing algorithm works good - good enough that i can't hear any artifacts.
What OS do you use?
 
I use pulseaudio with Linux. The windup issue has something to do with unused audio devices being put to sleep while not in use. Possibly the PC sends USB packets that are empty? So "f" is true and the teensy keeps ramping up feedback to request ever more samples per packet. Then the PC starts sending valid audio and the feedback value is unreasonable for several minutes.

Always monitor underruns and overruns. And ideally the diff values. But I'm not surprised that most systems work OK.
 
I can't test this- maybe it's better to do this in a separate pullrequest(?!) (you?)
There is also no direct connection with the sample rate.
 
I agree, a mostly separate issue. But on the other hand, I'm guessing that the concern with such a change is testing across lots of platforms and rates - which your code also needs. So convenient to combine them and test at the same time. I'm currently running this and it works. This has the side effect of nullifying the "+= 3500" windup problem.

Code:
                if (diff > 0)
                        feedback_accumulator = AUDIO_SAMPLE_RATE_EXACT * (1 + .0025) / 1000 * (1<<24);       // faster
                else
                        feedback_accumulator = AUDIO_SAMPLE_RATE_EXACT * (1 - .0025) / 1000 * (1<<24);       //  slower
 
Hi Frank,

I need my hand held a bit on this. I'm only used to installing the core stuff from the Teensyduino installer.

To try your stuff, do I need to download your whole repo and drop it on top of the current cores installation?

Or, can I only grab one or two files?

(Grabbing just one or two will also make it easier to undo my changes to get back to a standard cores setup)

Chip
 
Thanks!

Btw, high sample rates might not be relevant for audible audio but the high sample rates are very helpful when exploring ultrasound (mice, rats, bats) or when delightfully mis-using the audio library for generic signal processing. Having a live USB audio connection is / would be super useful!
 
Thanks!

Btw, high sample rates might not be relevant for audible audio but the high sample rates are very helpful when exploring ultrasound (mice, rats, bats) or when delightfully mis-using the audio library for generic signal processing. Having a live USB audio connection is / would be super useful!

Perhaps just try if it works :)
 
I just tried at 44.1kHz by recording audio from my Tympan via USB to the PC. I used the microphones on-board the Tympan and talked into them. I recorded the audio on the PC in Audacity.

I confirmed that 44100 Hz works.

I then tested at 96000 Hz and it didn't work. Data streamed into Audacity and it recorded, but the audio was all distorted. There was clearly my voice in there, but it was very distorted. I then whistled, which should be sorta like a sine wave. Here's what I got:

whistle_96kHz.jpg

Notice that the waveform is definitely chopped up. The spacing between discontinuities is about 96 samples. That is a weird number considering the block size is 128...but I don't know what the block size is over the USB. Maybe it's a very obvious number.


My question: when using the standard Teensy Audio Board, how do you recommend that one tell the hardware what the new sample rate is? One needs to set the I2S clocks, right? Do the I2S clocks get set correctly based on the SAMPLE_RATE_EXACT used in AudioStream? Or does one need to manually command different I2S mult/div values?

For my Tympan, I know how to change the sample rate...and I did so...but I got distorted results. I have run Tympan at 96 kHz many times, so I know that the Tympan runs fine at 96 kHz. But, maybe there is an incompatibility between my stuff and your stuff that has nothing to do with your mods. So, I'd like to try your stuff with as little Tympan stuff as possible. How does one change the sample rate of the hardware when using the Teensy Audio Board?

Chip
 
My question: when using the standard Teensy Audio Board, how do you recommend that one tell the hardware what the new sample rate is? One needs to set the I2S clocks, right? Do the I2S clocks get set correctly based on the SAMPLE_RATE_EXACT used in AudioStream? Or does one need to manually command different I2S mult/div values?

Hi Chip... no... it does not work this way.
USB does not accept "dynamic" change of the samplerate.
The way is to edit Audiostream.h and enter the samplerate there. Then, a clean compile.

It still may happen that Windoes is too dumb.. it caches some things in the registry. I've seen this several times.
In this case, the easiest way ist to unplug the Teensy and use an other USB port.
And take a look at the audio control panel of the Teensy device. Sometimes a disable/enable sequence is needed, or one has to choose the (deselected?) samplerate again.
You have to close all Windows programs that use audio, too. Or, better, reboot.

But... when it works, it works :) It needs to be done one time only.
 
So I don't need to do anything to tell the I2S classes that the sample rate is different than 44100? The classes use AUDIO_SAMPLE_RATE to set the mult/div parameters correctly?

Chip
 
So I don't need to do anything to tell the I2S classes that the sample rate is different than 44100? The classes use AUDIO_SAMPLE_RATE to set the mult/div parameters correctly?

Chip

Yes.
Did I mention we're talking about Teensy 4.x /mm only?
(first line in Post#1 :) )
 
It still may happen that Windoes is too dumb.. it caches some things in the registry. I've seen this several times.
In this case, the easiest way ist to unplug the Teensy and use an other USB port.
And take a look at the audio control panel of the Teensy device. Sometimes a disable/enable sequence is needed, or one has to choose the (deselected?) samplerate again.
You have to close all Windows programs that use audio, too. Or, better, reboot.

I can no longer get the USB Audio to work at any sample rate (in Audacity)...neither 44100 nor 96000. I've tried different USB ports and I've tried rebooting. I've tried enable/disable in Windows Device Manager. Surely, there must be some magical combination of actions to get Windows to cooperate with me (since I did get 44100 to work earlier) but so far I've had no luck.

I'm giving up. Struggling with Windows is not my idea of a good time. Sorry.
 
Would be great if some users test it
Hallo Frank, sorry for stepping late into the party...
Freshly installed Arduino 1.8.15 & Teensyduino 1.54 on Windows 10 Home. Did not yet copy the modified files from https://github.com/FrankBoesing/cores/tree/USBAudio-samplerates.
Using a PCM5102 board and a Teensy 4.0 [don't have a T4.1].
Ran this sketch on the setup:
Code:
// PCM5102 bd   Teensy 3.x    Teensy 4.x
// VCC          Vin           Vin           5V
// GND          GND           GND
// LRCK         23            20 [ 3]       44.1 KHz
// DATA         22             7 [ 2]       [xx] for secondary I2S bus
// BCK          9             21 [ 4]       2.8224 MHz = 64.LRCK
// --           11            23 [33]       MCLK 11.29 MHz
// set Tools > USB Type to Audio

#include <Audio.h>

AudioInputUSB            usb1;
AudioOutputI2S           i2s1;
AudioConnection          patchCord1(usb1, 0, i2s1, 1);
AudioConnection          patchCord2(usb1, 0, i2s1, 0);

void setup() {
  AudioMemory(12);
}

void loop() {
}

Using an sine-generator program running on the PC showed a nice 1kHz sine on the scope.

Then copied the teensy4 directory from Franks GitHub link into C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores, to overwrite with the 5 modified files.

Recompiled the same sketch leaving the samplerate at 44.1kHz. Sine wave looked OK again on the scope.

Then modified audiostream.h line 58 to "#define AUDIO_SAMPLE_RATE_EXACT 48000.0f" and recompiled/uploaded.

Two observations:
1. the Sound control panel looked like this:

Capture.PNG

Notice that the "Default Format" still shows "2 channel, 16 bit, 44100 Hz (CD Quality)". I expected 48000 Hz.

2. The sine wave is now corrupted:

SDS00042.png

Is this perhaps caused by what Jonr mentioned in his post above?

Please let me know what you want me to test next.

Gruesse,
Paul
 
Yes, i'd expect 48KHz in the panel, too. So, something is wrong. I've seen this working on my computer, so.. looks like windows problem?
 
Back
Top