Getting pcm_usb_stream plugin to know its limits.

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

 



Hi there everyone,

I've been fighting for a few hours with a USB sound device (namely,
Tascam US-144), to get it to work with Audacity (this not being the
relevant part).

At first, Audacity died in a painful segfault, without any explanation,
when associated with the usb_stream plugin[1]. 

Audacity uses PortAudio, which checks for a few possible parameters of
audio rate to find the list of accepted ones.  It tries to set a
parameter (snd_pcm_hw_params), and if it fails, closes the device, and
continues its way.

Suppose the `prepare` act of the usb_stream is aborted because of wrong
parameters.  Then, PortAudio tries to close the device, by calling
snd_pcm_close.  This in turn calls snd_pcm_drop, which calls the fast_op
drop (that of ioplug), which is snd_pcm_ioplug_drop, which then calls
the *stop* callback of the usb_stream (snd_pcm_us_stop).  The stream not
being properly initialized, us->uus->write_area is nil, and the memset
fails.

This is the modification I did for that purpose :

--- pcm_usb_stream.c	2008-11-21 18:08:16.000000000 -0500
+++ pcm_usb_stream.c	2009-12-30 12:36:00.654452577 -0500
@@ -258,7 +258,7 @@
 	snd_pcm_us_t *us = io->private_data;
 	VDBG("%u", us->uus->s->periods_done);
 
-	if (io->stream == SND_PCM_STREAM_PLAYBACK)
+	if (io->stream == SND_PCM_STREAM_PLAYBACK && us->uus->s)
 		memset(us->uus->write_area, 0, us->uus->s->write_size);
 
 	return 0;
Next, Audacity stopped segfaulting but still didn't work: it couldn't
manage to configure the plugin properly.  Here's how PortAudio searches
for an acceptable audio rate.  For each possible sample rate, it gets a
full hw_params for the device:
                snd_pcm_hw_params_any( pcm, hwParams );
then set the sample rate to the hwParams.  It then tries to set those
params to the device:
                  snd_pcm_hw_params( pcm, hwParams );

The period_size parameter is left untouched, and by default, the pcm
inherits of a high value (maybe the highest).  Now the problem is the
following.  pcm_usb_stream says that the maximum accepted period_size is
64*4096:
(err = snd_pcm_ioplug_set_param_minmax(&us->io, SND_PCM_IOPLUG_HW_PERIOD_BYTES,
                                       128, 64*4096)

BUT the us122l driver[2] (from 2.6.32) explicitly prohibits period_size
greater than 0x3000:

if ((cfg->sample_rate != 44100 && cfg->sample_rate != 48000  &&
	     (!high_speed ||
	      (cfg->sample_rate != 88200 && cfg->sample_rate != 96000))) ||
	    cfg->frame_size != 6 ||
	    cfg->period_frames > 0x3000)
		err = -EINVAL;

This is now what happens in PortAudio:  PortAudio tries each and every
sound rate with the "default" period_size, this being greater than
0x3000.  It follows that no sound rate will be accepted, because of the
period_size, and the device fails to initialize.


I'm not sure whose fault is this, and for the time being, I just did the
following:
--- pcm_usb_stream.c	2008-11-21 18:08:16.000000000 -0500
+++ pcm_usb_stream.c	2009-12-30 12:36:00.654452577 -0500
@@ -380,7 +380,7 @@
 	    (err = snd_pcm_ioplug_set_param_minmax(&us->io, SND_PCM_IOPLUG_HW_RATE,
 						   44100, 96000)) < 0 ||
 	    (err = snd_pcm_ioplug_set_param_minmax(&us->io, SND_PCM_IOPLUG_HW_PERIOD_BYTES,
-						   128, 64*4096)) < 0 ||
+						   128, 2*4096)) < 0 ||
 	    (err = snd_pcm_ioplug_set_param_minmax(&us->io, SND_PCM_IOPLUG_HW_PERIODS,
 						   2, 2)) < 0)
 		return err;

Well, that's all folks.  Happy new year to everyone.

Footnotes: 
[1]  Configured as
pcm.!usb_stream {
	type usb_stream
	card "1"
}
which works with a fine-tuned aplay.


[2]  linux/sound/usb/usx2y/us122l.c

-- 
Michaël `Micha' Cadilhac (LITQ, U. de Montréal) -- http://michael.cadilhac.name
	|| La culture, c'est comme l'amour.
	||  Faut y aller à petits coups au début pour bien en jouir plus tard.
	||         -- Pierre Desproges
_______________________________________________
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