Linux Usb audio issue with Teensy 4.1

docB

Member
Hi i am new to teensy, have a teensy 4.1 and made a small sketch
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

AudioSynthWaveformSine   sinewave;
AudioOutputI2S           i2s2;
AudioOutputUSB           usb1;
AudioConnection          patchCord1(sinewave, 0, usb1, 0);
AudioConnection          patchCord2(sinewave, 0, usb1, 1);
float baseFreq=110;

void setup() {
  AudioMemory(20);
  sinewave.frequency(baseFreq);
  sinewave.amplitude(0.5);
}

void loop() {
}

Then on linux i run
arecord -D "hw:6" test.wav -c 2 -r 44100

Then in the recorded wav is a sine wave but with glitches, they look like this:


1711130462769.png

I never had this problem with other usb audio interfaces on linux (however all other interfaces run on 48000HZ).
So the question is: what did i miss here?
Thanks!
 
Hi, at the screenshot it looks like you encounter buffer overruns on the the teensy. That means the Teensy generates audio samples too fast, the buffer of the usb output on the Teensy fills up until some samples need to be discarded. If that is true, then there is not much you can do about it.

I am currently testing a new implementation of the usb audio in- and output for the T4.1 that might solve your problem. I only tested it in combination with Windows and I would be very curious if it also works with Linux.
If you like to try out this new version then:
1. You need to use Teensyduino 1.59.
2. Make a back up copy of the T4 core files of your Teensyduino installation. Just save a copy of the folder cores/teensy4 so that you can restore the original states.
3. Clone or download the new usb audio implementation from https://github.com/alex6679/teensy-4-usbAudio
4. Copy all files from the changedCorefiles-folders into the cores/teensy4 folder
5. You can again use the short example you posted above to test the new implementation.

The new usb audio output provides 8 audio channels. If there are any problems, you can reduce the number of channels. Just change USB_AUDIO_NO_CHANNELS_480 from 8 to 2 in usb_desc.h line 981. I mention that because I first used Audacity in Windows to record data and to test the usb output. When I first switched from 2 to 8 channels, the recorded audio signal was completely distorted. It turned out that it was a problem of Audacity and not the Teensy.
 
Hi thanks for your reply and great initiative it would be great to have 8 audio input channels.
Unfortunately with your changes there is no card shown anymore on my ubuntu system and i cannot record audio.

It should be listed as before
Code:
card 6: MIDIAudio [Teensy MIDI/Audio], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
but it is not.

However teensy is shown as usb device via lsusb, and there is at least an usbstream listed:
Code:
usbstream:CARD=MIDIAudio
    Teensy MIDI/Audio
    USB Stream Output

but i think it should look like the Komplete Audio 6 (this interface has 6 inputs and 6 outputs)
Code:
hw:CARD=K6,DEV=0
    Komplete Audio 6, USB Audio
    Direct hardware device without any conversions
plughw:CARD=K6,DEV=0
    Komplete Audio 6, USB Audio
    Hardware device with all software conversions
usbstream:CARD=K6
    Komplete Audio 6
    USB Stream Output

Another point is that i managed to tweak the files via this method
to have finally 48KHZ, this worked perfect but there is the same problem with audio glitches.
and it would be cool to have a switch to 48KHZ in your code, too.


:
 
It would have been too good if my implementation had just worked on Linux as well. Which Ubuntu version do you have? Maybe I can reproduce the problem in a virtual machine.
Changing my usb in- and output to 48kHz is quite simple. Just change AUDIO_SAMPLE_RATE_EXACT and AUDIO_SAMPLE_RATE_I in AudioData.h from 44100.0f and 44100 to 48000.0f and 48000.
 
i have a ubuntu 20.04 with a 5.4 linux kernel. thats great having a simple switch between the sample rates!
 
I was a little bit impatient yesterday and already downloaded an Ubuntu image (kernel 6.5 ubuntu 22.04). I thought chances are high that it is not so critical which Ubuntu version I use and indeed the usb input and output do not work.
I had a look into the log file /var/log/dmesg and found two log messages that may give a hint what the problem is:
[ 18.636054] kernel: usb 2-1: 4:1 : bogus bTerminalLink 2
[ 18.636852] kernel: usb 2-1: 5:1 : bogus bTerminalLink 3
Can you also have a look into /var/log/dmesg and check if you have the same log messages?
I searched in the linux kernel code for this log messages in order to find out what the problem is and I think I found the relevant code in https://github.com/torvalds/linux/blob/v6.5/sound/usb/stream.c in line 794.
When I have time in next days I will try to find out what the exact problem is. If somebody has an idea about what causes the problem I would of course appreciate any input.
By the way, I fixed a small bug related to the usb communication between host and the Teensy in my code in usb.c. The bug does not seem to have any impact if the host OS is Windows 10 or 11. However, it caused a problem in Linux, when I ran "./alsa-info.sh".
 
hi may be this helps:
Code:
Mar 25 15:13:04 docb-ubuntu kernel: [201964.371471] usb 1-6.1: new high-speed USB device number 63 using xhci_hcd
Mar 25 15:13:04 docb-ubuntu kernel: [201964.509973] usb 1-6.1: New USB device found, idVendor=16c0, idProduct=1496, bcdDevice= 2.80
Mar 25 15:13:04 docb-ubuntu kernel: [201964.509976] usb 1-6.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
Mar 25 15:13:04 docb-ubuntu kernel: [201964.509978] usb 1-6.1: Product: Teensy MIDI/Audio
Mar 25 15:13:04 docb-ubuntu kernel: [201964.509979] usb 1-6.1: Manufacturer: Teensyduino
Mar 25 15:13:04 docb-ubuntu kernel: [201964.509980] usb 1-6.1: SerialNumber: 15235610
Mar 25 15:13:04 docb-ubuntu kernel: [201964.523086] cdc_acm 1-6.1:1.0: ttyACM0: USB ACM device
Mar 25 15:13:04 docb-ubuntu kernel: [201964.532340] usb 1-6.1: 4:1 : bogus bTerminalLink 2
Mar 25 15:13:04 docb-ubuntu kernel: [201964.533976] usb 1-6.1: 5:1 : bogus bTerminalLink 3
Mar 25 15:13:04 docb-ubuntu kernel: [201964.537961] usb 1-6.1: cannot get ctl value: req = 0x83, wValue = 0x201, wIndex = 0x3102, type = 4
Mar 25 15:13:04 docb-ubuntu kernel: [201964.537965] usb 1-6.1: 49:2: cannot get min/max values for control 2 (id 49)
Mar 25 15:13:04 docb-ubuntu kernel: [201964.584991] usb 1-6.1: cannot get ctl value: req = 0x83, wValue = 0x201, wIndex = 0x3102, type = 4
Mar 25 15:13:04 docb-ubuntu kernel: [201964.584994] usb 1-6.1: 49:2: cannot get min/max values for control 2 (id 49)
Mar 25 15:13:04 docb-ubuntu kernel: [201964.586976] usb 1-6.1: cannot get ctl value: req = 0x83, wValue = 0x201, wIndex = 0x3102, type = 4
Mar 25 15:13:04 docb-ubuntu kernel: [201964.586978] usb 1-6.1: 49:2: cannot get min/max values for control 2 (id 49)
Mar 25 15:13:04 docb-ubuntu kernel: [201964.588989] usb 1-6.1: cannot get ctl value: req = 0x83, wValue = 0x201, wIndex = 0x3102, type = 4
Mar 25 15:13:04 docb-ubuntu kernel: [201964.588991] usb 1-6.1: 49:2: cannot get min/max values for control 2 (id 49)
Mar 25 15:13:04 docb-ubuntu kernel: [201964.590978] usb 1-6.1: cannot get ctl value: req = 0x83, wValue = 0x201, wIndex = 0x3102, type = 4
Mar 25 15:13:04 docb-ubuntu kernel: [201964.590981] usb 1-6.1: 49:2: cannot get min/max values for control 2 (id 49)
Mar 25 15:13:04 docb-ubuntu kernel: [201964.592988] usb 1-6.1: cannot get ctl value: req = 0x83, wValue = 0x201, wIndex = 0x3102, type = 4
Mar 25 15:13:04 docb-ubuntu kernel: [201964.592992] usb 1-6.1: 49:2: cannot get min/max values for control 2 (id 49)
Mar 25 15:13:04 docb-ubuntu kernel: [201964.595006] usb 1-6.1: cannot get ctl value: req = 0x83, wValue = 0x201, wIndex = 0x3102, type = 4
Mar 25 15:13:04 docb-ubuntu kernel: [201964.595012] usb 1-6.1: 49:2: cannot get min/max values for control 2 (id 49)
Mar 25 15:13:04 docb-ubuntu kernel: [201964.597021] usb 1-6.1: cannot get ctl value: req = 0x83, wValue = 0x201, wIndex = 0x3102, type = 4
Mar 25 15:13:04 docb-ubuntu kernel: [201964.597025] usb 1-6.1: 49:2: cannot get min/max values for control 2 (id 49)
Mar 25 15:13:04 docb-ubuntu kernel: [201964.599088] usb 1-6.1: cannot get ctl value: req = 0x83, wValue = 0x201, wIndex = 0x3102, type = 4
Mar 25 15:13:04 docb-ubuntu kernel: [201964.599092] usb 1-6.1: 49:2: cannot get min/max values for control 2 (id 49)
Mar 25 15:13:04 docb-ubuntu kernel: [201964.601002] usb 1-6.1: cannot get ctl value: req = 0x83, wValue = 0x201, wIndex = 0x3102, type = 4
Mar 25 15:13:04 docb-ubuntu kernel: [201964.601006] usb 1-6.1: 49:2: cannot get min/max values for control 2 (id 49)
Mar 25 15:13:04 docb-ubuntu kernel: [201964.602978] usb 1-6.1: cannot get ctl value: req = 0x83, wValue = 0x201, wIndex = 0x3102, type = 4
Mar 25 15:13:04 docb-ubuntu kernel: [201964.602982] usb 1-6.1: 49:2: cannot get min/max values for control 2 (id 49)
Mar 25 15:13:04 docb-ubuntu kernel: [201964.604990] usb 1-6.1: cannot get ctl value: req = 0x83, wValue = 0x201, wIndex = 0x3102, type = 4
Mar 25 15:13:04 docb-ubuntu kernel: [201964.604995] usb 1-6.1: 49:2: cannot get min/max values for control 2 (id 49)
Mar 25 15:13:04 docb-ubuntu kernel: [201964.606988] usb 1-6.1: cannot get ctl value: req = 0x83, wValue = 0x201, wIndex = 0x3102, type = 4
Mar 25 15:13:04 docb-ubuntu kernel: [201964.606992] usb 1-6.1: 49:2: cannot get min/max values for control 2 (id 49)
Mar 25 15:13:04 docb-ubuntu kernel: [201964.609004] usb 1-6.1: cannot get ctl value: req = 0x83, wValue = 0x201, wIndex = 0x3102, type = 4
Mar 25 15:13:04 docb-ubuntu kernel: [201964.609008] usb 1-6.1: 49:2: cannot get min/max values for control 2 (id 49)
Mar 25 15:13:04 docb-ubuntu kernel: [201964.611009] usb 1-6.1: cannot get ctl value: req = 0x83, wValue = 0x201, wIndex = 0x3102, type = 4
Mar 25 15:13:04 docb-ubuntu kernel: [201964.611014] usb 1-6.1: 49:2: cannot get min/max values for control 2 (id 49)
Mar 25 15:13:04 docb-ubuntu kernel: [201964.612994] usb 1-6.1: cannot get ctl value: req = 0x83, wValue = 0x201, wIndex = 0x3102, type = 4
Mar 25 15:13:04 docb-ubuntu kernel: [201964.612999] usb 1-6.1: 49:2: cannot get min/max values for control 2 (id 49)
Mar 25 15:13:04 docb-ubuntu kernel: [201964.615116] usb 1-6.1: cannot get ctl value: req = 0x83, wValue = 0x201, wIndex = 0x3102, type = 4
Mar 25 15:13:04 docb-ubuntu kernel: [201964.615120] usb 1-6.1: 49:2: cannot get min/max values for control 2 (id 49)
Mar 25 15:13:04 docb-ubuntu kernel: [201964.617005] usb 1-6.1: cannot get ctl value: req = 0x83, wValue = 0x201, wIndex = 0x3102, type = 4
Mar 25 15:13:04 docb-ubuntu kernel: [201964.617009] usb 1-6.1: 49:2: cannot get min/max values for control 2 (id 49)
Mar 25 15:13:04 docb-ubuntu kernel: [201964.619010] usb 1-6.1: cannot get ctl value: req = 0x83, wValue = 0x201, wIndex = 0x3102, type = 4
Mar 25 15:13:04 docb-ubuntu kernel: [201964.619016] usb 1-6.1: 49:2: cannot get min/max values for control 2 (id 49)
Mar 25 15:13:04 docb-ubuntu kernel: [201964.621105] usb 1-6.1: cannot get ctl value: req = 0x83, wValue = 0x201, wIndex = 0x3102, type = 4
Mar 25 15:13:04 docb-ubuntu kernel: [201964.621109] usb 1-6.1: 49:2: cannot get min/max values for control 2 (id 49)
Mar 25 15:13:04 docb-ubuntu kernel: [201964.622981] usb 1-6.1: cannot get ctl value: req = 0x83, wValue = 0x201, wIndex = 0x3102, type = 4
Mar 25 15:13:04 docb-ubuntu kernel: [201964.622985] usb 1-6.1: 49:2: cannot get min/max values for control 2 (id 49)
Mar 25 15:13:04 docb-ubuntu kernel: [201964.625006] usb 1-6.1: cannot get ctl value: req = 0x83, wValue = 0x201, wIndex = 0x3102, type = 4
Mar 25 15:13:04 docb-ubuntu kernel: [201964.625010] usb 1-6.1: 49:2: cannot get min/max values for control 2 (id 49)
Mar 25 15:13:04 docb-ubuntu kernel: [201964.627019] usb 1-6.1: cannot get ctl value: req = 0x81, wValue = 0x201, wIndex = 0x3102, type = 4
Mar 25 15:13:04 docb-ubuntu kernel: [201964.628992] usb 1-6.1: cannot get ctl value: req = 0x81, wValue = 0x201, wIndex = 0x3102, type = 4
Mar 25 15:13:04 docb-ubuntu kernel: [201964.630993] usb 1-6.1: cannot get ctl value: req = 0x81, wValue = 0x100, wIndex = 0x3102, type = 1
 
That log output helped. I changed some things in the usb descriptors and now the my code provides similar results compared to the original code in the dmesg file. That means the 'bogus bTerminalLink' errors are solved and the Teensy is listed as device when I run 'arecord -l' or also 'aplay -l'. (At least with my Ubuntu version and if I compile either with the USB_MIDI_AUDIO_SERIAL or USB_AUDIO options.) I commited my changes. Can you please test if the new code also works with your Ubuntu?
 
So far this works perfect! Now i have 8 working inputs and the glitches are gone. Great effort, thanks.
 
I am glad that it works now. I have to admit I wasn't able to fully test the code. Even with the original usb input and output I wasn't able to e.g. generate a simple waveform that I can capture in my Ubuntu. In the end, I decided that the reason is probably related to my Ubuntu and not to the Teensy.
Can you also test how well it works regarding buffer over- and underruns?
If you add this code to your main loop, you could plot how the number of buffered samples changes over time:
Code:
  Serial.print(usb1.getBufferedSamples());
  Serial.print(" ");
  Serial.println(usb1.getBufferedSamplesSmooth());
  delay(200);
It would be nice if the number of buffered samples is quite stable like in the plots I posted here:
https://forum.pjrc.com/index.php?th...nel-outputs-not-just-stereo.70176/post-340690
 
I don't know if this is related but as i switch to another sketch i can't get the teensy usb port anymore, only two usb serial ports and in the log:

Code:
2024-04-01T06:10:17.289Z root WARN Detected a new port that has been already discovered. The old value will be overridden. Old value: {"port":{"address":
"usb1/1-6/1-6.4","addressLabel":"/dev/bus/usb/001/058 Bootloader","protocol":"teensy","protocolLabel":"Teensy Ports","properties":{"modelID":"0x25","name":"Teensy 4.1"}},"boards":[{"fqbn":"teensy:avr:teensy41","name":"Teensy 4.1"}]}, new value: {"boards":[{"fqbn":"teensy:avr:teensy41","name":"Teensy 4.1"}],"port":{"address":"usb1/1-6/1-6.4","addressLabel":"/dev/bus/usb/001/058 Bootloader","protocol":"teensy","protocolLabel":"Teensy Ports","properties":{"modelID":"0x25","na
me":"Teensy 4.1"}}}
2024-04-01T06:10:19.982Z daemon INFO time="2024-04-01T08:10:19+02:00" level=info msg="from discovery teensy:teensy-discovery received message type: remove, port: usb1/1-6/1-6.4"

2024-04-01T06:10:19.982Z discovery-log INFO {"eventType":"remove","port":{"matchingBoardsList":[],"port":{"address":"usb1/1-6/1-6.4","label":"","protocol":"tee
nsy","protocolLabel":"","propertiesMap":[],"hardwareId":""}},"error":""}
after rebooting all and cleaning the old patch to a blink, i still have the problem and i cant upload:

Teensy should be selected from "teensy ports" rather
than "Serial ports" in Arduino's Tools > Port menu
No Teensy boards were found on any USB ports of your computer.
Please press the PROGRAM MODE BUTTON on your Teensy to upload your sketch.
Failed uploading: uploading error: exit status 1

After pressing the reset button on teensy the above logs are shown and the port is removed.

By switching back to the original implementation, i got the usb audio running again.
there the usb port is not removed.
 
Last edited:
I think the issue may be that the product ID has been changed to one not matching the Teensy udev rules. Could be wrong, I'm not much of a Linuxist...
 
I also can only imagine that the cause is the changed PRODUCT_ID in usb_desc.h. In Windows I have to change the Id everytime I change the usb descriptors. Otherwise Windows seems to use some cached information. Anyway, I committed to the original Id again.
 
Yes, Windows is a pain like that. I've had good results changing the value of usb_string_serial_number, which seems to keep Windows a bit happier even if the VID/PID hasn't changed. If you look at the USBmultiChannelTest.ino example you just merged, you can see how I do it so the string tells Windows (and the user) what the channel count and sample rate is. This seems to be enough that Windows uses a different set of cached information for each serial number.

"Obviously" if you make fundamental changes to the descriptor there's a chance you'll have to uninstall the device from Windows so the cache gets cleared, but I've found it OK when "under the hood" changes are made, like your minor over/underrun changes.
 
Code:
ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04*", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789a]*", ENV{MTP_NO_PROBE}="1"
KERNEL=="ttyACM*", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04*", MODE:="0666", RUN:="/bin/stty -F /dev/%k raw -echo"
KERNEL=="hidraw*", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04*", MODE:="0666"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04*", MODE:="0666"
KERNEL=="hidraw*", ATTRS{idVendor}=="1fc9", ATTRS{idProduct}=="013*", MODE:="0666"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1fc9", ATTRS{idProduct}=="013*", MODE:="0666"
this is in my udev rules.
ah now i see: you have set the product id of USB_MIDI_AUDIO_SERIAL to 0x18B5, all others start with 04 which would be covered by the rule file.
Is there a specific reason for that?
 
I have switched now to USB_MIDI16_AUDIO_SERIAL, this works fine, however i would like to have a USB_AUDIO_SERIAL_SERIAL config as i only need serial and usb audio (i don't like midi and don't use it at all)
 
There was no specific reason for 0x18B5. I just changed it, because I wanted Windows to update its information about the Teensy. But I will follow h4yn0nnym0u5e's advice and change 'usb_string_serial_number' the next time I need to do that.
If you want the original product id, you can either set directly PRODUCT_ID back to 0x04D2 for USB_AUDIO and to 0x048A for USB_MIDI_AUDIO_SERIAL in usb_desc.h. Or you can pull the latest changes from my repository.
Unfortunately there is no option like USB_AUDIO_SERIAL yet.
 
Back
Top