* Re: [Alsa-user] No sound on Extigy
[not found] ` <s5hbs28yx2p.wl@alsa2.suse.de>
@ 2003-01-23 13:23 ` Takashi Iwai
[not found] ` <1043385385.1964.3.camel@idefix.homelinux.org>
0 siblings, 1 reply; 3+ messages in thread
From: Takashi Iwai @ 2003-01-23 13:23 UTC (permalink / raw)
To: Clemens Ladisch; +Cc: Jean-Marc Valin, alsa-devel
[-- Attachment #1: Type: text/plain, Size: 663 bytes --]
(moved to alsa-devel up to now...)
At Thu, 23 Jan 2003 11:33:50 +0100,
I wrote:
>
> At Thu, 23 Jan 2003 11:26:02 +0100 (MET),
> Clemens Ladisch wrote:
> >
> > The default output device used by aplay is "hw:0", which doesn't
> > automatically convert sample rates. Try "aplay -D plughw:0 something.wav".
>
> i'm afraid that it doesn't work, too, because this configuration is
> not handled well. anyway please try once.
>
> it's tough to solve...
if the original usb-audio driver doesn't work with plughw like above,
please try the attached patch.
it will show many debug messages. you can suppress it by undefining
HW_CONST_DEBUG at line 1167.
Takashi
[-- Attachment #2: usb-const.dif --]
[-- Type: application/octet-stream, Size: 8361 bytes --]
Index: alsa-kernel/usb/usbaudio.c
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/usb/usbaudio.c,v
retrieving revision 1.38
diff -u -r1.38 usbaudio.c
--- alsa-kernel/usb/usbaudio.c 22 Jan 2003 15:46:51 -0000 1.38
+++ alsa-kernel/usb/usbaudio.c 23 Jan 2003 13:19:44 -0000
@@ -36,7 +36,7 @@
#include <sound/core.h>
#include <sound/info.h>
#include <sound/pcm.h>
-#include <sound/seq_device.h>
+#include <sound/pcm_params.h>
#define SNDRV_GET_ID
#include <sound/initval.h>
@@ -1161,12 +1161,243 @@
};
/*
+ * h/w constraints
+ */
+
+#define HW_CONST_DEBUG
+
+static int hw_check_valid_format(snd_pcm_hw_params_t *params, struct audioformat *fp)
+{
+ snd_interval_t *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+ snd_interval_t *ct = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+ snd_mask_t *fmts = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+
+ /* check the format */
+ if (! snd_mask_test(fmts, fp->format))
+ return 0;
+ /* check the channels */
+ if (fp->channels < ct->min || fp->channels > ct->max)
+ return 0;
+ /* check the rate is within the range */
+ if (fp->rate_min > it->max || (fp->rate_min == it->max && !it->openmax))
+ return 0;
+ if (fp->rate_max < it->min || (fp->rate_max == it->min && !it->openmin))
+ return 0;
+ return 1;
+}
+
+static int hw_rule_rate(snd_pcm_hw_params_t *params,
+ snd_pcm_hw_rule_t *rule)
+{
+ snd_usb_substream_t *subs = rule->private;
+ struct list_head *p;
+ snd_interval_t *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+ int rmin, rmax, changed;
+
+#ifdef HW_CONST_DEBUG
+ printk(KERN_DEBUG "hw_rule_rate: (%d,%d)\n", it->min, it->max);
+#endif
+ changed = 0;
+ rmin = rmax = 0;
+ list_for_each(p, &subs->fmt_list) {
+ struct audioformat *fp;
+ fp = list_entry(p, struct audioformat, list);
+ if (! hw_check_valid_format(params, fp))
+ continue;
+ if (changed++) {
+ if (rmin > fp->rate_min)
+ rmin = fp->rate_min;
+ if (rmax < fp->rate_max)
+ rmax = fp->rate_max;
+ } else {
+ rmin = fp->rate_min;
+ rmax = fp->rate_max;
+ }
+ }
+
+ if (! changed) {
+#ifdef HW_CONST_DEBUG
+ printk(KERN_DEBUG " --> get empty\n");
+#endif
+ it->empty = 1;
+ return -EINVAL;
+ }
+
+ changed = 0;
+ if (it->min < rmin) {
+ it->min = rmin;
+ it->openmin = 0;
+ changed = 1;
+ }
+ if (it->max > rmax) {
+ it->max = rmax;
+ it->openmax = 0;
+ changed = 1;
+ }
+ if (snd_interval_checkempty(it)) {
+ it->empty = 1;
+ return -EINVAL;
+ }
+#ifdef HW_CONST_DEBUG
+ printk(KERN_DEBUG " --> (%d, %d) (changed = %d)\n", it->min, it->max, changed);
+#endif
+ return changed;
+}
+
+
+static int hw_rule_channels(snd_pcm_hw_params_t *params,
+ snd_pcm_hw_rule_t *rule)
+{
+ snd_usb_substream_t *subs = rule->private;
+ struct list_head *p;
+ snd_interval_t *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+ int rmin, rmax, changed;
+
+#ifdef HW_CONST_DEBUG
+ printk(KERN_DEBUG "hw_rule_channels: (%d,%d)\n", it->min, it->max);
+#endif
+ changed = 0;
+ rmin = rmax = 0;
+ list_for_each(p, &subs->fmt_list) {
+ struct audioformat *fp;
+ fp = list_entry(p, struct audioformat, list);
+ if (! hw_check_valid_format(params, fp))
+ continue;
+ if (changed++) {
+ if (rmin > fp->channels)
+ rmin = fp->channels;
+ if (rmax < fp->channels)
+ rmax = fp->channels;
+ } else {
+ rmin = fp->channels;
+ rmax = fp->channels;
+ }
+ }
+
+ if (! changed) {
+#ifdef HW_CONST_DEBUG
+ printk(KERN_DEBUG " --> get empty\n");
+#endif
+ it->empty = 1;
+ return -EINVAL;
+ }
+
+ changed = 0;
+ if (it->min < rmin) {
+ it->min = rmin;
+ it->openmin = 0;
+ changed = 1;
+ }
+ if (it->max > rmax) {
+ it->max = rmax;
+ it->openmax = 0;
+ changed = 1;
+ }
+ if (snd_interval_checkempty(it)) {
+ it->empty = 1;
+ return -EINVAL;
+ }
+#ifdef HW_CONST_DEBUG
+ printk(KERN_DEBUG " --> (%d, %d) (changed = %d)\n", it->min, it->max, changed);
+#endif
+ return changed;
+}
+
+static int hw_rule_format(snd_pcm_hw_params_t *params,
+ snd_pcm_hw_rule_t *rule)
+{
+ snd_usb_substream_t *subs = rule->private;
+ struct list_head *p;
+ snd_mask_t *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+ u64 fbits;
+ u32 oldbits[2];
+ int changed;
+
+#ifdef HW_CONST_DEBUG
+ printk(KERN_DEBUG "hw_rule_format: %x:%x\n", fmt->bits[0], fmt->bits[1]);
+#endif
+ fbits = 0;
+ list_for_each(p, &subs->fmt_list) {
+ struct audioformat *fp;
+ fp = list_entry(p, struct audioformat, list);
+ if (! hw_check_valid_format(params, fp))
+ continue;
+ fbits |= (1UL << fp->format);
+ }
+
+ oldbits[0] = fmt->bits[0];
+ oldbits[1] = fmt->bits[1];
+ fmt->bits[0] &= (u32)fbits;
+ fmt->bits[1] &= (u32)(fbits >> 32);
+ if (! fmt->bits[0] && ! fmt->bits[1]) {
+#ifdef HW_CONST_DEBUG
+ printk(KERN_DEBUG " --> get empty\n");
+#endif
+ return -EINVAL;
+ }
+ changed = (oldbits[0] != fmt->bits[0] || oldbits[1] != fmt->bits[1]);
+#ifdef HW_CONST_DEBUG
+ printk(KERN_DEBUG " --> %x:%x (changed = %d)\n", fmt->bits[0], fmt->bits[1], changed);
+#endif
+ return changed;
+}
+
+/*
+ * check whether the registered audio formats need special hw-constraints
+ */
+static int check_hw_params_convention(snd_usb_substream_t *subs)
+{
+ int i;
+ u32 channels[64];
+ u32 rates[64];
+ u32 cmaster, rmaster;
+ struct list_head *p;
+
+ memset(channels, 0, sizeof(channels));
+ memset(rates, 0, sizeof(rates));
+
+ list_for_each(p, &subs->fmt_list) {
+ struct audioformat *f;
+ f = list_entry(p, struct audioformat, list);
+ /* uncoventional rates? */
+ if (f->channels > 32 || (f->rates & SNDRV_PCM_RATE_KNOT))
+ return 1;
+ /* combination of continuous rates and fixed rates? */
+ if (rates[f->format] & SNDRV_PCM_RATE_CONTINUOUS) {
+ if (f->rates != rates[f->format])
+ return 1;
+ }
+ if (f->rates & SNDRV_PCM_RATE_CONTINUOUS) {
+ if (rates[f->format] && rates[f->format] != f->rates)
+ return 1;
+ }
+ channels[f->format] |= (1 << f->channels);
+ rates[f->format] |= f->rates;
+ }
+ /* check whether channels and rates match for all formats */
+ cmaster = rmaster = 0;
+ for (i = 0; i < 64; i++) {
+ if (cmaster != channels[i] && cmaster && channels[i])
+ return 1;
+ if (rmaster != rates[i] && rmaster && rates[i])
+ return 1;
+ if (channels[i])
+ cmaster = channels[i];
+ if (rates[i])
+ rmaster = rates[i];
+ }
+ return 0;
+}
+
+
+/*
* set up the runtime hardware information.
*/
-static void setup_hw_info(snd_pcm_runtime_t *runtime, snd_usb_substream_t *subs)
+static int setup_hw_info(snd_pcm_runtime_t *runtime, snd_usb_substream_t *subs)
{
struct list_head *p;
+ int err;
runtime->hw.formats = subs->formats;
@@ -1195,9 +1426,30 @@
1000 * MIN_PACKS_URB,
/*(NRPACKS * MAX_URBS) * 1000*/ UINT_MAX);
- /* FIXME: we need more constraints to restrict the format type,
- * channels and rates according to the audioformat list!
- */
+ if (check_hw_params_convention(subs)) {
+#ifdef HW_CONST_DEBUG
+ printk(KERN_DEBUG "setting extra hw constraints...\n");
+#endif
+ if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ hw_rule_rate, subs,
+ SNDRV_PCM_HW_PARAM_FORMAT,
+ SNDRV_PCM_HW_PARAM_CHANNELS,
+ -1)) < 0)
+ return err;
+ if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ hw_rule_channels, subs,
+ SNDRV_PCM_HW_PARAM_FORMAT,
+ SNDRV_PCM_HW_PARAM_RATE,
+ -1)) < 0)
+ return err;
+ if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
+ hw_rule_format, subs,
+ SNDRV_PCM_HW_PARAM_RATE,
+ SNDRV_PCM_HW_PARAM_CHANNELS,
+ -1)) < 0)
+ return err;
+ }
+ return 0;
}
static int snd_usb_pcm_open(snd_pcm_substream_t *substream, int direction,
@@ -1212,8 +1464,7 @@
runtime->hw = *hw;
runtime->private_data = subs;
subs->pcm_substream = substream;
- setup_hw_info(runtime, subs);
- return 0;
+ return setup_hw_info(runtime, subs);
}
static int snd_usb_pcm_close(snd_pcm_substream_t *substream, int direction)
@@ -1821,10 +2072,8 @@
break;
}
}
-#if 0 // FIXME - we need to define constraint
- if (c >= 13)
- fp->rates |= SNDRV_PCM_KNOT; /* unconventional rate */
-#endif
+ if (c >= 13) /* unconventional rate */
+ fp->rates |= SNDRV_PCM_RATE_KNOT;
}
} else {
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Alsa-user] No sound on Extigy
[not found] ` <1043385385.1964.3.camel@idefix.homelinux.org>
@ 2003-01-24 14:37 ` Takashi Iwai
2003-01-27 15:25 ` Takashi Iwai
1 sibling, 0 replies; 3+ messages in thread
From: Takashi Iwai @ 2003-01-24 14:37 UTC (permalink / raw)
To: Jean-Marc Valin; +Cc: alsa-devel
At Fri, 24 Jan 2003 00:16:25 -0500,
Jean-Marc Valin wrote:
>
> [1 <text/plain; ISO-8859-1 (quoted-printable)>]
> > if the original usb-audio driver doesn't work with plughw like above,
> > please try the attached patch.
>
> I tried the patch, but I still can't play anything other than 48000, 2
> channels and 48000, 4 channels (tried the other ones listed in
> /proc/asound/card0/stream0 but they didn't work). Any way I can at least
> get 44.1 kHz/stereo and 8000/mono working?
please show me the kernel debug messages when you tried 44100 2ch
samples!
Takashi
-------------------------------------------------------
This SF.NET email is sponsored by:
SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See!
http://www.vasoftware.com
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Alsa-user] No sound on Extigy
[not found] ` <1043385385.1964.3.camel@idefix.homelinux.org>
2003-01-24 14:37 ` Takashi Iwai
@ 2003-01-27 15:25 ` Takashi Iwai
1 sibling, 0 replies; 3+ messages in thread
From: Takashi Iwai @ 2003-01-27 15:25 UTC (permalink / raw)
To: Jean-Marc Valin; +Cc: alsa-devel
At Fri, 24 Jan 2003 00:16:25 -0500,
Jean-Marc Valin wrote:
>
> [1 <text/plain; ISO-8859-1 (quoted-printable)>]
> > if the original usb-audio driver doesn't work with plughw like above,
> > please try the attached patch.
>
> I tried the patch, but I still can't play anything other than 48000, 2
> channels and 48000, 4 channels (tried the other ones listed in
> /proc/asound/card0/stream0 but they didn't work). Any way I can at least
> get 44.1 kHz/stereo and 8000/mono working?
there was a bug in the patch. i already committed the fixed version
to cvs. please update the cvs version and give a try again (you'll
need to plug layer anyway, because extigy doesn't support two-channels
44100 hz).
Takashi
-------------------------------------------------------
This SF.NET email is sponsored by:
SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See!
http://www.vasoftware.com
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2003-01-27 15:25 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <s5hel74yya8.wl@alsa2.suse.de>
[not found] ` <Pine.HPX.4.33n.0301231122530.18209-100000@studcom.urz.uni-halle.de>
[not found] ` <s5hbs28yx2p.wl@alsa2.suse.de>
2003-01-23 13:23 ` [Alsa-user] No sound on Extigy Takashi Iwai
[not found] ` <1043385385.1964.3.camel@idefix.homelinux.org>
2003-01-24 14:37 ` Takashi Iwai
2003-01-27 15:25 ` Takashi Iwai
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.