From c392128002d4b537cfc4426e6bf8b17cd0a1e1ff Mon Sep 17 00:00:00 2001 From: augustss Date: Mon, 4 Aug 1997 09:29:51 +0000 Subject: [PATCH] Audio: * Make it possible to use software assisted encodings that expand the sample size. * Use 16 bits per sample when emulating mulaw coding on the SB. * Prepare for SB16 without CT1745 mixer. --- sys/dev/audio.c | 43 +++++++++++++++++++++++++++--------- sys/dev/isa/sbdsp.c | 49 ++++++++++++++++++++++++------------------ sys/dev/isa/sbdspvar.h | 6 ++++-- sys/dev/mulaw.c | 10 ++++----- 4 files changed, 70 insertions(+), 38 deletions(-) diff --git a/sys/dev/audio.c b/sys/dev/audio.c index 43878b896163..7e19ad0217fd 100644 --- a/sys/dev/audio.c +++ b/sys/dev/audio.c @@ -1,4 +1,4 @@ -/* $NetBSD: audio.c,v 1.59 1997/08/01 17:04:00 augustss Exp $ */ +/* $NetBSD: audio.c,v 1.60 1997/08/04 09:29:51 augustss Exp $ */ /* * Copyright (c) 1991-1993 Regents of the University of California. @@ -756,7 +756,7 @@ audio_drain(sc) */ drops = cb->drops; while (cb->drops == drops) { - DPRINTF(("audio_drain: used=%d\n", sc->sc_pr.used)); + DPRINTF(("audio_drain: used=%d, drops=%ld\n", sc->sc_pr.used, cb->drops)); /* * When the process is exiting, it ignores all signals and * we can't interrupt this sleep, so we set a timeout just in case. @@ -956,7 +956,8 @@ audio_calc_blksize(sc, mode) } bs = parm->sample_rate * audio_blk_ms / 1000 * - parm->channels * parm->precision / NBBY; + parm->channels * parm->precision / NBBY * + parm->factor; ROUNDSIZE(bs); if (hw->round_blocksize) bs = hw->round_blocksize(sc->hw_hdl, bs); @@ -1100,13 +1101,27 @@ audio_write(dev, uio, ioflag) splx(s); cc = cb->usedhigh - used; /* maximum to write */ n = cb->end - inp; + if (sc->sc_pparams.factor != 1) { + /* Compensate for software coding expansion factor. */ + n /= sc->sc_pparams.factor; + cc /= sc->sc_pparams.factor; + } if (n < cc) cc = n; /* don't write beyond end of buffer */ if (uio->uio_resid < cc) cc = uio->uio_resid; /* and no more than we have */ - /* Compensate for software coding expansion factor. */ - cc = (cc + sc->sc_pparams.factor - 1) / sc->sc_pparams.factor; +#ifdef DIAGNOSTIC + /* + * This should never happen since the block size and and + * block pointers are always nicely aligned. + */ + if (cc == 0) { + printf("audio_write: cc == 0, factor=%d\n", + sc->sc_pparams.factor); + return EINVAL; + } +#endif #ifdef AUDIO_DEBUG if (audiodebug > 1) printf("audio_write: uiomove cc=%d inp=%p, left=%d\n", cc, inp, uio->uio_resid); @@ -1119,12 +1134,20 @@ audio_write(dev, uio, ioflag) printf("audio_write:(1) uiomove failed %d; cc=%d inp=%p\n", error, cc, inp); #endif - /* Continue even if uiomove() failed because we may have - * gotten a partial block. */ - if (sc->sc_pparams.sw_code) + /* + * Continue even if uiomove() failed because we may have + * gotten a partial block. + */ + + if (sc->sc_pparams.sw_code) { sc->sc_pparams.sw_code(sc->hw_hdl, inp, cc); - /* And adjust count after the expansion. */ - cc *= sc->sc_pparams.factor; + /* Adjust count after the expansion. */ + cc *= sc->sc_pparams.factor; +#ifdef AUDIO_DEBUG + if (audiodebug > 1) + printf("audio_write: expanded cc=%d\n", cc); +#endif + } einp = cb->inp + cc; if (einp >= cb->end) diff --git a/sys/dev/isa/sbdsp.c b/sys/dev/isa/sbdsp.c index c328d3502d39..874e3d5597b0 100644 --- a/sys/dev/isa/sbdsp.c +++ b/sys/dev/isa/sbdsp.c @@ -1,4 +1,4 @@ -/* $NetBSD: sbdsp.c,v 1.64 1997/07/31 22:33:36 augustss Exp $ */ +/* $NetBSD: sbdsp.c,v 1.65 1997/08/04 09:29:56 augustss Exp $ */ /* * Copyright (c) 1991-1993 Regents of the University of California. @@ -532,26 +532,18 @@ sbdsp_set_params(addr, mode, p, q) break; case AUDIO_ENCODING_ULAW: if (mode == AUMODE_PLAY) { -#if 0 swcode = mulaw_to_ulinear16; factor = 2; m = &sbpmodes[PLAY16]; -#else - swcode = mulaw_to_ulinear8; -#endif } else swcode = ulinear8_to_mulaw; bmode = SB_BMODE_UNSIGNED; break; case AUDIO_ENCODING_ALAW: if (mode == AUMODE_PLAY) { -#if 0 swcode = alaw_to_ulinear16; factor = 2; m = &sbpmodes[PLAY16]; -#else - swcode = alaw_to_ulinear8; -#endif } else swcode = ulinear8_to_alaw; bmode = SB_BMODE_UNSIGNED; @@ -638,9 +630,9 @@ sbdsp_set_params(addr, mode, p, q) */ sc->sc_dmadir = SB_DMA_NONE; - DPRINTF(("set_params: model=%d, mode=%d, rate=%ld, prec=%d, chan=%d, enc=%d -> tc=%02x, cmd=%02x, bmode=%02x, cmdchan=%02x, swcode=%p\n", + DPRINTF(("set_params: model=%d, mode=%d, rate=%ld, prec=%d, chan=%d, enc=%d -> tc=%02x, cmd=%02x, bmode=%02x, cmdchan=%02x, swcode=%p, factor=%d\n", sc->sc_model, mode, p->sample_rate, p->precision, p->channels, - p->encoding, tc, m->cmd, bmode, m->cmdchan, swcode)); + p->encoding, tc, m->cmd, bmode, m->cmdchan, swcode, factor)); return 0; } @@ -755,6 +747,7 @@ sbdsp_set_in_ports(sc, mask) sbdsp_mix_write(sc, SBP_RECORD_SOURCE, SBP_RECORD_FROM(sbport, SBP_FILTER_OFF, SBP_IFILTER_HIGH)); break; + case SBM_CT1XX5: case SBM_CT1745: if (mask & ~((1<sc_model = SB_PRO; break; case 4: +#if 0 +/* XXX This does not work */ + /* Most SB16 have a tone controls, but some don't. */ + sbdsp_mix_write(sc, SB16P_TREBLE_L, 0x80); + /* Check if we can read back the mixer value. */ + if ((sbdsp_mix_read(sc, SB16P_TREBLE_L) & 0xf0) == 0x80) + sc->sc_mixer_model = SBM_CT1745; + else + sc->sc_mixer_model = SBM_CT1XX5; +#else sc->sc_mixer_model = SBM_CT1745; +#endif /* XXX what about SB_32 */ if (SBVER_MINOR(v) == 16) sc->sc_model = SB_64; @@ -1584,6 +1588,7 @@ sbdsp_set_mixer_gain(sc, port) } sbdsp_mix_write(sc, src, gain); break; + case SBM_CT1XX5: case SBM_CT1745: switch (port) { case SB_MIC_VOL: @@ -1645,7 +1650,8 @@ sbdsp_mixer_set_port(addr, cp) switch (cp->dev) { case SB_TREBLE: case SB_BASS: - if (sc->sc_mixer_model == SBM_CT1345) { + if (sc->sc_mixer_model == SBM_CT1345 || + sc->sc_mixer_model == SBM_CT1XX5) { if (cp->type != AUDIO_MIXER_ENUM) return EINVAL; switch (cp->dev) { @@ -1660,7 +1666,7 @@ sbdsp_mixer_set_port(addr, cp) case SB_PCSPEAKER: case SB_INPUT_GAIN: case SB_OUTPUT_GAIN: - if (sc->sc_mixer_model != SBM_CT1745) + if (!ISSBM1745(sc)) return EINVAL; case SB_MIC_VOL: case SB_LINE_IN_VOL: @@ -1722,7 +1728,7 @@ sbdsp_mixer_set_port(addr, cp) break; case SB_RECORD_SOURCE: - if (sc->sc_mixer_model == SBM_CT1745) { + if (ISSBM1745(sc)) { if (cp->type != AUDIO_MIXER_SET) return EINVAL; return sbdsp_set_in_ports(sc, cp->un.mask); @@ -1734,7 +1740,7 @@ sbdsp_mixer_set_port(addr, cp) break; case SB_AGC: - if (sc->sc_mixer_model != SBM_CT1745 || cp->type != AUDIO_MIXER_ENUM) + if (!ISSBM1745(sc) || cp->type != AUDIO_MIXER_ENUM) return EINVAL; sbdsp_mix_write(sc, SB16P_AGC, cp->un.ord & 1); break; @@ -1761,7 +1767,8 @@ sbdsp_mixer_get_port(addr, cp) switch (cp->dev) { case SB_TREBLE: case SB_BASS: - if (sc->sc_mixer_model == SBM_CT1345) { + if (sc->sc_mixer_model == SBM_CT1345 || + sc->sc_mixer_model == SBM_CT1XX5) { switch (cp->dev) { case SB_TREBLE: cp->un.ord = sbdsp_get_ifilter(addr) == SB_TREBLE; @@ -1774,7 +1781,7 @@ sbdsp_mixer_get_port(addr, cp) case SB_PCSPEAKER: case SB_INPUT_GAIN: case SB_OUTPUT_GAIN: - if (sc->sc_mixer_model != SBM_CT1745) + if (!ISSBM1745(sc)) return EINVAL; case SB_MIC_VOL: case SB_LINE_IN_VOL: @@ -1810,14 +1817,14 @@ sbdsp_mixer_get_port(addr, cp) break; case SB_RECORD_SOURCE: - if (sc->sc_mixer_model == SBM_CT1745) + if (ISSBM1745(sc)) cp->un.mask = sc->in_mask; else cp->un.ord = sc->in_port; break; case SB_AGC: - if (sc->sc_mixer_model != SBM_CT1745) + if (!ISSBM1745(sc)) return EINVAL; cp->un.ord = sbdsp_mix_read(sc, SB16P_AGC); break; @@ -1844,7 +1851,7 @@ sbdsp_mixer_query_devinfo(addr, dip) return ENXIO; chan = sc->sc_mixer_model == SBM_CT1335 ? 1 : 2; - class = sc->sc_mixer_model == SBM_CT1745 ? SB_INPUT_CLASS : SB_OUTPUT_CLASS; + class = ISSBM1745(sc) ? SB_INPUT_CLASS : SB_OUTPUT_CLASS; switch (dip->index) { case SB_MASTER_VOL: @@ -1918,7 +1925,7 @@ sbdsp_mixer_query_devinfo(addr, dip) dip->mixer_class = SB_RECORD_CLASS; dip->prev = dip->next = AUDIO_MIXER_LAST; strcpy(dip->label.name, AudioNsource); - if (sc->sc_mixer_model == SBM_CT1745) { + if (ISSBM1745(sc)) { dip->type = AUDIO_MIXER_SET; dip->un.s.num_mem = 4; strcpy(dip->un.s.member[0].label.name, AudioNmicrophone); diff --git a/sys/dev/isa/sbdspvar.h b/sys/dev/isa/sbdspvar.h index 72de4da62cd4..92b66caaefec 100644 --- a/sys/dev/isa/sbdspvar.h +++ b/sys/dev/isa/sbdspvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: sbdspvar.h,v 1.27 1997/07/31 22:33:38 augustss Exp $ */ +/* $NetBSD: sbdspvar.h,v 1.28 1997/08/04 09:29:57 augustss Exp $ */ /* * Copyright (c) 1991-1993 Regents of the University of California. @@ -127,7 +127,9 @@ struct sbdsp_softc { #define SBM_NONE 0 #define SBM_CT1335 1 #define SBM_CT1345 2 -#define SBM_CT1745 3 +#define SBM_CT1XX5 3 +#define SBM_CT1745 4 +#define ISSBM1745(x) ((x)->sc_mixer_model >= SBM_CT1XX5) u_int sc_model; /* DSP model */ #define SB_UNK -1 diff --git a/sys/dev/mulaw.c b/sys/dev/mulaw.c index faefc4b55bda..96ad536214f1 100644 --- a/sys/dev/mulaw.c +++ b/sys/dev/mulaw.c @@ -1,4 +1,4 @@ -/* $NetBSD: mulaw.c,v 1.7 1997/07/31 22:33:21 augustss Exp $ */ +/* $NetBSD: mulaw.c,v 1.8 1997/08/04 09:29:53 augustss Exp $ */ /* * Copyright (c) 1991-1993 Regents of the University of California. @@ -278,10 +278,10 @@ mulaw_to_ulinear16(v, p, cc) u_char *q = p; p += cc; - q += cc; + q += cc * 2; while (--cc >= 0) { - *--q = mulawtolin16[*p ][HI]; *--q = mulawtolin16[*--p][LO]; + *--q = mulawtolin16[*p ][HI]; } } @@ -319,10 +319,10 @@ alaw_to_ulinear16(v, p, cc) u_char *q = p; p += cc; - q += cc; + q += cc * 2; while (--cc >= 0) { - *--q = alawtolin16[*p ][HI]; *--q = alawtolin16[*--p][LO]; + *--q = alawtolin16[*p ][HI]; } }