Re: [PATCH 0/3] UAC2 Gadget: feedback endpoint support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun 22 Nov 2020 at 20:51, Ruslan Bilovol <ruslan.bilovol@xxxxxxxxx> wrote:

> On Fri, Nov 13, 2020 at 5:35 PM Glenn Schmottlach
> <gschmottlach@xxxxxxxxx> wrote:
>>
>> On Thu, Nov 12, 2020 at 6:20 PM Ruslan Bilovol <ruslan.bilovol@xxxxxxxxx> wrote:
>> >
>> > On Wed, Nov 11, 2020 at 11:30 AM Peter Chen <peter.chen@xxxxxxx> wrote:
>> > >
>> > > On 20-11-08 02:18:28, Ruslan Bilovol wrote:
>> > > > Current UAC2 gadget implements capture/sync paths
>> > > > as two USB ISO ASYNC endpoints (IN and OUT).
>> > > >
>> > > > This violates USB spec which says that ISO ASYNC OUT endpoint
>> > > > should have feedback companion endpoint.
>> > > > See USB2.0 spec  "5.12.4.1 Synchronization Type": asynchronous
>> > > > sink provides explicit feedback (isochronous pipe).
>> > > > Interesting that for ISO ASYNC *IN* endpoint respective
>> > > > feedback isn't required since source provides implicit
>> > > > feedforward (data stream).
>> > > >
>> > > > While it's not an issue if UAC2 Gadget is connected to
>> > > > Linux host (Linux ignores missing feedback endpoint),
>> > > > with other hosts like Windows or MacOS the UAC2 Gadget
>> > > > isn't enumerated due to missing feedback endpoint.
>> > > >
>> > > > This patch series adds feedback endpoint support to
>> > > > UAC2 function, new control to UAC2 mixer which can
>> > > > be used by userspace tools (like alsaloop from alsa-utils)
>> > > > for updating feedback frequency reported to the host.
>> > > > This is useful for usecases when UAC2 Gadget's audio
>> > > > samples are played to another codec or audio card
>> > > > with its own internal freerunning clock so host can
>> > > > be notified that more/less samples are required.
>> > > >
>> > > > The alsaloop tool requires some (relatively small)
>> > > > modifications in order to start support driving
>> > > > feedback frequency through UAC2 mixer control.
>> > > > That change will be sent as a separate patch
>> > > > to ALSA community.
>> > > >
>> > > > Also added ability to switch ISO ASYNC OUT endpoint into
>> > > > adaptive endpoint which doesn't require feedback endpoint
>> > > > (as per USB spec).
>> > > >
>> > > > Ruslan Bilovol (3):
>> > > >   usb: gadget: f_uac2/u_audio: add feedback endpoint support
>> > > >   usb: gadget: f_uac2: add adaptive sync support for capture
>> > > >   usb: gadget: u_audio: add real feedback implementation
>> > >
>> > > Hi Ruslan,
>> > >
>> > > I applied your patches, but WIN10 still can't recognize it well.
>> > > The UAC1 is OK for WIN10 with the below same configuration.
>> > > Any debug information you would like to know to check it?
>> > >
>> > >
>> > > if [ "$FUNC" == "uac2" ]; then
>> > > mkdir functions/$FUNC".0"
>> > > echo 2 > functions/$FUNC".0"/p_ssize
>> > > echo 48000 > functions/$FUNC".0"/p_srate
>> > > echo 3 > functions/$FUNC".0"/p_chmask
>> > >
>> > > echo 2 > functions/$FUNC".0"/c_ssize
>> > > echo 48000 > functions/$FUNC".0"/c_srate
>> > > echo 3 > functions/$FUNC".0"/c_chmask
>> > > #echo 4 > functions/$FUNC".0"/req_number
>> > > ln -s functions/$FUNC".0" configs/c.1
>> > > echo high-speed > /sys/kernel/config/usb_gadget/g1/max_speed
>> > > fi
>> > >
>> >
>> > Hmm... I just tested below config and it works fine with my Win10.
>> > The only thing I noticed is Windows doesn't enable UAC2 gadget
>> > by default, but this can be done from Win10 sound settings
>> >
>> > --------------------------------->8--------------------------------------
>> > mkdir cfg
>> > mount none cfg -t configfs
>> > mkdir cfg/usb_gadget/g1
>> > cd cfg/usb_gadget/g1
>> > mkdir configs/c.1
>> > mkdir functions/uac2.0
>> >
>> > # 44.1 kHz sample rate
>> > echo 44100 > functions/uac2.0/c_srate
>> > echo 44100 > functions/uac2.0/p_srate
>> >
>> > mkdir strings/0x409
>> > mkdir configs/c.1/strings/0x409
>> > echo 0x0101 > idProduct
>> > echo 0x1d6b > idVendor
>> > echo my-serial-num > strings/0x409/serialnumber
>> > echo my-manufacturer > strings/0x409/manufacturer
>> > echo "Test gadget" > strings/0x409/product
>> > echo "Conf 1" > configs/c.1/strings/0x409/configuration
>> > echo 120 > configs/c.1/MaxPower
>> > ln -s functions/uac2.0 configs/c.1
>> > echo musb-hdrc.0 > UDC
>> > --------------------------------->8--------------------------------------
>> >
>> > Thanks,
>> > Ruslan
>>
>> Hi Ruslan -
>>
>> With your configuration (above) Win10 was able to recognize and load
>> the driver. What appears to prevent my configuration from loading is
>> the fact that I selected 48K as my sample rate and my capture/playback
>> channel mask includes more than two (2) channels. If I take your
>> configuration and change the sample rate (c_srate/p_srate) to 48000
>> Windows will fail to load the driver. Likewise, setting the
>> c_chmask/p_chmask to 7 (three channels) will also cause the driver to
>> fail to load.
>>
>> You mentioned there is an option in Win10 Sound Settings to "enable"
>> UAC2 by default. I cannot find that option and I wonder if this is
>> what is preventing me from changing the sample rate or channel mask?
>> Could Windows be treating my audio gadget as a UAC1 device rather than
>> a fully multi-channel audio device (even though the usbaudio2.sys
>> driver is loaded)? Have you tried other configurations to verify your
>> Win10 box supports more than two channels and a 44.1K sample rate? I
>> look forward to your feedback and any suggestions you might offer.
>>
>
> I was able to reproduce the issue and prepared a patch below, please
> try it and see if it fixes the issue.
>
> Maximum data rates that I used were (AFAIR) 8 channel 192kHz/32bit,
> but there is another issue with high data rate if someone uses so many
> channels, very high sampling frequency or sample size that data can't
> fit into allowed (by USB spec) max packet size of endpoint. In this case
> need to decrease bInterval of endpoint.
> I test it in a high-performance audio case so always use a minimal possible
> bInterval (set to '1').
> Of course in the future that need to be calculated dynamically depending on
> the UAC2 settings
>
> Please test patches below and see it it helps
>
> ---------------------------------------------8<----------------------------------------
> From 51516435bbf2486574ec7bc9fd4726677cd474a4 Mon Sep 17 00:00:00 2001
> From: Ruslan Bilovol <ruslan.bilovol@xxxxxxxxx>
> Date: Sun, 22 Nov 2020 21:05:38 +0200
> Subject: [PATCH] usb: gadget: f_uac2: always increase endpoint max_packet_size
>  by one audio slot
>
> As per UAC2 Audio Data Formats spec (2.3.1.1 USB Packets),
> if the sampling rate is a constant, the allowable variation
> of number of audio slots per virtual frame is +/- 1 audio slot.
>
> It means that endpoint should be able to accept/send +1 audio
> slot.
>
> Previous endpoint max_packet_size calculation code
> was adding sometimes +1 audio slot due to DIV_ROUND_UP
> behaviour which was rounding up to closest integer.
> However this doesn't work if the numbers are divisible.
>
> It had no any impact with Linux hosts which ignore
> this issue, but in case of more strict Windows it
> caused rejected enumeration
>
> Thus always add +1 audio slot to endpoint's max packet size
>
> Signed-off-by: Ruslan Bilovol <ruslan.bilovol@xxxxxxxxx>
> ---
>  drivers/usb/gadget/function/f_uac2.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/usb/gadget/function/f_uac2.c
> b/drivers/usb/gadget/function/f_uac2.c
> index ebdb2a1..1698587 100644
> --- a/drivers/usb/gadget/function/f_uac2.c
> +++ b/drivers/usb/gadget/function/f_uac2.c
> @@ -486,7 +486,7 @@ static void set_ep_max_packet_size(const struct
> f_uac2_opts *uac2_opts,
>   }
>
>   max_packet_size = num_channels(chmask) * ssize *
> - DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1)));
> + ((srate / (factor / (1 << (ep_desc->bInterval - 1)))) + 1);
>
>   if (!is_playback && (uac2_opts->c_sync == USB_ENDPOINT_SYNC_ASYNC))
>   max_packet_size = max_packet_size * FBACK_FREQ_MAX / 100;

I think "reserving" 20% additional bandwidth is a bit extreme.
In the end, the purpose is composate the drift which appears between
different XTALs

Allocating bandwidth for 1 more sample than the stream should require
(49 instead of 48 for 48kHz with 4 bIntervals) should allow to
compensate any realistic drift, don't you think ?

> -- 
> 1.9.1
>
>
> ---------------------------------------------8<----------------------------------------
> From c8f2f2b414af672ec40841e75fb1ea761ae29122 Mon Sep 17 00:00:00 2001
> From: Ruslan Bilovol <ruslan.bilovol@xxxxxxxxx>
> Date: Sun, 16 Feb 2020 22:40:23 +0200
> Subject: [PATCH] usb: gadget: f_uac2: change bInterval to 1 for
>  8ch/24bit/44.1kHz
>
> With bInterval=4 one audio slot in case of 8ch/24bit/44.1kHz
> exeeds MaxPacket size of ISO endpoint (>1024) and can't be
> transferred in time.
> USB spec ("5.6.3 Isochronous Transfer Packet Size Constraints")
> says if we need to transfer more than 1024 it is a high speed, high
> bandwidth endpoint and should have bInterval=1.
>
> In the future, bInterval should be dynamically calculated
> depending on bandwith requirementes

Probably better to do it from the start to avoid breaking stuff for
people who have been using the gadget with the current badnwidth so far

>
> Signed-off-by: Ruslan Bilovol <ruslan.bilovol@xxxxxxxxx>
> ---
>  drivers/usb/gadget/function/f_uac2.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/usb/gadget/function/f_uac2.c
> b/drivers/usb/gadget/function/f_uac2.c
> index 3633df6..fb9b875 100644
> --- a/drivers/usb/gadget/function/f_uac2.c
> +++ b/drivers/usb/gadget/function/f_uac2.c
> @@ -281,7 +281,7 @@ enum {
>
>   .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC,
>   .wMaxPacketSize = cpu_to_le16(1024),
> - .bInterval = 4,
> + .bInterval = 1,
>  };
>
>  /* CS AS ISO OUT Endpoint */
> @@ -358,7 +358,7 @@ enum {
>
>   .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC,
>   .wMaxPacketSize = cpu_to_le16(1024),
> - .bInterval = 4,
> + .bInterval = 1,
>  };
>
>  /* CS AS ISO IN Endpoint */




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux