Vendor Audio Requests implementation

Discussions about USB Audio on XMOS devices
MaximLiadov
XCore Addict
Posts: 130
Joined: Mon Apr 16, 2018 9:14 am

Vendor Audio Requests implementation

Post by MaximLiadov »

Hello there,
I need to implement Vendor Audio Requests for a USB Audio project. I need to sent some custom options from software Control Panel to device and get it back from device to software. Which is the best practice to do that? Please, help.
I have Thesycon SDK that supports Vendor Requests. I also see in endpoint0.c file VendorAudioRequests VendorAudioRequestsInit calls, if defined VENDOR_AUDIO_REQS. Any implementation is absent, just a declaration in the header. Does anyone have any code template or any documentation link? It would be very helpful. Thank you in advance.


User avatar
Ross
XCore Expert
Posts: 973
Joined: Thu Dec 10, 2009 9:20 pm
Location: Bristol, UK

Post by Ross »

What sort of request are you looking to implement?

You will want to take a look a 5.2.1 of the audio class 2.0 specification. When you send you custom request via the thesycon driver VendorAudioRequests() will be called with relevant params for bRequest (Likely CUR or RANGE), cs (Control Selector) cn (Channel Number) and a direction (Get or Set request).

Simply add your own implementation of VendorAudioRequests(). The default (empty) implementation is a weak symbol so your version will take precedence.
MaximLiadov
XCore Addict
Posts: 130
Joined: Mon Apr 16, 2018 9:14 am

Post by MaximLiadov »

Dear Ross, thank you very much!

The main idea is very simple. To use software control panel not only for volume/mute control, but for more options beyond standard USB audio class requests. Modern DAC has many dedicated settings, like interpolation filter type, PLL mode, phase, OSD mode, language, loopback on/off, spdif on/off, hp amp gain, so on. Default Thesycon panel is dull and almost useless. Make sense to add many custom options, isn't it? So I need to transfer settings through USB back and forth in the same moment as playback/recording does work. Besides that, I have a OSD menu on the device and need synchronise it with a control panel. I am not so good in understanding of USB specific though, I have no much experience with XUD programming yet. Hope Vendor Audio Requests is what I am looking for and it would be helpful here. I found no similar topic on the forum. I try my best to make my implementation with your kind support. My chance is about 10% of 100% at the moment. Many thanks for every guidance and links!
User avatar
Ross
XCore Expert
Posts: 973
Joined: Thu Dec 10, 2009 9:20 pm
Location: Bristol, UK

Post by Ross »

Yes, most large customers would design their own control panel application to control various custom features.

On the host side, for private control request, you should implement EP0 Vendor Requests with recipient set to Device. This is supported through the API functions TUSBAUDIO_ClassVendorRequestOut and TUSBAUDIO_ClassVendorRequestIn.

Alternatively, TUSBAUDIO_AudioControlRequestSet and TUSBAUDIO_AudioControlRequestGet can be used. But this requires that an Extension Unit is implemented in the firmware. The functions can send GET/SET CUR or MEM requests to that unit.
User avatar
fabriceo
XCore Addict
Posts: 213
Joined: Mon Jan 08, 2018 4:14 pm

Post by fabriceo »

Hi There
Ross you could also mention that th new usbaudio 7.2 contains a nice exemple of Usb host for controling Mixer, with both thesicon and libusb… inspiring
User avatar
Ross
XCore Expert
Posts: 973
Joined: Thu Dec 10, 2009 9:20 pm
Location: Bristol, UK

Post by Ross »

Oh yes, of course. Thanks for the reminder!
MaximLiadov
XCore Addict
Posts: 130
Joined: Mon Apr 16, 2018 9:14 am

Post by MaximLiadov »

Thank you very much for your guidance!

Seems to be the old code and comment are obsolete:

Code: Select all

/* If result is ERR at this point, then request to audio interface not handled - handle vendor audio reqs */
                            if(result == XUD_RES_ERR)
It doesn't work for me for vendor audio reqs, as it is placed inside audio class reqs.

The new code that works for me is:

Code: Select all

                case USB_BMREQ_H2D_VENDOR_DEV:
                case USB_BMREQ_D2H_VENDOR_DEV:
Hope that could save someone's hours of useless trials to get there from host. :)

My current question is: how to send message from device to host, outside of main XUD cycle? I.e. how to interrupt XUD from user's part of code to get into "case USB_BMREQ_D2H_VENDOR_DEV"? Any documentation link or guidance or code template would be very appriciated.
MaximLiadov
XCore Addict
Posts: 130
Joined: Mon Apr 16, 2018 9:14 am

Post by MaximLiadov »

Even more wide question, beyond Vendor Audio Requests. I see the code that never ever run:

Code: Select all

                          else /* Direction: Device-to-host */
                            {
                                if(unitID == FU_USBOUT)
                                {
                                    if ((sp.wValue & 0xff) <= NUM_USB_CHAN_OUT)
                                    {
                                        buffer[0] = volsOut[ sp.wValue&0xff ];
                                        buffer[1] = volsOut[ sp.wValue&0xff ] >> 8;
                                        return XUD_DoGetRequest(ep0_out, ep0_in, buffer, 2,  sp.wLength);
                                    }
                                }
                                else
                                {
                                    if ((sp.wValue & 0xff) <= NUM_USB_CHAN_IN)
                                    {
                                        buffer[0] = volsIn[ sp.wValue&0xff ];
                                        buffer[1] = volsIn[ sp.wValue&0xff ] >> 8;
                                        return XUD_DoGetRequest(ep0_out, ep0_in, buffer, 2,  sp.wLength);
                                    }
                                }
                            }
                            break; /* FU_VOLUME_CONTROL */
How to get to this or any part of code D2H, outside of XUD cycle, from user's code? I am not a lazy person and I would love to spend 10 years for XUD architecture if there was a good guidance or documentation.
MaximLiadov
XCore Addict
Posts: 130
Joined: Mon Apr 16, 2018 9:14 am

Post by MaximLiadov »

I saw interupt processing inside usb_buffer.xc/buffer(...) for clock changing, but I still don't understand how to sneak into device-to-host code in endpoint0.c and how make it work.
MaximLiadov
XCore Addict
Posts: 130
Joined: Mon Apr 16, 2018 9:14 am

Post by MaximLiadov »

fabriceo wrote: Thu Apr 06, 2023 2:53 pm usbaudio 7.2 contains a nice exemple of Usb host for controling Mixer, with both thesicon and libusb…
I compiled this mixer poject on Visual Studio with Thesycon SDK. Besides mixer, it also has --vendor-audio-request-get --vendor-audio-request-set command line options. I see a standard function TUSBAUDIO_AudioControlRequestSet inside the code, not really vendor. I see nothing on firmware side yet. Ross said: "But this requires that an Extension Unit is implemented in the firmware". I am curious how to do this exactly in firmware. Hope someone more experienced does know or have a code template.