From owner-freebsd-multimedia@FreeBSD.ORG Sat Mar 12 01:03:26 2005 Return-Path: Delivered-To: freebsd-multimedia@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 4C0D616A4CE for ; Sat, 12 Mar 2005 01:03:26 +0000 (GMT) Received: from drizzle.CC.McGill.CA (drizzle.cc.mcgill.ca [132.206.27.48]) by mx1.FreeBSD.org (Postfix) with ESMTP id 2AFC943D54 for ; Sat, 12 Mar 2005 01:03:23 +0000 (GMT) (envelope-from mat@cnd.mcgill.ca) Received: from mailscan2.cc.mcgill.ca (mailscan2.CC.McGill.CA [132.216.77.249])j2C13J9a018562; Fri, 11 Mar 2005 20:03:19 -0500 Received: from cube.cnd.mcgill.ca (cube.CND.McGill.CA [132.216.25.196]) j2C12vrO016163; Fri, 11 Mar 2005 20:02:58 -0500 (EST) Received: from localhost.localdomain (acid.cnd.mcgill.ca [132.216.11.151]) by cube.cnd.mcgill.ca (8.12.11/8.12.11) with ESMTP id j2C12pYt009627; Fri, 11 Mar 2005 20:02:56 -0500 Received: from localhost.localdomain (acid [127.0.0.1]) j2C12pkJ019229; Fri, 11 Mar 2005 20:02:51 -0500 Received: (from mat@localhost) by localhost.localdomain (8.12.11/8.12.11/Submit) id j2C12mHf019228; Fri, 11 Mar 2005 20:02:48 -0500 Date: Fri, 11 Mar 2005 20:02:48 -0500 From: Mathew Kanner To: Kazuhito HONDA Message-ID: <20050312010248.GG2944@cnd.mcgill.ca> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="UlVJffcvxoiEqYs2" Content-Disposition: inline User-Agent: Mutt/1.4.2i Organization: I speak for myself, operating in Montreal, CANADA cc: freebsd-multimedia@freebsd.org Subject: uaudio patch, capabilities X-BeenThere: freebsd-multimedia@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Multimedia discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 12 Mar 2005 01:03:26 -0000 --UlVJffcvxoiEqYs2 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Mar 09, Kazuhito HONDA wrote: > From: Mathew Kanner > 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--