Date: Fri, 11 Mar 2005 20:02:48 -0500 From: Mathew Kanner <mat@cnd.mcgill.ca> To: Kazuhito HONDA <kazuhito@ph.noda.tus.ac.jp> Cc: freebsd-multimedia@freebsd.org Subject: uaudio patch, capabilities Message-ID: <20050312010248.GG2944@cnd.mcgill.ca>
next in thread | raw e-mail | index | archive | help
--UlVJffcvxoiEqYs2
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
On Mar 09, Kazuhito HONDA wrote:
> From: Mathew Kanner <mat@cnd.mcgill.ca>
> Subject: Re: uaudio patch, configurable buffer size
> Date: Tue, 8 Mar 2005 07:08:20 -0500
>
> > I'm presently working on moving the ua_playcaps and ua_reccaps
> > into struct ua_info instead of global variables.
>
> O.K. I'm looking forward to your result.
Hello Kazuhito,
Please find attached my work in progress to add probing the
min/max rate for the uaudio device. It does what I described before
(de-globalizes the caps). It still prints some extra debugging
information and needs some polish thought before commiting.
I also sneak in some minor changes:
- add the kld info to /dev/sndstat (like the other sound
modules)
- reduce the default buffer size to 8kb
- Start to get ready for no playback/ mixer only devices.
--Mat
--UlVJffcvxoiEqYs2
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="uaudio_caps.diff"
Index: sys/dev/sound/usb/uaudio.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/sound/usb/uaudio.c,v
retrieving revision 1.13
diff -u -r1.13 uaudio.c
--- sys/dev/sound/usb/uaudio.c 6 Jan 2005 01:43:22 -0000 1.13
+++ sys/dev/sound/usb/uaudio.c 11 Mar 2005 20:01:52 -0000
@@ -3764,22 +3764,24 @@
return (0);
}
-void
-uaudio_query_formats(device_t dev, u_int32_t *pfmt, u_int32_t *rfmt)
+int
+uaudio_query_formats(device_t dev, u_int32_t *min, u_int32_t *max, u_int32_t *pfmt, u_int32_t *rfmt)
{
int i, pn=0, rn=0;
int prec, dir;
u_int32_t fmt;
struct uaudio_softc *sc;
- const struct usb_audio_streaming_type1_descriptor *a1d;
+ const struct usb_audio_streaming_type1_descriptor *asf1d;
sc = device_get_softc(dev);
+ *min = *max = 0;
+
for (i = 0; i < sc->sc_nalts; i++) {
fmt = 0;
- a1d = sc->sc_alts[i].asf1desc;
- prec = a1d->bBitResolution; /* precision */
+ asf1d = sc->sc_alts[i].asf1desc;
+ prec = asf1d->bBitResolution; /* precision */
switch (sc->sc_alts[i].encoding) {
case AUDIO_ENCODING_ULINEAR_LE:
@@ -3819,28 +3821,58 @@
}
if (fmt != 0) {
- if (a1d->bNrChannels == 2) { /* stereo/mono */
+ if (asf1d->bNrChannels == 2) { /* stereo/mono */
fmt |= AFMT_STEREO;
- } else if (a1d->bNrChannels != 1) {
+ } else if (asf1d->bNrChannels != 1) {
fmt = 0;
}
}
if (fmt != 0) {
dir= UE_GET_DIR(sc->sc_alts[i].edesc->bEndpointAddress);
- if (dir == UE_DIR_OUT) {
+ if (dir == UE_DIR_OUT && pn <= 8*2) {
pfmt[pn++] = fmt;
- } else if (dir == UE_DIR_IN) {
+ } else if (dir == UE_DIR_IN && rn <= 8*2 ) {
rfmt[rn++] = fmt;
}
}
- if ((pn > 8*2) || (rn > 8*2))
- break;
+ /*
+ * Sadly, for now, we will only look for the min/max
+ * of playback channels as this is more important to
+ * report correctly. I don't know of a way to report
+ * caps of playback and record seperately
+ */
+ if ( fmt == 0 || dir != UE_DIR_OUT )
+ continue;
+ if ( asf1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
+ int it = UA_SAMP_LO(asf1d);
+ printf( " Testing continuous lo %d min %d max %d\n", it, *min, *max);
+ if ( *min == 0 || it <= *min )
+ *min = it;
+ if ( *max == 0 )
+ *max = *min;
+ it = UA_SAMP_HI(asf1d);
+ printf( " Testing continuous hi %d min %d max %d\n", it, *min, *max);
+ if ( it >= *max )
+ *max = it;
+ } else {
+ int r, it;
+ for (r = 0; r < asf1d->bSamFreqType; r++) {
+ it = UA_GETSAMP(asf1d, r);
+ printf( " Testing fixed %d min %d max %d\n", it, *min, *max);
+ if ( *min == 0 || it <= *min )
+ *min = it;
+ if ( *max == 0 )
+ *max = *min;
+ if ( it >= *max )
+ *max = it;
+ }
+ }
}
pfmt[pn] = 0;
rfmt[rn] = 0;
- return;
+ return 1;
}
void
Index: sys/dev/sound/usb/uaudio.h
===================================================================
RCS file: /home/ncvs/src/sys/dev/sound/usb/uaudio.h,v
retrieving revision 1.5
diff -u -r1.5 uaudio.h
--- sys/dev/sound/usb/uaudio.h 6 Jan 2005 01:43:22 -0000 1.5
+++ sys/dev/sound/usb/uaudio.h 11 Mar 2005 20:04:51 -0000
@@ -49,4 +49,4 @@
u_int32_t uaudio_mixer_setrecsrc(device_t dev, u_int32_t src);
u_int32_t uaudio_query_mix_info(device_t dev);
u_int32_t uaudio_query_recsrc_info(device_t dev);
-void uaudio_query_formats(device_t dev, u_int32_t *pfmt, u_int32_t *rfmt);
+int uaudio_query_formats(device_t dev, u_int32_t *min, u_int32_t *max, u_int32_t *pfmt, u_int32_t *rfmt);
Index: sys/dev/sound/usb/uaudio_pcm.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/sound/usb/uaudio_pcm.c,v
retrieving revision 1.10
diff -u -r1.10 uaudio_pcm.c
--- sys/dev/sound/usb/uaudio_pcm.c 1 Mar 2005 08:58:06 -0000 1.10
+++ sys/dev/sound/usb/uaudio_pcm.c 11 Mar 2005 20:03:03 -0000
@@ -48,17 +48,13 @@
device_t sc_dev;
struct ua_chinfo pch, rch;
bus_dma_tag_t parent_dmat;
+ u_int32_t ua_playfmt[8*2+1]; /* 8 format * (stereo or mono) + endptr */
+ u_int32_t ua_recfmt[8*2+1]; /* 8 format * (stereo or mono) + endptr */
+ struct pcmchan_caps ua_playcaps;
+ struct pcmchan_caps ua_reccaps;
};
-static u_int32_t ua_playfmt[8*2+1]; /* 8 format * (stereo or mono) + endptr */
-
-static struct pcmchan_caps ua_playcaps = {8000, 48000, ua_playfmt, 0};
-
-static u_int32_t ua_recfmt[8*2+1]; /* 8 format * (stereo or mono) + endptr */
-
-static struct pcmchan_caps ua_reccaps = {8000, 48000, ua_recfmt, 0};
-
-#define UAUDIO_PCM_BUFF_SIZE 16*1024
+#define UAUDIO_PCM_BUFF_SIZE 8*1024
/************************************************************/
static void *
@@ -76,12 +72,6 @@
ch->dir = dir;
pa_dev = device_get_parent(sc->sc_dev);
- /* Create ua_playfmt[] & ua_recfmt[] */
- uaudio_query_formats(pa_dev, (u_int32_t *)&ua_playfmt, (u_int32_t *)&ua_recfmt);
- if (ua_playfmt[0] == 0) {
- printf("%s channel supported format list invalid\n", dir == PCMDIR_PLAY? "play" : "record");
- return NULL;
- }
/* allocate PCM side DMA buffer */
if (sndbuf_alloc(ch->buffer, sc->parent_dmat, UAUDIO_PCM_BUFF_SIZE) != 0) {
@@ -207,7 +197,7 @@
{
struct ua_chinfo *ch = data;
- return (ch->dir == PCMDIR_PLAY) ? &ua_playcaps : & ua_reccaps;
+ return (ch->dir == PCMDIR_PLAY) ? &(ch->parent->ua_playcaps) : &(ch->parent->ua_reccaps);
}
static kobj_method_t ua_chan_methods[] = {
@@ -299,6 +289,9 @@
struct ua_info *ua;
char status[SND_STATUSLEN];
unsigned int bufsz;
+ u_int32_t nplay, nrec;
+ u_int32_t min, max;
+ int i;
ua = (struct ua_info *)malloc(sizeof *ua, M_DEVBUF, M_NOWAIT);
if (!ua)
@@ -323,22 +316,40 @@
}
if (mixer_init(dev, &ua_mixer_class, ua)) {
- return(ENXIO);
+ goto bad;
}
- snprintf(status, SND_STATUSLEN, "at addr ?");
+ snprintf(status, SND_STATUSLEN, "%s", PCM_KLDSTRING(snd_uaudio));
+ uaudio_query_formats(device_get_parent(dev), &min, &max, ua->ua_playfmt, ua->ua_recfmt);
+ ua->ua_playcaps.minspeed = min;
+ ua->ua_playcaps.maxspeed = max;
+ ua->ua_playcaps.fmtlist = ua->ua_playfmt;
+ ua->ua_reccaps.minspeed = min;
+ ua->ua_reccaps.maxspeed = max;
+ ua->ua_reccaps.fmtlist = ua->ua_recfmt;
+
+ nplay = 1;
+ nrec = 1;
+ /*
+ * XXX Should really check if we have playback and record channels
+ */
#ifndef NO_RECORDING
- if (pcm_register(dev, ua, 1, 1)) {
+ if (pcm_register(dev, ua, nplay, nrec)) {
#else
- if (pcm_register(dev, ua, 1, 0)) {
+ if (pcm_register(dev, ua, nplay, 0)) {
#endif
return(ENXIO);
}
- pcm_addchan(dev, PCMDIR_PLAY, &ua_chan_class, ua);
+ for (i = 0; i < nplay; i++) {
+ pcm_addchan(dev, PCMDIR_PLAY, &ua_chan_class, ua);
+ }
+
#ifndef NO_RECORDING
- pcm_addchan(dev, PCMDIR_REC, &ua_chan_class, ua);
+ for (i = 0; i < nplay; i++) {
+ pcm_addchan(dev, PCMDIR_REC, &ua_chan_class, ua);
+ }
#endif
pcm_setstatus(dev, status);
--UlVJffcvxoiEqYs2--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20050312010248.GG2944>
