[alsa-devel] [PATCH - usb/usbaudio.c 1/1] sound/usb: Relax urb data align. restriction for HVR-950Q and HVR-850 only

Takashi Iwai tiwai at suse.de
Tue Dec 15 22:49:39 CET 2009


At Sun, 13 Dec 2009 19:51:01 -0500,
John S Gruber wrote:
> 
> Addressing audio quality problem.
> 
> In sound/usb/usbaudio.c, for the Hauppage HVR-950Q only, change
> retire_capture_urb to copy the entire byte stream while still counting
> entire audio frames. urbs unaligned on channel sample boundaries are
> still truncated to the next lowest stride (audio slot) size to try to
> retain channel alignment in cases of data loss over usb.
> 
> With the HVR950Q the left and right channel samples can be split between
> two different urbs. Throwing away extra channel samples causes a sound
> quality problem for stereo streams as the left and right channels are
> swapped repeatedly.

Through a quick glance, the patch looks good and safe to apply.

Just a few comments below.

> diff --git a/usb/usbaudio.c b/usb/usbaudio.c
> index b074a59..d450b23 100644
> --- a/usb/usbaudio.c
> +++ b/usb/usbaudio.c
> @@ -108,6 +108,7 @@ MODULE_PARM_DESC(ignore_ctl_error,
>  #define MAX_URBS	8
>  #define SYNC_URBS	4	/* always four urbs for sync */
>  #define MAX_QUEUE	24	/* try not to exceed this queue length, in ms */
> +#define ALLOW_SUBSLOT_BOUNDARIES 0x01	/* quirk */

If it's just a boolean flag, we don't need to use bits.
Simply use a char flag or a bit-field flag instead of bit-and operation.


>  struct audioformat {
>  	struct list_head list;
> @@ -127,6 +128,7 @@ struct audioformat {
>  	unsigned int rate_min, rate_max;	/* min/max rates */
>  	unsigned int nr_rates;		/* number of rate table entries */
>  	unsigned int *rate_table;	/* rate table */
> +	unsigned int txfr_quirks;	/* transfer quirks */

I'm not sure whether this flag should belong to audiofmt.
Isn't it rather controller-wide?  If so, it can be better fit to another,
more global struct.

The rest are just trivial coding-style issues.  For example...

> @@ -354,29 +358,39 @@ static int retire_capture_urb(struct
> snd_usb_substream *subs,
>  			snd_printd(KERN_ERR "frame %d active: %d\n", i,
> urb->iso_frame_desc[i].status);
>  			// continue;
>  		}
> -		len = urb->iso_frame_desc[i].actual_length / stride;
> -		if (! len)
> +		bytelen = (urb->iso_frame_desc[i].actual_length);

No need of parentheses.

> +		if (!bytelen)
>  			continue;
> +		if (bytelen%(runtime->sample_bits>>3) != 0) {

Please put spaces around operators.

> +			int oldbytelen = bytelen;
> +			bytelen = ((bytelen/stride)*stride);

Ditto.  Try to run scripts/checkpatch.pl once and fix the complains
there.

> +			snd_printd(KERN_ERR "Corrected urb data len. %d->%d\n",
> +				oldbytelen, bytelen);

Hm, how often would it be printed?  If it's really verbose, use
snd_printdd() instead.


thanks,

Takashi


More information about the Alsa-devel mailing list