From owner-p4-projects@FreeBSD.ORG Fri Jul 25 17:24:05 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 05B661065670; Fri, 25 Jul 2008 17:24:05 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id BC91D106568C for ; Fri, 25 Jul 2008 17:24:04 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id BD7838FC17 for ; Fri, 25 Jul 2008 17:24:04 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.2/8.14.2) with ESMTP id m6PHO4sf019820 for ; Fri, 25 Jul 2008 17:24:04 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.2/8.14.1/Submit) id m6PHO4Nc019818 for perforce@freebsd.org; Fri, 25 Jul 2008 17:24:04 GMT (envelope-from hselasky@FreeBSD.org) Date: Fri, 25 Jul 2008 17:24:04 GMT Message-Id: <200807251724.m6PHO4Nc019818@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky To: Perforce Change Reviews Cc: Subject: PERFORCE change 145900 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 25 Jul 2008 17:24:05 -0000 http://perforce.freebsd.org/chv.cgi?CH=145900 Change 145900 by hselasky@hselasky_laptop001 on 2008/07/25 17:23:56 Significantly improve USB audio playback and recording latency. Affected files ... .. //depot/projects/usb/src/sys/dev/usb2/sound/uaudio2.c#8 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb2/sound/uaudio2.c#8 (text+ko) ==== @@ -95,7 +95,7 @@ #define UAUDIO_NCHANBUFS 2 /* number of outstanding request */ #define UAUDIO_NFRAMES 25 /* ms of sound in each request */ #define UAUDIO_RECURSE_LIMIT 24 /* rounds */ -#define UAUDIO_DEFAULT_BUFSZ (16*1024) /* bytes */ +#define UAUDIO_DEFAULT_BUFSZ ((2 * 96000 * 4 * 2) / (1000 / UAUDIO_NCHANBUFS)) /* bytes */ #define MAKE_WORD(h,l) (((h) << 8) | (l)) #define BIT_TEST(bm,bno) (((bm)[(bno) / 8] >> (7 - ((bno) % 8))) & 1) @@ -223,7 +223,6 @@ struct uaudio_mixer_node *sc_mixer_root; struct uaudio_mixer_node *sc_mixer_curr; - uint32_t sc_buffer_size; uint32_t sc_mix_info; uint32_t sc_recsrc_info; @@ -694,11 +693,9 @@ struct uaudio_softc *sc = device_get_softc(device_get_parent(dev)); char status[SND_STATUSLEN]; - sc->sc_buffer_size = pcm_getbuffersize(dev, 4096, UAUDIO_DEFAULT_BUFSZ, 65536); - if (bootverbose) { device_printf(dev, "using a default buffer " - "size of %u bytes\n", sc->sc_buffer_size); + "size of %u bytes\n", UAUDIO_DEFAULT_BUFSZ); } uaudio_mixer_init(sc); @@ -1134,10 +1131,29 @@ { struct uaudio_chan *ch = xfer->priv_sc; uint32_t *p_len = xfer->frlengths; + uint32_t total = (sndbuf_getblkcnt(ch->pcm_buf) * + sndbuf_getblksz(ch->pcm_buf)) / 2; + uint32_t blockcount; uint32_t n; - uint32_t total = (ch->bytes_per_frame * xfer->nframes); uint32_t offset; + /* allow dynamic sizing of play buffer */ + blockcount = total / ch->bytes_per_frame; + + /* align to 8 units */ + blockcount &= ~7; + + /* range check - min */ + if (blockcount == 0) { + blockcount = 8; + } + /* range check - max */ + if (blockcount > xfer->max_frame_count) { + blockcount = xfer->max_frame_count; + } + /* compute the total length */ + total = blockcount * ch->bytes_per_frame; + switch (USB_GET_STATE(xfer)) { case USB_ST_TRANSFERRED: tr_transferred: @@ -1153,15 +1169,17 @@ "exceeds maximum, %d!\n", ch->bytes_per_frame, xfer->max_frame_size); - return; + break; } - for (n = 0; n < xfer->nframes; n++) { + /* setup frame length */ + xfer->nframes = blockcount; + for (n = 0; n != blockcount; n++) { p_len[n] = ch->bytes_per_frame; } if (ch->end == ch->start) { DPRINTF(0, "no buffer!\n"); - return; + break; } DPRINTF(5, "transfer %d bytes\n", total); @@ -1185,14 +1203,15 @@ } usb2_start_hardware(xfer); - return; + break; default: /* Error */ if (xfer->error == USB_ERR_CANCELLED) { - return; + break; } goto tr_transferred; } + return; } static void @@ -1202,10 +1221,29 @@ uint32_t *p_len = xfer->frlengths; uint32_t n; uint32_t m; - uint32_t total = (xfer->nframes * ch->bytes_per_frame); + uint32_t total = (sndbuf_getblkcnt(ch->pcm_buf) * + sndbuf_getblksz(ch->pcm_buf)) / 2; + uint32_t blockcount; uint32_t offset0; uint32_t offset1; + /* allow dynamic sizing of play buffer */ + blockcount = total / ch->bytes_per_frame; + + /* align to 8 units */ + blockcount &= ~7; + + /* range check - min */ + if (blockcount == 0) { + blockcount = 8; + } + /* range check - max */ + if (blockcount > xfer->max_frame_count) { + blockcount = xfer->max_frame_count; + } + /* compute the total length */ + total = blockcount * ch->bytes_per_frame; + switch (USB_GET_STATE(xfer)) { case USB_ST_TRANSFERRED: tr_transferred: @@ -1218,7 +1256,7 @@ offset0 = 0; - for (n = 0; n < xfer->nframes; n++) { + for (n = 0; n != xfer->nframes; n++) { offset1 = offset0; @@ -1253,7 +1291,8 @@ xfer->max_frame_size); return; } - for (n = 0; n < xfer->nframes; n++) { + xfer->nframes = blockcount; + for (n = 0; n != xfer->nframes; n++) { p_len[n] = ch->bytes_per_frame; } @@ -1283,16 +1322,16 @@ uint8_t alt_index; usb2_error_t err; - ch->buf = malloc(sc->sc_buffer_size, M_DEVBUF, M_WAITOK | M_ZERO); + ch->buf = malloc(UAUDIO_DEFAULT_BUFSZ, M_DEVBUF, M_WAITOK | M_ZERO); if (ch->buf == NULL) { goto error; } - if (sndbuf_setup(b, ch->buf, sc->sc_buffer_size) != 0) { + if (sndbuf_setup(b, ch->buf, UAUDIO_DEFAULT_BUFSZ) != 0) { goto error; } ch->start = ch->buf; - ch->end = ch->buf + sc->sc_buffer_size; + ch->end = ch->buf + UAUDIO_DEFAULT_BUFSZ; ch->cur = ch->buf; ch->pcm_ch = c; ch->pcm_mtx = c->lock; @@ -1380,11 +1419,7 @@ int uaudio_chan_set_param_blocksize(struct uaudio_chan *ch, uint32_t blocksize) { - uint32_t max = sndbuf_getmaxsize(ch->pcm_buf); - - RANGE(blocksize, 128, max / 2); - - uaudio_chan_set_param_fragments(ch, blocksize, max / blocksize); + uaudio_chan_set_param_fragments(ch, blocksize, 0 - 1); return (ch->block_size); } @@ -1396,17 +1431,10 @@ uint32_t max = sndbuf_getmaxsize(ch->pcm_buf); RANGE(blocksize, 128, max / 2); + + blockcount = max / blocksize; RANGE(blockcount, 2, 512); - while ((blocksize * blockcount) > max) { - if ((blockcount >> 1) >= 2) - blockcount >>= 1; - else if ((blocksize >> 1) >= 128) - blocksize >>= 1; - else - break; - } - if ((sndbuf_getblksz(ch->pcm_buf) != blocksize) || (sndbuf_getblkcnt(ch->pcm_buf) != blockcount)) {