Re: Getting pcm_usb_stream plugin to know its limits. [Kind of SOLVED]

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

 



michael@xxxxxxxxxxxxx (Michaël Cadilhac) writes:

> So, my final saying is the following patch.  It fixes the segfault on
> stopping a non-started usb_stream, plus it adds the ability to set a
> period size and sound rate.  The latter offers a workaround for the
> second issue I came with (that the default values for period bytes, and
> hence period size, were too high for us122l to work).

Any comment on that patch would be greatly appreciated.  I'm just
wondering if it's safe for me to give it to some people.

> --- /dd/alsa-plugins/usb_stream/pcm_usb_stream.c	2008-11-21 18:08:16.000000000 -0500
> +++ pcm_usb_stream.c	2009-12-30 23:40:46.467973740 -0500
> @@ -48,6 +48,9 @@
>  #define VDBG(f, ...)
>  #endif
>  
> +#define FRAME_SIZE 6
> +
> +
>  #define LCARD 32
>  struct user_usb_stream {
>  	char			card[LCARD];
> @@ -70,6 +73,8 @@
>  	unsigned		periods_done;
>  
>  	unsigned 		channels;
> +	snd_pcm_uframes_t	period_size;
> +	unsigned int		rate;
>  } snd_pcm_us_t;
>  
>  static struct user_usb_stream *uus;
> @@ -177,7 +182,7 @@
>  	VDBG("");
>  
>  	us_cfg.version = USB_STREAM_INTERFACE_VERSION;
> -	us_cfg.frame_size = 6;
> +	us_cfg.frame_size = FRAME_SIZE;
>  	us_cfg.sample_rate = io->rate;
>  	us_cfg.period_frames = io->period_size;
>  
> @@ -256,8 +261,11 @@
>  static int snd_pcm_us_stop(snd_pcm_ioplug_t *io)
>  {
>  	snd_pcm_us_t *us = io->private_data;
> -	VDBG("%u", us->uus->s->periods_done);
>  
> +	if (!us->uus->s)
> +	  return 0;
> +
> +	VDBG("%u", us->uus->s->periods_done);
>  	if (io->stream == SND_PCM_STREAM_PLAYBACK)
>  		memset(us->uus->write_area, 0, us->uus->s->write_size);
>  
> @@ -370,6 +378,10 @@
>  	};
>  
>  	int err;
> +	unsigned int rate_min = us->rate ? us->rate : 44100,
> +		rate_max = us->rate ? us->rate : 96000,
> +		period_bytes_min = us->period_size ? FRAME_SIZE * us->period_size : 128,
> +		period_bytes_max = us->period_size ? FRAME_SIZE * us->period_size : 64*4096;
>  
>  	if ((err = snd_pcm_ioplug_set_param_list(&us->io, SND_PCM_IOPLUG_HW_ACCESS,
>  						 ARRAY_SIZE(access_list), access_list)) < 0 ||
> @@ -378,19 +390,20 @@
>  	    (err = snd_pcm_ioplug_set_param_minmax(&us->io, SND_PCM_IOPLUG_HW_CHANNELS,
>  						   us->channels, us->channels)) < 0 ||
>  	    (err = snd_pcm_ioplug_set_param_minmax(&us->io, SND_PCM_IOPLUG_HW_RATE,
> -						   44100, 96000)) < 0 ||
> +						   rate_min, rate_max)) < 0 ||
>  	    (err = snd_pcm_ioplug_set_param_minmax(&us->io, SND_PCM_IOPLUG_HW_PERIOD_BYTES,
> -						   128, 64*4096)) < 0 ||
> +						   period_bytes_min, period_bytes_max)) < 0 ||
>  	    (err = snd_pcm_ioplug_set_param_minmax(&us->io, SND_PCM_IOPLUG_HW_PERIODS,
>  						   2, 2)) < 0)
>  		return err;
> -
>  	return 0;
>  }
>  
>  static int snd_pcm_us_open(snd_pcm_t **pcmp, const char *name,
>  				   const char *card,
> -				   snd_pcm_stream_t stream, int mode)
> +			   snd_pcm_stream_t stream, int mode,
> +			   snd_pcm_uframes_t period_size,
> +			   unsigned int rate)
>  {
>  	snd_pcm_us_t *us;
>  	int err;
> @@ -421,6 +434,8 @@
>  	snd_hwdep_poll_descriptors(us->hwdep, &us->pfd, 1);
>  
>  	us->channels = 2;
> +	us->period_size = period_size;
> +	us->rate = rate;
>  
>  	us->io.version = SND_PCM_IOPLUG_VERSION;
>  	us->io.name = "ALSA <-> USB_STREAM PCM I/O Plugin";
> @@ -455,6 +470,7 @@
>  	snd_config_iterator_t i, next;
>  	const char *card;
>  	int err;
> +	long period_size = 0, rate = 0;
>  	
>  	snd_config_for_each(i, next, conf) {
>  		snd_config_t *n = snd_config_iterator_entry(i);
> @@ -472,12 +488,27 @@
>  			snd_config_get_string(n, &card);
>  			continue;
>  		}
> +		if (strcmp(id, "period_size") == 0) {
> +			if (snd_config_get_type(n) != SND_CONFIG_TYPE_INTEGER) {
> +				SNDERR("Invalid type for %s", id);
> +				return -EINVAL;
> +			}
> +			snd_config_get_integer(n, &period_size);
> +			continue;
> +		}
> +		if (strcmp(id, "rate") == 0) {
> +			if (snd_config_get_type(n) != SND_CONFIG_TYPE_INTEGER) {
> +				SNDERR("Invalid type for %s", id);
> +				return -EINVAL;
> +			}
> +			snd_config_get_integer(n, &rate);
> +			continue;
> +		}
>  		SNDERR("Unknown field %s", id);
>  		return -EINVAL;
>  	}
>  
> -	err = snd_pcm_us_open(pcmp, name, card, stream, mode);
> -
> +	err = snd_pcm_us_open(pcmp, name, card, stream, mode, period_size, rate);
>  	return err;
>  }

-- 
Michaël `Micha' Cadilhac (LITQ, U. de Montréal) -- http://michael.cadilhac.name
	|| <ESC>ape this <COLON> thing,
	||   <Q>uit and do <NOT> <RET>urn.
	||         -- VI

_______________________________________________
Alsa-devel mailing list
Alsa-devel@xxxxxxxxxxxxxxxx
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel


[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux