USB interface for multi channel outputs, not just stereo

I didn't test different sampling frequencies yet, but I want to try out 48kHz in the next days. I tested different bIntervals by just changing the value AUDIO_POLLING_INTERVAL_480 in usb_desk.h for testing purposes (Manually setting the value is normally not necessary). Or also by setting the AUDIO_SUBSLOT_SIZE to 3 (24bit per samples). Then 1059bytes/ms are required at 8channels/44.1kHz.
 
I tested the usb input now also with 48kHz and I fixed a small bug (unrelated to the sampling frequency), that caused sometimes a nearly empty buffer at the beginning of a stream. As far as I can tell, the usb input also works for 48kHz.
 
I've had a very brief play and it seems to be the best I've heard yet - nice job!

I can see the extra samples being inserted (Teensy->PC) but can't hear them. Curious to know how the PC reacts if you just send the occasional packet with one fewer sample in it. For example, 44.1kHz ought to be 9 packets of 44 samples and 1 of 45, forever; but if you need to make the occasional 44-sample packet a 43-sample, or the 45 another 44, rather than inserting a duplicate sample, does it all fail horribly? Similarly if you would drop a sample, can you just send an extra 45-sample packet? I confess I can't follow your code well enough to try this for myself :(
 
I have to admit, I need to clean that part of my implementation up. My focus was on the usb input and I only adapted the usb output, because my changes of course broke the original two channel code.
When I have some time within the next days, I will try out your suggestion. Maybe we should also try to change the type of the usb output endpoint from adaptive to asynchronous.
Did you also test the usb input? And did you use 96kHz as sampling rate?
 
I only tested input very briefly … even more so than the output! Seemed OK but I need to do a thorough test, recording known-perfect waveforms and then looking at them with a spectral display to highlight any discontinuities.

Didn’t touch 96kHz. I will get to it at some point, for sure. If you think it’s working as-is, apart from sample dropping or stuffing, I’d say don’t change the endpoint type yet.

I did do some multi-channel USB objects, and edits to the Design Tool so you can place them. Feel free to use any of that; alternatively, I’ll fork your code and do a PR with those added, once we’re confident it’s as good as it can be. I’m kinda hoping the next Teensyduino will pull in a lot of the pending Audio PRs (or at least the good ones ;)), and this looks like a definite candidate - there’s been lots of interest over the years…
 
I tested you suggestion:
There is now the variable 'async' in line 789 in usb_audio.cpp. (I will change that later, but for now for some quick tests it should be fine). If async is set to false, the usb audio output sends always the expect number of samples. (E.g. 9 times 44 samples and then once 45 samples). If the buffer gets too full, it just skips one sample of the buffer and if the buffer gets too empty it sends one sample twice. This is the version you already tested.
If async is set to true (as in the code I commited), then it never discards or stuffs samples. Instead it sends one sample more or one sample less too the host. At a first test this also seems to work. I used this triangular waveforms from your example and recorded them in Goldwave. Just visually there don't seem to be any glitches.
However, now the usb output behaves like an asynchronous source endpoint:
1711137904597.png

So I wanted to know if it makes any difference if I change the usb descriptor from adaptive to asynchronous (Line 1644 and 2791 in usb_desc.c). It didn't make any difference and I kept it for now.
All in all I think defining the usb output as asynchronous source and adapting the number of sent samples is the best solution.
 
Regarding a pull request: I am not sure how to proceed. I changed a lot compared to the original code like the update to the usb2 specification. Unfortunatley it is not possible for me to test it with many different hosts and it would therefore be very risky to merge it into the main branch. Maybe it is possible to add new build options like USB_MIDI_UAC2AUDIO_SERIAL in addition to USB_MIDI_AUDIO_SERIAL (for some transition time)? Then we can be sure that we don't break old code and people who want to try out the new interface can easily switch.
 
That sounds like good news, will give it a go as soon as I can.

With regard to the PR, I was thinking only as far as forking your repo, adding in some of my modifications to allow placement of wider USB objects in the Design Tool, and submitting a PR for you to consider. Pulling the result into the official Teensyduino release would of course be a matter for Paul to decide in a future release cycle. The release times do tend to be quite long (1.59 took 10 months from beta #1 to release), so there would in theory be plenty of time to find any real show-stoppers and back out the changes if they couldn't be fixed.
 
Sure, I expressed myself unclearly. I was just thinking about how we could prepare the code so that there is the chance that Paul accepts a pull request.
I have to admit, I have never used the Design Tool, but I would give it a try and test the changes you made to the USB object.
 
I've done a PR to your repo, having done a bit more testing - this essentially adds in stuff I'd already done previously. Minor change to your code to make it compile with 8 channels @ 96kHz. Haven't time for more right now, but will be back!
 
WoW :D
I've been using your asynchronous spdif input successful and now you bring us hope for USB 8ch.
Alex thanks for this wish I have time to test this out now.
 
Back
Top