From owner-p4-projects@FreeBSD.ORG Tue Nov 25 17:51:34 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 8AFB71065676; Tue, 25 Nov 2008 17:51:34 +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 4F717106564A for ; Tue, 25 Nov 2008 17:51:34 +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 450918FC1A for ; Tue, 25 Nov 2008 17:51:34 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id mAPHpX3l091463 for ; Tue, 25 Nov 2008 17:51:33 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id mAPHpXbW091461 for perforce@freebsd.org; Tue, 25 Nov 2008 17:51:33 GMT (envelope-from hselasky@FreeBSD.org) Date: Tue, 25 Nov 2008 17:51:33 GMT Message-Id: <200811251751.mAPHpXbW091461@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 153538 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: Tue, 25 Nov 2008 17:51:34 -0000 http://perforce.freebsd.org/chv.cgi?CH=153538 Change 153538 by hselasky@hselasky_laptop001 on 2008/11/25 17:50:46 Fix USB audio buffer handling for 24-bit audio devices. Affected files ... .. //depot/projects/usb/src/sys/dev/usb2/sound/uaudio2.c#19 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb2/sound/uaudio2.c#19 (text+ko) ==== @@ -92,10 +92,9 @@ static uint8_t uaudio_default_bits = 32; static uint8_t uaudio_default_channels = 2; +#define UAUDIO_MINFRAMES 16 /* must be factor of 8 due HS-USB */ #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 ((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) @@ -154,6 +153,7 @@ uint8_t *cur; /* current position in upper layer * buffer */ + uint32_t intr_size; /* in bytes */ uint32_t block_size; uint32_t sample_rate; uint32_t format; @@ -376,13 +376,13 @@ static int32_t umidi_detach(device_t dev); static const struct usb2_config - uaudio_cfg_record_full_speed[UAUDIO_NCHANBUFS] = { + uaudio_cfg_record[UAUDIO_NCHANBUFS] = { [0] = { .type = UE_ISOCHRONOUS, .endpoint = UE_ADDR_ANY, .direction = UE_DIR_IN, .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */ - .mh.frames = UAUDIO_NFRAMES, + .mh.frames = UAUDIO_MINFRAMES, .mh.flags = {.short_xfer_ok = 1,}, .mh.callback = &uaudio_chan_record_callback, }, @@ -392,43 +392,20 @@ .endpoint = UE_ADDR_ANY, .direction = UE_DIR_IN, .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */ - .mh.frames = UAUDIO_NFRAMES, + .mh.frames = UAUDIO_MINFRAMES, .mh.flags = {.short_xfer_ok = 1,}, .mh.callback = &uaudio_chan_record_callback, }, }; static const struct usb2_config - uaudio_cfg_record_high_speed[UAUDIO_NCHANBUFS] = { - [0] = { - .type = UE_ISOCHRONOUS, - .endpoint = UE_ADDR_ANY, - .direction = UE_DIR_IN, - .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */ - .mh.frames = (UAUDIO_NFRAMES * 8), - .mh.flags = {.short_xfer_ok = 1,}, - .mh.callback = &uaudio_chan_record_callback, - }, - - [1] = { - .type = UE_ISOCHRONOUS, - .endpoint = UE_ADDR_ANY, - .direction = UE_DIR_IN, - .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */ - .mh.frames = (UAUDIO_NFRAMES * 8), - .mh.flags = {.short_xfer_ok = 1,}, - .mh.callback = &uaudio_chan_record_callback, - }, -}; - -static const struct usb2_config - uaudio_cfg_play_full_speed[UAUDIO_NCHANBUFS] = { + uaudio_cfg_play[UAUDIO_NCHANBUFS] = { [0] = { .type = UE_ISOCHRONOUS, .endpoint = UE_ADDR_ANY, .direction = UE_DIR_OUT, .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */ - .mh.frames = UAUDIO_NFRAMES, + .mh.frames = UAUDIO_MINFRAMES, .mh.flags = {.short_xfer_ok = 1,}, .mh.callback = &uaudio_chan_play_callback, }, @@ -438,36 +415,13 @@ .endpoint = UE_ADDR_ANY, .direction = UE_DIR_OUT, .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */ - .mh.frames = UAUDIO_NFRAMES, + .mh.frames = UAUDIO_MINFRAMES, .mh.flags = {.short_xfer_ok = 1,}, .mh.callback = &uaudio_chan_play_callback, }, }; static const struct usb2_config - uaudio_cfg_play_high_speed[UAUDIO_NCHANBUFS] = { - [0] = { - .type = UE_ISOCHRONOUS, - .endpoint = UE_ADDR_ANY, - .direction = UE_DIR_OUT, - .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */ - .mh.frames = (UAUDIO_NFRAMES * 8), - .mh.flags = {.short_xfer_ok = 1,}, - .mh.callback = &uaudio_chan_play_callback, - }, - - [1] = { - .type = UE_ISOCHRONOUS, - .endpoint = UE_ADDR_ANY, - .direction = UE_DIR_OUT, - .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */ - .mh.frames = (UAUDIO_NFRAMES * 8), - .mh.flags = {.short_xfer_ok = 1,}, - .mh.callback = &uaudio_chan_play_callback, - }, -}; - -static const struct usb2_config uaudio_mixer_config[1] = { [0] = { .type = UE_CONTROL, @@ -693,10 +647,6 @@ struct uaudio_softc *sc = device_get_softc(device_get_parent(dev)); char status[SND_STATUSLEN]; - if (bootverbose) { - device_printf(dev, "using a default buffer " - "size of %u bytes\n", UAUDIO_DEFAULT_BUFSZ); - } uaudio_mixer_init(sc); if (sc->sc_uq_audio_swap_lr) { @@ -1054,16 +1004,13 @@ chan->iface_index = curidx; chan->iface_alt_index = alt_index; - chan->usb2_cfg = - (ep_dir == UE_DIR_IN) ? - ((fps == 1000) ? - uaudio_cfg_record_full_speed : - uaudio_cfg_record_high_speed) : - ((fps == 1000) ? - uaudio_cfg_play_full_speed : - uaudio_cfg_play_high_speed); + if (ep_dir == UE_DIR_IN) + chan->usb2_cfg = + uaudio_cfg_record; + else + chan->usb2_cfg = + uaudio_cfg_play; - sample_size = ((chan->p_asf1d->bNrChannels * chan->p_asf1d->bBitResolution) / 8); @@ -1135,21 +1082,23 @@ { 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 total; uint32_t blockcount; uint32_t n; uint32_t offset; /* allow dynamic sizing of play buffer */ + total = ch->intr_size; + + /* allow dynamic sizing of play buffer */ blockcount = total / ch->bytes_per_frame; - /* align to 8 units */ - blockcount &= ~7; + /* align units */ + blockcount -= (blockcount % UAUDIO_MINFRAMES); /* range check - min */ if (blockcount == 0) { - blockcount = 8; + blockcount = UAUDIO_MINFRAMES; } /* range check - max */ if (blockcount > xfer->max_frame_count) { @@ -1225,21 +1174,23 @@ uint32_t *p_len = xfer->frlengths; uint32_t n; uint32_t m; - uint32_t total = (sndbuf_getblkcnt(ch->pcm_buf) * - sndbuf_getblksz(ch->pcm_buf)) / 2; + uint32_t total; uint32_t blockcount; uint32_t offset0; uint32_t offset1; /* allow dynamic sizing of play buffer */ + total = ch->intr_size; + + /* allow dynamic sizing of play buffer */ blockcount = total / ch->bytes_per_frame; - /* align to 8 units */ - blockcount &= ~7; + /* align units */ + blockcount -= (blockcount % UAUDIO_MINFRAMES); /* range check - min */ if (blockcount == 0) { - blockcount = 8; + blockcount = UAUDIO_MINFRAMES; } /* range check - max */ if (blockcount > xfer->max_frame_count) { @@ -1321,21 +1272,30 @@ { struct uaudio_chan *ch = ((dir == PCMDIR_PLAY) ? &sc->sc_play_chan : &sc->sc_rec_chan); + uint32_t buf_size; uint8_t endpoint; uint8_t iface_index; uint8_t alt_index; usb2_error_t err; - ch->buf = malloc(UAUDIO_DEFAULT_BUFSZ, M_DEVBUF, M_WAITOK | M_ZERO); + /* compute required buffer size */ + buf_size = (ch->bytes_per_frame * UAUDIO_MINFRAMES); + + /* setup interrupt interval */ + ch->intr_size = buf_size; + + /* double buffering */ + buf_size *= 2; + ch->buf = malloc(buf_size, M_DEVBUF, M_WAITOK | M_ZERO); if (ch->buf == NULL) { goto error; } - if (sndbuf_setup(b, ch->buf, UAUDIO_DEFAULT_BUFSZ) != 0) { + if (sndbuf_setup(b, ch->buf, buf_size) != 0) { goto error; } ch->start = ch->buf; - ch->end = ch->buf + UAUDIO_DEFAULT_BUFSZ; + ch->end = ch->buf + buf_size; ch->cur = ch->buf; ch->pcm_ch = c; ch->pcm_mtx = c->lock; @@ -1432,26 +1392,14 @@ uaudio_chan_set_param_fragments(struct uaudio_chan *ch, uint32_t blocksize, uint32_t blockcount) { - uint32_t max = sndbuf_getmaxsize(ch->pcm_buf); + /* we only support one size */ + blocksize = ch->intr_size; + blockcount = 2; - RANGE(blocksize, 128, max / 2); - - /* - * Make sure that the blocksize is a factor of the number of bytes - * we insert per isochronous frame. - */ - blocksize += (ch->bytes_per_frame - blocksize) % ch->bytes_per_frame; - if (blocksize > (max / 2)) { - /* should not happen */ - DPRINTFN(0, "blocksize overflow!\n"); - blocksize = (max / 2); - } - blockcount = max / blocksize; - RANGE(blockcount, 2, 512); - if ((sndbuf_getblksz(ch->pcm_buf) != blocksize) || (sndbuf_getblkcnt(ch->pcm_buf) != blockcount)) { - + DPRINTFN(1, "resizing to %u x " + "%u bytes\n", blockcount, blocksize); if (sndbuf_resize(ch->pcm_buf, blockcount, blocksize)) { DPRINTFN(0, "failed to resize sound buffer, count=%u, " "size=%u\n", blockcount, blocksize);