Re: [PATCH v3 4/4] usb: gadget: f_uac2: send reasonably sized packets

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

 



On Tue, Aug 26, 2014 at 1:46 PM, Daniel Mack <zonque@xxxxxxxxx> wrote:
>
> +static void
> +afunc_set_p_pktsize(struct usb_gadget *gadget, struct audio_dev *agdev)
> +{
> +       unsigned i, residue, rate, factor, interval, framesize, pktsize, len;
> +       struct snd_uac2_chip *uac2 = &agdev->uac2;
> +       struct usb_endpoint_descriptor *ep_desc;
> +       struct f_uac2_opts *opts =
> +               container_of(agdev->func.fi, struct f_uac2_opts, func_inst);
> +
> +       if (gadget->speed == USB_SPEED_FULL) {
> +               ep_desc = &fs_epin_desc;
> +               factor = 1000;
> +       } else {
> +               ep_desc = &hs_epin_desc;
> +               factor = 125;
> +       }
> +
> +       /*
> +        * Simply dividing the desired data rate by the number of available
> +        * packets per seconds give rounding errors. Hence, we prepare a
> +        * sequence of packet sizes that will be alternated over when sending
> +        * the packets to the IN endpoint.
> +        */
> +       framesize = opts->p_ssize * num_channels(opts->p_chmask);
> +       interval = (1 << (ep_desc->bInterval - 1)) * factor;
>
Or simply, interval = 1000 ?

> +       rate = opts->p_srate * framesize;
> +
> +       pktsize = min_t(unsigned, rate / interval, ep_desc->wMaxPacketSize);
> +
> +       /*
> +        * If there's a residue from the modulo operation, calculate the index
> +        * of the first packet that could be increased by one sample frame.
> +        * This will be our sequence length, and the last member carries one
> +        * frame more than the others. Hence, the shorter the sequence is, the
> +        * more bytes will be transferred.
> +        */
> +       residue = (rate % interval) / framesize;
> +       if (residue)
> +               len = min_t(unsigned, interval / residue,
> +                           ARRAY_SIZE(uac2->p_pktsize_seq));
> +       else
> +               len = 1;
> +
> +       /* Set all lengths in the sequence to the divided value ... */
> +       for (i = 0; i < len; i++)
> +               uac2->p_pktsize_seq[i] = pktsize;
> +
> +       /* ... and add another frame to the last sequence member */
> +       if (len > 1)
> +               uac2->p_pktsize_seq[len - 1] += framesize;
> +
I see this takes care of only 44100Hz case. As I said in other post,
we should take care of all standard [5512.5, 192000] rates, possibly
also optimizing poll period.

Regards,
Jassi
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




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

  Powered by Linux