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 :
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:
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