Audio class enhancements
I'd like to make some major changes to UAC2 class:
- Remove support FIFO
The UAC code is pretty complex and difficult for new comers to contribute. An obvious way to simplify is to remove support FIFO as the only use is channel muxing/demuxing, which can be (should be IMO) done in application layer. At first it was planned to allow decoding formats other than TYPE I - PCM but never gets implemented.
- Move transfer into ISR with new
driver->xfer_isr
WIP: https://github.com/HiFiPhile/tinyusb/tree/xfer_isr
ISO transfer has a high timing requirements, currently all transfers are processed in the same queue, even with a preemptive OS or run TUSB inside ISR ISO transfers are still blocked by other transfers, causing audio distortion.
(Mostly for HS) there are some USB hosts that I've tested schedule the transfer poorly, instead of traiting ISO transfer with the highest priority (1st transfer after SOF) the interval between 2 transfers varies between 50us-200us. With a i7-1195G7 notebook I even saw 20us packet interval ! This behavior further reduce the processing time.
Without traiting ISO transfer separately in ISR the only way is differing processing other transfers (what I do currently) which scales poorly.
What do you think ? @PanRe @hathach @kf6gpe @gmikitiuk
Nice to hear from you! I don't mind - simplicity is better than too many features I guess. I implemented them with the idea that users might need them as I did. Please go ahead!
In general I like the idea, due to strict timing requirements, keeping isochronous in ISR would make sense.
Fortunately the application I've been developing had almost no other transfers in play so putting tinyUSB on highest prio task in the system was enough to keep the audio running smooth.
What I came across is that with multi-channel(up to 32ch 32bit) probably host is not capable of filling the transfers properly anymore as I've seen discontinuity in audio data without any under/over run on the application side(also no isochronous errors in the peripheral). Unfortunately I do not have usb analyzer to confirm my theory. It's hard to detect such cases when host is not keeping up(unless I've missed something).
PS. removing FIFO would also mean it would be user responsibility to calculate/fill feedback endpoint?
PS. removing FIFO would also mean it would be user responsibility to calculate/fill feedback endpoint?
The main FIFO won't be changed, support FIFO refers to the code guarded by #define CFG_TUD_AUDIO_ENABLE_ENCODING & #define CFG_TUD_AUDIO_ENABLE_DECODING
That would be great, I also think the audio driver is a bit complicated at the moment. The example's descritpor can also be simplified by using app-level struct like uvc https://github.com/hathach/tinyusb/blob/master/examples/device/video_capture/src/usb_descriptors.c#L174 . I think both audio and video are too complicated for pre-defined macros, maybe we can have macro with simplest form. I plan to do the same with audio examples but haven't manage the time yet. And yes, isochronous can use SOF/isr to meet the timing requirement.
If the changes is too large, and you can't manage the time to get it done in one/two time. We can add an audio_device_v2.c or something with audiod2 while keeping the existing driver intact, and can update it incrementally.
It turns remove support FIFO is pretty straight forward.
The example's descriptor can also be simplified by using app-level struct like uvc
Using struct is cleaner although mixing classes is more complicate.
Actually it's a little hard to set #define CFG_TUD_AUDIO_FUNC_1_DESC_LEN in tusb_config.h due to struct dependency loop.
Otherwise in order to figure out the descriptor length in the driver, bInterfaceCount of IAD need to be passed into audiod_open()
Hi, developer of Pico-ASHA here.
I know it's a little off-topic, but I was wondering if there would be an opportunity to provide basic UAC1 support? Many applications don't require anything more than basic (at max) 24 bit 96 KHz stereo audio, so UAC2 is a bit overkill. For example, Pico-ASHA only requires 16-bit 16KHz stereo audio.
The downsides of UAC2 is compatibility. While UAC2 works on modern Windows/Mac/Linux systems, the chances of it working elsewhere are fairly slim. For example, I tried Pico-ASHA with my Google TV (AKA Android TV) the other day, and it was not happy. It turns out Android only officially supports UAC1. Now, granted, I could be using TinyUSB incorrectly, but Pico-ASHA does work with Linux and Windows at least.
I started having a read of the UAC1 standard, but my head started hurting pretty quickly - I just don't know enough about USB and TinyUSB to implement such support myself.
I know it's a little off-topic, but I was wondering if there would be an opportunity to provide basic UAC1 support?
There are already request to support UAC1, mainly because feedback compatibility issue between Windows and OS X. However UAC1 and UAC2 descriptors and controls are pretty different, it will be a mess to support both of them in one driver.
@mastupristi Hi, PR is up in #3150
Finished
@shermp Hi, good news for you, my UAC1 support is in a good state: https://github.com/HiFiPhile/tinyusb/tree/uac1, it supports v1 & v2 at the same time.
audio_test_multi_rate and uac2_speaker_fb examples have been updated with dynamic switching based on actual operating speed (FS=UAC1, HS=UAC2)
However with uac2_speaker_fb example I'm unable to getting UAC1 feedback work on Windows, enumeration goes well but the device ended with Error 10: the i/o device is configured incorrectly or the configuration parameters to the driver are incorrect. I had to remove feedback endpoint from the descriptor.
@shermp Hi, good news for you, my UAC1 support is in a good state: https://github.com/HiFiPhile/tinyusb/tree/uac1, it supports v1 & v2 at the same time.
audio_test_multi_rateanduac2_speaker_fbexamples have been updated with dynamic switching based on actual operating speed (FS=UAC1, HS=UAC2)However with
uac2_speaker_fbexample I'm unable to getting UAC1 feedback work on Windows, enumeration goes well but the device ended withError 10: the i/o device is configured incorrectly or the configuration parameters to the driver are incorrect. I had to remove feedback endpoint from the descriptor.
Wow, that's great to see! I'll be sure to check it out if/when it gets merged into TinyUSB.
@shermp Hi, good news for you, my UAC1 support is in a good state: https://github.com/HiFiPhile/tinyusb/tree/uac1, it supports v1 & v2 at the same time.
audio_test_multi_rateanduac2_speaker_fbexamples have been updated with dynamic switching based on actual operating speed (FS=UAC1, HS=UAC2)However with
uac2_speaker_fbexample I'm unable to getting UAC1 feedback work on Windows, enumeration goes well but the device ended withError 10: the i/o device is configured incorrectly or the configuration parameters to the driver are incorrect. I had to remove feedback endpoint from the descriptor.
Yooo, that's crazy 👏
UAC1 PR is up ! https://github.com/hathach/tinyusb/pull/3270