From: michael@cadilhac.name (Michaël Cadilhac)
To: alsa-devel@alsa-project.org
Subject: Getting pcm_usb_stream plugin to know its limits.
Date: Wed, 30 Dec 2009 12:48:22 -0500 [thread overview]
Message-ID: <87ljgkuzdl.fsf@cadilhac.name> (raw)
[-- Attachment #1: Type: text/plain, Size: 1030 bytes --]
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 :
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: memset.patch --]
[-- Type: text/x-patch, Size: 392 bytes --]
--- 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;
[-- Attachment #3: Type: text/plain, Size: 1479 bytes --]
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:
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: period_size.patch --]
[-- Type: text/x-patch, Size: 511 bytes --]
--- 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;
[-- Attachment #5: Type: text/plain, Size: 455 bytes --]
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
[-- Attachment #6: Type: text/plain, Size: 160 bytes --]
_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
next reply other threads:[~2009-12-30 17:50 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-12-30 17:48 Michaël Cadilhac [this message]
2009-12-30 17:58 ` Getting pcm_usb_stream plugin to know its limits Michaël Cadilhac
2009-12-31 4:15 ` Michaël Cadilhac
2009-12-31 4:57 ` Getting pcm_usb_stream plugin to know its limits. [Kind of SOLVED] Michaël Cadilhac
2010-01-05 3:26 ` Michaël Cadilhac
2010-01-11 18:35 ` Michaël Cadilhac
2010-01-12 9:52 ` Takashi Iwai
2010-02-02 5:24 ` Michaël Cadilhac
2010-02-10 22:56 ` Michaël Cadilhac
2010-02-22 9:04 ` Takashi Iwai
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87ljgkuzdl.fsf@cadilhac.name \
--to=michael@cadilhac.name \
--cc=alsa-devel@alsa-project.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox