michael@xxxxxxxxxxxxx (Michaël Cadilhac) writes: > 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. Anyone? Note that this also fixes a real bug, so it might be of interest to include it in the trunk. >> --- /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 || 21 seems like a good value: half of 42, || and just old enough to drink! Why would you want to change it? || -- Stefan Monnier _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel