- Change audio_hw_if a little: set_param now sets the play and record modes

at the same time instead by using two different calls.  This enables
  it to check more easily if the combined mode is all right.
- Improve the error checking in audio.c.
- Add a new audio property, AUDIO_PROP_INDEPENDENT, show if the
  play and record settings are independent.
- Fix some buglets in audio.c.
This commit is contained in:
augustss 1997-08-24 22:31:23 +00:00
parent 4d74b89725
commit 6616d47838
16 changed files with 434 additions and 434 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: aucc.c,v 1.17 1997/08/19 23:49:40 augustss Exp $ */
/* $NetBSD: aucc.c,v 1.18 1997/08/24 22:31:23 augustss Exp $ */
#undef AUDIO_DEBUG
/*
* Copyright (c) 1997 Stephan Thesing
@ -189,8 +189,8 @@ int aucc_set_port __P((void *, mixer_ctrl_t *));
int aucc_get_port __P((void *, mixer_ctrl_t *));
int aucc_query_devinfo __P((void *, mixer_devinfo_t *));
void aucc_encode __P((int, int, int, u_char *, u_short **));
int aucc_set_params __P((void *, int, struct audio_params *,
struct audio_params *));
int aucc_set_params __P((void *, int, int,
struct audio_params *, struct audio_params *));
int aucc_get_props __P((void *));
struct audio_hw_if sa_hw_if = {
@ -406,21 +406,19 @@ aucc_query_encoding(addr, fp)
}
int
aucc_set_params(addr, mode, p, q)
aucc_set_params(addr, setmode, usemode, p, r)
void *addr;
int mode;
struct audio_params *p, *q;
int setmode, usemode;
struct audio_params *p, *r;
{
struct aucc_softc *sc;
struct aucc_softc *sc = addr;
sc = addr;
/* if (mode == AUMODE_RECORD)
/* if (setmode & AUMODE_RECORD)
return 0 ENXIO*/;
#ifdef AUCCDEBUG
printf("aucc_set_params(mode %x, enc %d, bits %d, chn %d, sr %ld)\n",
mode, p->encoding, p->precision, p->channels, p->sample_rate);
printf("aucc_set_params(setmode 0x%x, usemode 0x%x, enc %d, bits %d, chn %d, sr %ld)\n",
setmode, usemode, p->encoding, p->precision, p->channels, p->sample_rate);
#endif
switch (p->encoding) {
@ -446,11 +444,6 @@ aucc_set_params(addr, mode, p, q)
sc->sc_channels = p->channels;
sc->sc_encoding = p->encoding;
q->encoding = p->encoding;
q->precision = p->precision;
q->channels = p->channels;
q->sample_rate = p->sample_rate;
return aucc_set_out_sr(addr, p->sample_rate);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: lmcaudio.c,v 1.12 1997/08/19 23:49:44 augustss Exp $ */
/* $NetBSD: lmcaudio.c,v 1.13 1997/08/24 22:31:25 augustss Exp $ */
/*
* Copyright (c) 1996, Danny C Tsen.
@ -105,7 +105,6 @@ void lmcaudio_timeout __P((void *arg));
int lmcaudio_intr __P((void *arg));
int lmcaudio_dma_program __P((vm_offset_t cur, vm_offset_t end, void (*intr)(), void *arg));
void lmcaudio_dummy_routine __P((void *arg));
int lmcaudio_stereo __P((int channel, int position));
int lmcaudio_rate __P((int rate));
void lmcaudio_shutdown __P((void));
@ -312,7 +311,7 @@ lmcaudio_drain(addr)
* ************************************************************************* */
int lmcaudio_query_encoding __P((void *, struct audio_encoding *));
int lmcaudio_set_params __P((void *, int, struct audio_params *, struct audio_params *));
int lmcaudio_set_params __P((void *, int, int, struct audio_params *, struct audio_params *));
int lmcaudio_round_blocksize __P((void *, int));
int lmcaudio_set_out_port __P((void *, int));
int lmcaudio_get_out_port __P((void *));
@ -338,22 +337,17 @@ struct audio_device lmcaudio_device = {
};
int
lmcaudio_set_params(addr, mode, p, q)
lmcaudio_set_params(addr, setmode, usemode, p, r)
void *addr;
int mode;
struct audio_params *p, *q;
int setmode, usemode;
struct audio_params *p, *r;
{
if (p->encoding != AUDIO_ENCODING_SLINEAR_LE ||
p->precision != 16 ||
p->channels != 2)
return EINVAL;
/* Update setting for the other mode. */
q->sample_rate = p->sample_rate;
q->encoding = p->encoding;
q->channels = p->channels;
q->precision = p->precision;
return 0;
return lmcaudio_rate(p->sample_rate);
}
int
@ -619,14 +613,6 @@ lmcaudio_rate(rate)
return(0);
}
int
lmcaudio_stereo(channel, position)
int channel;
int position;
{
return(0);
}
#define PHYS(x) (pmap_extract( kernel_pmap, ((x)&PG_FRAME) ))
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: vidcaudio.c,v 1.17 1997/08/19 23:49:45 augustss Exp $ */
/* $NetBSD: vidcaudio.c,v 1.18 1997/08/24 22:31:26 augustss Exp $ */
/*
* Copyright (c) 1995 Melvin Tang-Richardson
@ -278,7 +278,7 @@ vidcaudio_close(addr)
* ************************************************************************* */
int vidcaudio_query_encoding __P((void *, struct audio_encoding *));
int vidcaudio_set_params __P((void *, int, struct audio_params *, struct audio_params *));
int vidcaudio_set_params __P((void *, int, int, struct audio_params *, struct audio_params *));
int vidcaudio_round_blocksize __P((void *, int));
int vidcaudio_set_out_port __P((void *, int));
int vidcaudio_get_out_port __P((void *));
@ -321,21 +321,16 @@ int vidcaudio_query_encoding ( void *addr, struct audio_encoding *fp )
}
int
vidcaudio_set_params(addr, mode, p, q)
vidcaudio_set_params(addr, setmode, usemode, p, r)
void *addr;
struct audio_params *p, *q;
int setmode, usemode;
struct audio_params *p, *r;
{
if (p->encoding != AUDIO_ENCODING_ULAW ||
p->channels != 8)
return EINVAL;
vidcaudio_rate(4 * p->sample_rate / (3 * 1024)); /* XXX probably wrong */
p->sw_code = 0;
/* Update setting for the other mode. */
q->sample_rate = p->sample_rate;
q->encoding = p->encoding;
q->channels = p->channels;
q->precision = p->precision;
return 0;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: lmcaudio.c,v 1.12 1997/08/19 23:49:44 augustss Exp $ */
/* $NetBSD: lmcaudio.c,v 1.13 1997/08/24 22:31:25 augustss Exp $ */
/*
* Copyright (c) 1996, Danny C Tsen.
@ -105,7 +105,6 @@ void lmcaudio_timeout __P((void *arg));
int lmcaudio_intr __P((void *arg));
int lmcaudio_dma_program __P((vm_offset_t cur, vm_offset_t end, void (*intr)(), void *arg));
void lmcaudio_dummy_routine __P((void *arg));
int lmcaudio_stereo __P((int channel, int position));
int lmcaudio_rate __P((int rate));
void lmcaudio_shutdown __P((void));
@ -312,7 +311,7 @@ lmcaudio_drain(addr)
* ************************************************************************* */
int lmcaudio_query_encoding __P((void *, struct audio_encoding *));
int lmcaudio_set_params __P((void *, int, struct audio_params *, struct audio_params *));
int lmcaudio_set_params __P((void *, int, int, struct audio_params *, struct audio_params *));
int lmcaudio_round_blocksize __P((void *, int));
int lmcaudio_set_out_port __P((void *, int));
int lmcaudio_get_out_port __P((void *));
@ -338,22 +337,17 @@ struct audio_device lmcaudio_device = {
};
int
lmcaudio_set_params(addr, mode, p, q)
lmcaudio_set_params(addr, setmode, usemode, p, r)
void *addr;
int mode;
struct audio_params *p, *q;
int setmode, usemode;
struct audio_params *p, *r;
{
if (p->encoding != AUDIO_ENCODING_SLINEAR_LE ||
p->precision != 16 ||
p->channels != 2)
return EINVAL;
/* Update setting for the other mode. */
q->sample_rate = p->sample_rate;
q->encoding = p->encoding;
q->channels = p->channels;
q->precision = p->precision;
return 0;
return lmcaudio_rate(p->sample_rate);
}
int
@ -619,14 +613,6 @@ lmcaudio_rate(rate)
return(0);
}
int
lmcaudio_stereo(channel, position)
int channel;
int position;
{
return(0);
}
#define PHYS(x) (pmap_extract( kernel_pmap, ((x)&PG_FRAME) ))
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: vidcaudio.c,v 1.17 1997/08/19 23:49:45 augustss Exp $ */
/* $NetBSD: vidcaudio.c,v 1.18 1997/08/24 22:31:26 augustss Exp $ */
/*
* Copyright (c) 1995 Melvin Tang-Richardson
@ -278,7 +278,7 @@ vidcaudio_close(addr)
* ************************************************************************* */
int vidcaudio_query_encoding __P((void *, struct audio_encoding *));
int vidcaudio_set_params __P((void *, int, struct audio_params *, struct audio_params *));
int vidcaudio_set_params __P((void *, int, int, struct audio_params *, struct audio_params *));
int vidcaudio_round_blocksize __P((void *, int));
int vidcaudio_set_out_port __P((void *, int));
int vidcaudio_get_out_port __P((void *));
@ -321,21 +321,16 @@ int vidcaudio_query_encoding ( void *addr, struct audio_encoding *fp )
}
int
vidcaudio_set_params(addr, mode, p, q)
vidcaudio_set_params(addr, setmode, usemode, p, r)
void *addr;
struct audio_params *p, *q;
int setmode, usemode;
struct audio_params *p, *r;
{
if (p->encoding != AUDIO_ENCODING_ULAW ||
p->channels != 8)
return EINVAL;
vidcaudio_rate(4 * p->sample_rate / (3 * 1024)); /* XXX probably wrong */
p->sw_code = 0;
/* Update setting for the other mode. */
q->sample_rate = p->sample_rate;
q->encoding = p->encoding;
q->channels = p->channels;
q->precision = p->precision;
return 0;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: am7930_sparc.c,v 1.27 1997/08/19 23:49:54 augustss Exp $ */
/* $NetBSD: am7930_sparc.c,v 1.28 1997/08/24 22:31:27 augustss Exp $ */
/*
* Copyright (c) 1995 Rolf Grossmann
@ -393,10 +393,10 @@ amd7930_close(addr)
}
int
amd7930_set_params(addr, mode, p, q)
amd7930_set_params(addr, setmode, usemode, p, r)
void *addr;
int mode;
struct audio_params *p, *q;
int setmode, usemode;
struct audio_params *p, *r;
{
if (p->sample_rate < 7500 || p->sample_rate > 8500 ||
p->encoding != AUDIO_ENCODING_ULAW ||
@ -405,12 +405,6 @@ amd7930_set_params(addr, mode, p, q)
return EINVAL;
p->sample_rate = 8000; /* no other sampling rates supported by amd chip */
/* Update setting for the other mode. */
q->sample_rate = p->sample_rate;
q->encoding = p->encoding;
q->channels = p->channels;
q->precision = p->precision;
return 0;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: amd7930.c,v 1.27 1997/08/19 23:49:54 augustss Exp $ */
/* $NetBSD: amd7930.c,v 1.28 1997/08/24 22:31:27 augustss Exp $ */
/*
* Copyright (c) 1995 Rolf Grossmann
@ -393,10 +393,10 @@ amd7930_close(addr)
}
int
amd7930_set_params(addr, mode, p, q)
amd7930_set_params(addr, setmode, usemode, p, r)
void *addr;
int mode;
struct audio_params *p, *q;
int setmode, usemode;
struct audio_params *p, *r;
{
if (p->sample_rate < 7500 || p->sample_rate > 8500 ||
p->encoding != AUDIO_ENCODING_ULAW ||
@ -405,12 +405,6 @@ amd7930_set_params(addr, mode, p, q)
return EINVAL;
p->sample_rate = 8000; /* no other sampling rates supported by amd chip */
/* Update setting for the other mode. */
q->sample_rate = p->sample_rate;
q->encoding = p->encoding;
q->channels = p->channels;
q->precision = p->precision;
return 0;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: audio.c,v 1.67 1997/08/19 23:49:56 augustss Exp $ */
/* $NetBSD: audio.c,v 1.68 1997/08/24 22:31:29 augustss Exp $ */
/*
* Copyright (c) 1991-1993 Regents of the University of California.
@ -117,8 +117,8 @@ static void mixer_signal __P((struct audio_softc *));
void audio_init_record __P((struct audio_softc *));
void audio_init_play __P((struct audio_softc *));
void audiostartr __P((struct audio_softc *));
void audiostartp __P((struct audio_softc *));
int audiostartr __P((struct audio_softc *));
int audiostartp __P((struct audio_softc *));
void audio_rint __P((void *));
void audio_pint __P((void *));
int audio_check_params __P((struct audio_params *));
@ -128,7 +128,7 @@ void audio_fill_silence __P((struct audio_params *, u_char *, int));
int audio_silence_copyout __P((struct audio_softc *, int, struct uio *));
void audio_init_ringbuffer __P((struct audio_ringbuffer *));
void audio_initbufs __P((struct audio_softc *));
int audio_initbufs __P((struct audio_softc *));
void audio_calcwater __P((struct audio_softc *));
static __inline int audio_sleep_timo __P((int *, char *, int));
static __inline int audio_sleep __P((int *, char *));
@ -504,23 +504,30 @@ audio_init_ringbuffer(rp)
rp->mmapped = 0;
}
void
int
audio_initbufs(sc)
struct audio_softc *sc;
{
struct audio_hw_if *hw = sc->hw_if;
int error;
DPRINTF(("audio_initbufs: mode=0x%x\n", sc->sc_mode));
audio_init_ringbuffer(&sc->sc_rr);
if (hw->init_input && (sc->sc_mode & AUMODE_RECORD))
hw->init_input(sc->hw_hdl, sc->sc_rr.start,
sc->sc_rr.end - sc->sc_rr.start);
if (hw->init_input && (sc->sc_mode & AUMODE_RECORD)) {
error = hw->init_input(sc->hw_hdl, sc->sc_rr.start,
sc->sc_rr.end - sc->sc_rr.start);
if (error)
return error;
}
audio_init_ringbuffer(&sc->sc_pr);
sc->sc_sil_count = 0;
if (hw->init_output && (sc->sc_mode & AUMODE_PLAY))
hw->init_output(sc->hw_hdl, sc->sc_pr.start,
sc->sc_pr.end - sc->sc_pr.start);
if (hw->init_output && (sc->sc_mode & AUMODE_PLAY)) {
error = hw->init_output(sc->hw_hdl, sc->sc_pr.start,
sc->sc_pr.end - sc->sc_pr.start);
if (error)
return error;
}
#ifdef AUDIO_INTR_TIME
sc->sc_pnintr = 0;
@ -540,6 +547,8 @@ audio_initbufs(sc)
DPRINTF(("audio: record blktime = %lu for %d\n",
sc->sc_rblktime, sc->sc_rr.blksize));
#endif
return 0;
}
void
@ -602,7 +611,9 @@ audio_open(dev, flags, ifmt, p)
int unit = AUDIOUNIT(dev);
struct audio_softc *sc;
int error;
int mode;
struct audio_hw_if *hw;
struct audio_info ai;
sc = audio_cd.cd_devs[unit];
if (!sc)
@ -623,10 +634,29 @@ audio_open(dev, flags, ifmt, p)
if (error)
return (error);
if (flags & FREAD)
sc->sc_async_audio = 0;
sc->sc_rchan = 0;
sc->sc_wchan = 0;
sc->sc_blkset = 0; /* Block sizes not set yet */
sc->sc_sil_count = 0;
sc->sc_rbus = 0;
sc->sc_pbus = 0;
sc->sc_eof = 0;
sc->sc_playdrop = 0;
sc->sc_full_duplex = (flags & (FWRITE|FREAD)) == (FWRITE|FREAD) &&
(hw->get_props(sc->hw_hdl) & AUDIO_PROP_FULLDUPLEX);
mode = 0;
if (flags & FREAD) {
sc->sc_open |= AUOPEN_READ;
if (flags & FWRITE)
mode |= AUMODE_RECORD;
}
if (flags & FWRITE) {
sc->sc_open |= AUOPEN_WRITE;
mode |= AUMODE_PLAY | AUMODE_PLAY_ALL;
}
/*
* Multiplex device: /dev/audio (MU-Law) and /dev/sound (linear)
@ -637,20 +667,7 @@ audio_open(dev, flags, ifmt, p)
/* /dev/audio */
sc->sc_rparams = audio_default;
sc->sc_pparams = audio_default;
if (flags & FREAD) {
error = hw->set_params(sc->hw_hdl, AUMODE_RECORD,
&sc->sc_rparams, &sc->sc_pparams);
if (error)
return (error);
}
if (flags & FWRITE) {
error = hw->set_params(sc->hw_hdl, AUMODE_PLAY,
&sc->sc_pparams, &sc->sc_rparams);
if (error)
return (error);
}
}
#ifdef DIAGNOSTIC
/*
* Sample rate and precision are supposed to be set to proper
@ -663,47 +680,31 @@ audio_open(dev, flags, ifmt, p)
}
#endif
sc->sc_blkset = 0; /* Block sizes not set yet */
AUDIO_INITINFO(&ai);
ai.record.sample_rate = sc->sc_rparams.sample_rate;
ai.record.encoding = sc->sc_rparams.encoding;
ai.record.channels = sc->sc_rparams.channels;
ai.record.precision = sc->sc_rparams.precision;
ai.play.sample_rate = sc->sc_pparams.sample_rate;
ai.play.encoding = sc->sc_pparams.encoding;
ai.play.channels = sc->sc_pparams.channels;
ai.play.precision = sc->sc_pparams.precision;
ai.mode = mode;
sc->sc_pr.blksize = sc->sc_rr.blksize = 0; /* force recalculation */
error = audiosetinfo(sc, &ai);
if (error)
goto bad;
if (flags & FREAD) {
audio_calc_blksize(sc, AUMODE_RECORD);
sc->sc_mode = AUMODE_RECORD;
}
if (flags & FWRITE) {
audio_calc_blksize(sc, AUMODE_PLAY);
sc->sc_mode = AUMODE_PLAY | AUMODE_PLAY_ALL;
}
audio_initbufs(sc);
audio_calcwater(sc);
sc->sc_playdrop = 0;
DPRINTF(("audio_open: rr.buf=%p-%p pr.buf=%p-%p\n",
sc->sc_rr.start, sc->sc_rr.end, sc->sc_pr.start, sc->sc_pr.end));
DPRINTF(("audio_open: done sc_mode = 0x%x\n", sc->sc_mode));
if (hw->commit_settings)
hw->commit_settings(sc->hw_hdl);
return 0;
sc->sc_rchan = 0;
sc->sc_wchan = 0;
sc->sc_rbus = 0;
sc->sc_pbus = 0;
sc->sc_eof = 0;
if ((flags & (FWRITE|FREAD)) == (FWRITE|FREAD))
sc->sc_full_duplex =
(hw->get_props(sc->hw_hdl) & AUDIO_PROP_FULLDUPLEX) != 0;
if (flags & FWRITE)
audio_init_play(sc);
if (flags & FREAD) {
/* Play takes precedence if HW is half-duplex */
if (sc->sc_full_duplex || (flags & FWRITE) == 0)
audio_init_record(sc);
}
return (0);
bad:
hw->close(sc->hw_hdl);
sc->sc_open = 0;
sc->sc_mode = 0;
sc->sc_full_duplex = 0;
return error;
}
/*
@ -715,7 +716,6 @@ audio_init_record(sc)
{
int s = splaudio();
sc->sc_mode |= AUMODE_RECORD;
if (sc->hw_if->speaker_ctl &&
(!sc->sc_full_duplex || (sc->sc_mode & AUMODE_PLAY) == 0))
sc->hw_if->speaker_ctl(sc->hw_hdl, SPKR_OFF);
@ -732,8 +732,6 @@ audio_init_play(sc)
int s = splaudio();
sc->sc_wstamp = sc->sc_pr.stamp;
sc->sc_mode |= AUMODE_PLAY;
if (sc->hw_if->speaker_ctl)
sc->hw_if->speaker_ctl(sc->hw_hdl, SPKR_ON);
splx(s);
@ -763,8 +761,10 @@ audio_drain(sc)
s = splaudio();
cb->used += cc;
cb->inp = inp;
audiostartp(sc);
error = audiostartp(sc);
splx(s);
if (error)
return error;
}
/*
* Play until a silence block has been played, then we
@ -831,6 +831,8 @@ audio_close(dev, flags, ifmt, p)
sc->sc_open &= ~AUOPEN_WRITE;
sc->sc_async_audio = 0;
sc->sc_mode = 0;
sc->sc_full_duplex = 0;
splx(s);
DPRINTF(("audio_close: done\n"));
@ -852,7 +854,10 @@ audio_read(dev, uio, ioflag)
if (cb->mmapped)
return EINVAL;
DPRINTF(("audio_read: cc=%d mode=%d\n", uio->uio_resid, sc->sc_mode));
#ifdef AUDIO_DEBUG
if (audiodebug > 1)
printf("audio_read: cc=%d mode=%d\n", uio->uio_resid, sc->sc_mode);
#endif
error = 0;
/*
@ -899,13 +904,16 @@ audio_read(dev, uio, ioflag)
return (error);
}
s = splaudio();
if (!sc->sc_rbus)
audiostartr(sc);
if (!sc->sc_rbus) {
error = audiostartr(sc);
if (error) goto err;
}
#ifdef AUDIO_DEBUG
if (audiodebug > 2)
printf("audio_read: sleep used=%d\n", cb->used);
#endif
error = audio_sleep(&sc->sc_rchan, "aud rd");
err:
splx(s);
if (error)
return (error);
@ -1104,6 +1112,7 @@ audio_write(dev, uio, ioflag)
if (!(sc->sc_mode & AUMODE_PLAY_ALL) && sc->sc_playdrop > 0) {
n = min(sc->sc_playdrop, uio->uio_resid);
DPRINTF(("audio_write: playdrop %d\n", n));
uio->uio_offset += n;
uio->uio_resid -= n;
sc->sc_playdrop -= n;
@ -1214,7 +1223,7 @@ audio_write(dev, uio, ioflag)
cb->needfill = 0;
cb->copying = 0;
if (!sc->sc_pbus && !cb->pause)
audiostartp(sc);
error = audiostartp(sc);
splx(s);
if (cc) {
#ifdef AUDIO_DEBUG
@ -1262,14 +1271,16 @@ audio_ioctl(dev, cmd, addr, flag, p)
DPRINTF(("AUDIO_FLUSH\n"));
audio_clear(sc);
s = splaudio();
audio_initbufs(sc);
error = audio_initbufs(sc);
if (error) {
splx(s);
return error;
}
if ((sc->sc_mode & AUMODE_PLAY) && !sc->sc_pbus)
audiostartp(sc);
/* Again, play takes precedence on half-duplex hardware */
if ((sc->sc_mode & AUMODE_RECORD) &&
(sc->sc_full_duplex ||
((sc->sc_mode & AUMODE_PLAY) == 0)))
audiostartr(sc);
error = audiostartp(sc);
if (!error &&
(sc->sc_mode & AUMODE_RECORD) && !sc->sc_rbus)
error = audiostartr(sc);
splx(s);
break;
@ -1400,19 +1411,17 @@ audio_poll(dev, events, p)
int revents = 0;
int s = splaudio();
#if 0
DPRINTF(("audio_poll: events=%d mode=%d rr.nblk=%d\n",
events, sc->sc_mode, sc->sc_rr.nblk));
#endif
DPRINTF(("audio_poll: events=0x%x mode=%d\n", events, sc->sc_mode));
if (events & (POLLIN | POLLRDNORM))
if ((sc->sc_mode & AUMODE_PLAY) ?
0/*XXX*/ : sc->sc_rr.used > sc->sc_rr.usedlow)
sc->sc_pr.stamp > sc->sc_wstamp :
sc->sc_rr.used > sc->sc_rr.usedlow)
revents |= events & (POLLIN | POLLRDNORM);
if (events & (POLLOUT | POLLWRNORM))
if (sc->sc_mode & AUMODE_RECORD ||
sc->sc_pr.used < sc->sc_pr.usedlow)
sc->sc_pr.used <= sc->sc_pr.usedlow)
revents |= events & (POLLOUT | POLLWRNORM);
if (revents == 0) {
@ -1474,12 +1483,12 @@ audio_mmap(dev, off, prot)
audio_fill_silence(&sc->sc_pparams, cb->start, cb->bufsize);
s = splaudio();
if (!sc->sc_pbus)
audiostartp(sc);
(void)audiostartp(sc);
splx(s);
} else {
s = splaudio();
if (!sc->sc_rbus)
audiostartr(sc);
(void)audiostartr(sc);
splx(s);
}
}
@ -1487,7 +1496,7 @@ audio_mmap(dev, off, prot)
return hw->mappage(sc->hw_hdl, cb->start, off, prot);
}
void
int
audiostartr(sc)
struct audio_softc *sc;
{
@ -1501,12 +1510,13 @@ audiostartr(sc)
sc->sc_rr.blksize, audio_rint, (void *)sc);
if (error) {
DPRINTF(("audiostartr failed: %d\n", error));
audio_clear(sc);
} else
sc->sc_rbus = 1;
return error;
}
sc->sc_rbus = 1;
return 0;
}
void
int
audiostartp(sc)
struct audio_softc *sc;
{
@ -1520,11 +1530,12 @@ audiostartp(sc)
error = sc->hw_if->start_output(sc->hw_hdl, sc->sc_pr.outp,
sc->sc_pr.blksize, audio_pint, (void *)sc);
if (error) {
DPRINTF(("audiostartp: failed: %d\n", error));
} else {
sc->sc_pbus = 1;
DPRINTF(("audiostartp failed: %d\n", error));
return error;
}
sc->sc_pbus = 1;
}
return 0;
}
/*
@ -1599,7 +1610,7 @@ audio_pint(v)
struct audio_hw_if *hw = sc->hw_if;
struct audio_ringbuffer *cb = &sc->sc_pr;
u_char *inp;
int cc;
int cc, ccr;
int error;
cb->outp += cb->blksize;
@ -1612,8 +1623,8 @@ audio_pint(v)
printf("audio_pint: mmapped outp=%p cc=%d inp=%p\n",
cb->outp, cb->blksize, cb->inp);
#endif
hw->start_output(sc->hw_hdl, cb->outp, cb->blksize,
audio_pint, (void *)sc);
(void)hw->start_output(sc->hw_hdl, cb->outp, cb->blksize,
audio_pint, (void *)sc);
return;
}
@ -1657,11 +1668,12 @@ audio_pint(v)
} else {
inp = cb->inp;
cc = cb->blksize - (inp - cb->start) % cb->blksize;
ccr = cc / sc->sc_pparams.factor;
if (cb->pause)
cb->pdrops += cc;
cb->pdrops += ccr;
else {
cb->drops += cc;
sc->sc_playdrop += cc;
cb->drops += ccr;
sc->sc_playdrop += ccr;
}
audio_pint_silence(sc, cb, inp, cc);
inp += cc;
@ -1741,8 +1753,8 @@ audio_rint(v)
printf("audio_rint: mmapped inp=%p cc=%d\n",
cb->inp, cb->blksize);
#endif
hw->start_output(sc->hw_hdl, cb->inp, cb->blksize,
audio_rint, (void *)sc);
(void)hw->start_input(sc->hw_hdl, cb->inp, cb->blksize,
audio_rint, (void *)sc);
return;
}
@ -1775,12 +1787,18 @@ audio_rint(v)
cb->used += cb->blksize;
if (cb->pause) {
DPRINTF(("audio_rint: pdrops %lu\n", cb->pdrops));
#ifdef AUDIO_DEBUG
if (audiodebug > 1)
printf("audio_rint: pdrops %lu\n", cb->pdrops);
#endif
cb->pdrops += cb->blksize;
cb->outp += cb->blksize;
cb->used -= cb->blksize;
} else if (cb->used + cb->blksize >= cb->usedhigh && !cb->copying) {
DPRINTF(("audio_rint: drops %lu\n", cb->drops));
#ifdef AUDIO_DEBUG
if (audiodebug > 1)
printf("audio_rint: drops %lu\n", cb->drops);
#endif
cb->drops += cb->blksize;
cb->outp += cb->blksize;
cb->used -= cb->blksize;
@ -1866,20 +1884,27 @@ audiosetinfo(sc, ai)
struct audio_info *ai;
{
struct audio_prinfo *r = &ai->record, *p = &ai->play;
int cleared = 0;
int s, error = 0;
int cleared;
int s, setmode;
int error;
struct audio_hw_if *hw = sc->hw_if;
mixer_ctrl_t ct;
struct audio_params pp, rp;
int np, nr;
unsigned int blks;
int oldpblksize, oldrblksize;
int rbus, pbus;
if (hw == 0) /* HW has not attached */
return(ENXIO);
pp = sc->sc_pparams;
rp = sc->sc_rparams;
rbus = sc->sc_rbus;
pbus = sc->sc_pbus;
error = 0;
cleared = 0;
pp = sc->sc_pparams; /* Temporary encoding storage in */
rp = sc->sc_rparams; /* case setting the modes fails. */
nr = np = 0;
if (p->sample_rate != ~0) {
@ -1924,17 +1949,14 @@ audiosetinfo(sc, ai)
return error;
if (np && (error = audio_check_params(&pp)))
return error;
setmode = 0;
if (nr) {
if (!cleared)
audio_clear(sc);
cleared = 1;
rp.sw_code = 0;
rp.factor = 1;
error = hw->set_params(sc->hw_hdl, AUMODE_RECORD,
&rp, &sc->sc_pparams);
if (error)
return (error);
sc->sc_rparams = rp;
setmode |= AUMODE_RECORD;
}
if (np) {
if (!cleared)
@ -1942,11 +1964,49 @@ audiosetinfo(sc, ai)
cleared = 1;
pp.sw_code = 0;
pp.factor = 1;
error = hw->set_params(sc->hw_hdl, AUMODE_PLAY,
&pp, &sc->sc_rparams);
setmode |= AUMODE_PLAY;
}
if (ai->mode != ~0) {
if (!cleared)
audio_clear(sc);
cleared = 1;
sc->sc_mode = ai->mode;
if (sc->sc_mode & AUMODE_PLAY_ALL)
sc->sc_mode |= AUMODE_PLAY;
if ((sc->sc_mode & AUMODE_PLAY) && !sc->sc_full_duplex)
/* Play takes precedence */
sc->sc_mode &= ~AUMODE_RECORD;
}
if (setmode) {
int indep = hw->get_props(sc->hw_hdl) & AUDIO_PROP_INDEPENDENT;
if (!indep) {
if (setmode == AUMODE_RECORD)
pp = rp;
else if (setmode == AUMODE_PLAY)
rp = pp;
}
error = hw->set_params(sc->hw_hdl, setmode, sc->sc_mode, &pp, &rp);
if (error)
return (error);
sc->sc_pparams = pp;
if (!indep) {
if (setmode == AUMODE_RECORD) {
pp.sample_rate = rp.sample_rate;
pp.encoding = rp.encoding;
pp.channels = rp.channels;
pp.precision = rp.precision;
} else if (setmode == AUMODE_PLAY) {
rp.sample_rate = pp.sample_rate;
rp.encoding = pp.encoding;
rp.channels = pp.channels;
rp.precision = pp.precision;
}
}
if (setmode & AUMODE_RECORD)
sc->sc_rparams = rp;
if (setmode & AUMODE_PLAY)
sc->sc_pparams = pp;
}
oldpblksize = sc->sc_pr.blksize;
@ -2002,18 +2062,22 @@ audiosetinfo(sc, ai)
if (p->pause != (u_char)~0) {
sc->sc_pr.pause = p->pause;
if (!p->pause) {
if (!p->pause && !sc->sc_pbus) {
s = splaudio();
audiostartp(sc);
error = audiostartp(sc);
splx(s);
if (error)
return error;
}
}
if (r->pause != (u_char)~0) {
sc->sc_rr.pause = r->pause;
if (!r->pause) {
if (!r->pause && !sc->sc_rbus) {
s = splaudio();
audiostartr(sc);
error = audiostartr(sc);
splx(s);
if (error)
return error;
}
}
@ -2036,16 +2100,8 @@ audiosetinfo(sc, ai)
}
if (ai->mode != ~0) {
if (!cleared)
audio_clear(sc);
cleared = 1;
sc->sc_mode = ai->mode;
if (sc->sc_mode & AUMODE_PLAY) {
if (sc->sc_mode & AUMODE_PLAY)
audio_init_play(sc);
if (!sc->sc_full_duplex) /* Play takes precedence */
sc->sc_mode &= ~AUMODE_RECORD;
}
if (sc->sc_mode & AUMODE_RECORD)
audio_init_record(sc);
}
@ -2060,17 +2116,22 @@ audiosetinfo(sc, ai)
if (cleared) {
s = splaudio();
audio_initbufs(sc);
error = audio_initbufs(sc);
if (error) goto err;
if (sc->sc_pr.blksize != oldpblksize ||
sc->sc_rr.blksize != oldrblksize)
audio_calcwater(sc);
if (sc->sc_mode & AUMODE_PLAY)
audiostartp(sc);
if ((sc->sc_mode & AUMODE_RECORD) &&
(sc->sc_full_duplex ||
((sc->sc_mode & AUMODE_PLAY) == 0)))
audiostartr(sc);
if ((sc->sc_mode & AUMODE_PLAY) &&
pbus && !sc->sc_pbus)
error = audiostartp(sc);
if (!error &&
(sc->sc_mode & AUMODE_RECORD) &&
rbus && !sc->sc_rbus)
error = audiostartr(sc);
err:
splx(s);
if (error)
return error;
}
/* Change water marks after initializing the buffers. */

View File

@ -1,4 +1,4 @@
/* $NetBSD: audio_if.h,v 1.19 1997/08/19 23:49:58 augustss Exp $ */
/* $NetBSD: audio_if.h,v 1.20 1997/08/24 22:31:30 augustss Exp $ */
/*
* Copyright (c) 1994 Havard Eidnes.
@ -68,7 +68,7 @@ struct audio_hw_if {
* The values in the params struct may be changed (e.g. rounding
* to the nearest sample rate.)
*/
int (*set_params)__P((void *, int, struct audio_params *, struct audio_params *));
int (*set_params)__P((void *, int, int, struct audio_params *, struct audio_params *));
/* Hardware may have some say in the blocksize to choose */
int (*round_blocksize)__P((void *, int));

View File

@ -1,4 +1,4 @@
/* $NetBSD: am7930.c,v 1.27 1997/08/19 23:49:54 augustss Exp $ */
/* $NetBSD: am7930.c,v 1.28 1997/08/24 22:31:27 augustss Exp $ */
/*
* Copyright (c) 1995 Rolf Grossmann
@ -393,10 +393,10 @@ amd7930_close(addr)
}
int
amd7930_set_params(addr, mode, p, q)
amd7930_set_params(addr, setmode, usemode, p, r)
void *addr;
int mode;
struct audio_params *p, *q;
int setmode, usemode;
struct audio_params *p, *r;
{
if (p->sample_rate < 7500 || p->sample_rate > 8500 ||
p->encoding != AUDIO_ENCODING_ULAW ||
@ -405,12 +405,6 @@ amd7930_set_params(addr, mode, p, q)
return EINVAL;
p->sample_rate = 8000; /* no other sampling rates supported by amd chip */
/* Update setting for the other mode. */
q->sample_rate = p->sample_rate;
q->encoding = p->encoding;
q->channels = p->channels;
q->precision = p->precision;
return 0;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: ad1848.c,v 1.39 1997/08/20 15:26:25 augustss Exp $ */
/* $NetBSD: ad1848.c,v 1.40 1997/08/24 22:31:31 augustss Exp $ */
/*
* Copyright (c) 1994 John Brezak
@ -497,7 +497,7 @@ ad1848_attach(sc)
int i;
struct ad1848_volume vol_mid = {220, 220};
struct ad1848_volume vol_0 = {0, 0};
struct audio_params params, xparams;
struct audio_params pparams, rparams;
sc->sc_locked = 0;
sc->sc_playrun = NOTRUNNING;
@ -532,10 +532,9 @@ ad1848_attach(sc)
}
ad1848_reset(sc);
params = audio_default;
(void) ad1848_set_params(sc, AUMODE_RECORD, &params, &xparams);
params = audio_default;
(void) ad1848_set_params(sc, AUMODE_PLAY, &params, &xparams);
pparams = audio_default;
rparams = audio_default;
(void) ad1848_set_params(sc, AUMODE_RECORD|AUMODE_PLAY, 0, &pparams, &rparams);
/* Set default gains */
(void) ad1848_set_rec_gain(sc, &vol_mid);
@ -1015,44 +1014,45 @@ ad1848_query_encoding(addr, fp)
}
int
ad1848_set_params(addr, mode, p, q)
ad1848_set_params(addr, setmode, usemode, p, r)
void *addr;
int mode;
struct audio_params *p, *q;
int setmode, usemode;
struct audio_params *p, *r;
{
struct ad1848_softc *sc = addr;
int error, bits, enc;
void (*swcode) __P((void *, u_char *buf, int cnt));
void (*pswcode) __P((void *, u_char *buf, int cnt));
void (*rswcode) __P((void *, u_char *buf, int cnt));
DPRINTF(("ad1848_set_params: %d %d %d %ld\n",
p->encoding, p->precision, p->channels, p->sample_rate));
enc = p->encoding;
swcode = 0;
pswcode = rswcode = 0;
switch (enc) {
case AUDIO_ENCODING_SLINEAR_LE:
if (p->precision == 8) {
enc = AUDIO_ENCODING_ULINEAR_LE;
swcode = change_sign8;
pswcode = rswcode = change_sign8;
}
break;
case AUDIO_ENCODING_SLINEAR_BE:
if (p->precision == 16 && sc->mode == 1) {
enc = AUDIO_ENCODING_SLINEAR_LE;
swcode = swap_bytes;
pswcode = rswcode = swap_bytes;
}
break;
case AUDIO_ENCODING_ULINEAR_LE:
if (p->precision == 16) {
enc = AUDIO_ENCODING_SLINEAR_LE;
swcode = change_sign16;
pswcode = rswcode = change_sign16;
}
break;
case AUDIO_ENCODING_ULINEAR_BE:
if (p->precision == 16) {
enc = AUDIO_ENCODING_SLINEAR_LE;
swcode = mode == AUMODE_PLAY ?
swap_bytes_change_sign16 : change_sign16_swap_bytes;
pswcode = swap_bytes_change_sign16;
rswcode = change_sign16_swap_bytes;
}
break;
}
@ -1085,29 +1085,24 @@ ad1848_set_params(addr, mode, p, q)
return EINVAL;
break;
default:
return (EINVAL);
return EINVAL;
}
if (p->channels < 1 || p->channels > 2)
return(EINVAL);
return EINVAL;
error = ad1848_set_speed(sc, &p->sample_rate);
if (error)
return error;
p->sw_code = swcode;
p->sw_code = pswcode;
r->sw_code = rswcode;
sc->format_bits = bits;
sc->channels = p->channels;
sc->precision = p->precision;
sc->need_commit = 1;
/* Update setting for the other mode. */
q->sample_rate = p->sample_rate;
q->encoding = p->encoding;
q->channels = p->channels;
q->precision = p->precision;
DPRINTF(("ad1848_set_params succeeded, bits=%x\n", bits));
return (0);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: ad1848var.h,v 1.19 1997/08/20 15:26:27 augustss Exp $ */
/* $NetBSD: ad1848var.h,v 1.20 1997/08/24 22:31:32 augustss Exp $ */
/*
* Copyright (c) 1994 John Brezak
@ -116,7 +116,7 @@ void ad1848_close __P((void *));
void ad1848_forceintr __P((struct ad1848_softc *));
int ad1848_query_encoding __P((void *, struct audio_encoding *));
int ad1848_set_params __P((void *, int, struct audio_params *, struct audio_params *));
int ad1848_set_params __P((void *, int, int, struct audio_params *, struct audio_params *));
int ad1848_round_blocksize __P((void *, int));

View File

@ -1,4 +1,4 @@
/* $NetBSD: gus.c,v 1.40 1997/08/19 23:50:00 augustss Exp $ */
/* $NetBSD: gus.c,v 1.41 1997/08/24 22:31:33 augustss Exp $ */
/*-
* Copyright (c) 1996 The NetBSD Foundation, Inc.
@ -357,8 +357,8 @@ int gus_set_in_gain __P((caddr_t, u_int, u_char));
int gus_get_in_gain __P((caddr_t));
int gus_set_out_gain __P((caddr_t, u_int, u_char));
int gus_get_out_gain __P((caddr_t));
int gus_set_params __P((void *, int, struct audio_params *, struct audio_params *));
int gusmax_set_params __P((void *, int, struct audio_params *, struct audio_params *));
int gus_set_params __P((void *, int, int, struct audio_params *, struct audio_params *));
int gusmax_set_params __P((void *, int, int, struct audio_params *, struct audio_params *));
int gus_round_blocksize __P((void *, int));
int gus_set_out_port __P((void *, int));
int gus_get_out_port __P((void *));
@ -2088,27 +2088,27 @@ gus_set_volume(sc, voice, volume)
*/
int
gusmax_set_params(addr, mode, p, q)
gusmax_set_params(addr, setmode, usemode, p, r)
void *addr;
int mode;
struct audio_params *p, *q;
int setmode, usemode;
struct audio_params *p, *r;
{
struct ad1848_softc *ac = addr;
struct gus_softc *sc = ac->parent;
int error;
error = ad1848_set_params(ac, mode, p, q);
error = ad1848_set_params(ac, setmode, usemode, p, r);
if (error)
return error;
error = gus_set_params(sc, mode, p, q);
error = gus_set_params(sc, setmode, usemode, p, r);
return error;
}
int
gus_set_params(addr, mode, p, q)
gus_set_params(addr, setmode, usemode, p, r)
void *addr;
int mode;
struct audio_params *p, *q;
int setmode, usemode;
struct audio_params *p, *r;
{
struct gus_softc *sc = addr;
int s;
@ -2143,32 +2143,26 @@ gus_set_params(addr, mode, p, q)
if (p->sample_rate > gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES])
p->sample_rate = gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES];
if (mode == AUMODE_RECORD)
if (setmode & AUMODE_RECORD)
sc->sc_irate = p->sample_rate;
else
if (setmode & AUMODE_PLAY)
sc->sc_orate = p->sample_rate;
switch (p->encoding) {
case AUDIO_ENCODING_ULAW:
p->sw_code = mode == AUMODE_PLAY ?
mulaw_to_ulinear8 : ulinear8_to_mulaw;
p->sw_code = mulaw_to_ulinear8;
r->sw_code = ulinear8_to_mulaw;
break;
case AUDIO_ENCODING_ALAW:
p->sw_code = mode == AUMODE_PLAY ?
alaw_to_ulinear8 : ulinear8_to_alaw;
p->sw_code = alaw_to_ulinear8;
r->sw_code = ulinear8_to_alaw;
break;
case AUDIO_ENCODING_ULINEAR_BE:
case AUDIO_ENCODING_SLINEAR_BE:
p->sw_code = swap_bytes;
r->sw_code = p->sw_code = swap_bytes;
break;
default:
p->sw_code = 0;
}
/* Update setting for the other mode. */
q->encoding = p->encoding;
q->channels = p->channels;
q->precision = p->precision;
return 0;
}
@ -2260,8 +2254,11 @@ gusmax_commit_settings(addr)
{
struct ad1848_softc *ac = addr;
struct gus_softc *sc = ac->parent;
int error;
(void) ad1848_commit_settings(ac);
error = ad1848_commit_settings(ac);
if (error)
return error;
return gus_commit_settings(sc);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: sbdsp.c,v 1.67 1997/08/19 23:35:44 augustss Exp $ */
/* $NetBSD: sbdsp.c,v 1.68 1997/08/24 22:31:35 augustss Exp $ */
/*
* Copyright (c) 1991-1993 Regents of the University of California.
@ -316,7 +316,7 @@ void
sbdsp_attach(sc)
struct sbdsp_softc *sc;
{
struct audio_params params, xparams;
struct audio_params pparams, rparams;
int i;
u_int v;
@ -340,10 +340,9 @@ sbdsp_attach(sc)
}
}
params = audio_default;
sbdsp_set_params(sc, AUMODE_RECORD, &params, &xparams);
params = audio_default;
sbdsp_set_params(sc, AUMODE_PLAY, &params, &xparams);
pparams = audio_default;
rparams = audio_default;
sbdsp_set_params(sc, AUMODE_RECORD|AUMODE_PLAY, 0, &pparams, &rparams);
sbdsp_set_in_port(sc, SB_MIC_VOL);
sbdsp_set_out_port(sc, SB_MASTER_VOL);
@ -490,153 +489,162 @@ sbdsp_query_encoding(addr, fp)
}
int
sbdsp_set_params(addr, mode, p, q)
sbdsp_set_params(addr, setmode, usemode, play, rec)
void *addr;
int mode;
struct audio_params *p, *q;
int setmode, usemode;
struct audio_params *play, *rec;
{
struct sbdsp_softc *sc = addr;
struct sbmode *m;
u_int rate, tc = 1, bmode = -1;
u_int rate, tc, bmode;
void (*swcode) __P((void *, u_char *buf, int cnt));
int factor = 1;
int factor;
int model;
struct audio_params *p;
int mode;
model = sc->sc_model;
if (model > SB_16)
model = SB_16; /* later models work like SB16 */
for(m = mode == AUMODE_PLAY ? sbpmodes : sbrmodes;
m->model != -1; m++) {
if (model == m->model &&
p->channels == m->channels &&
p->precision == m->precision &&
p->sample_rate >= m->lowrate &&
p->sample_rate < m->highrate)
break;
}
if (m->model == -1)
return EINVAL;
rate = p->sample_rate;
swcode = 0;
if (model == SB_16) {
switch (p->encoding) {
case AUDIO_ENCODING_SLINEAR_BE:
if (p->precision == 16)
/* Set first record info, then play info */
for(mode = AUMODE_RECORD; mode != -1;
mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
if ((setmode & mode) == 0)
continue;
p = mode == AUMODE_PLAY ? play : rec;
for(m = mode == AUMODE_PLAY ? sbpmodes : sbrmodes;
m->model != -1; m++) {
if (model == m->model &&
p->channels == m->channels &&
p->precision == m->precision &&
p->sample_rate >= m->lowrate &&
p->sample_rate < m->highrate)
break;
}
if (m->model == -1)
return EINVAL;
rate = p->sample_rate;
swcode = 0;
factor = 1;
tc = 1;
bmode = -1;
if (model == SB_16) {
switch (p->encoding) {
case AUDIO_ENCODING_SLINEAR_BE:
if (p->precision == 16)
swcode = swap_bytes;
/* fall into */
case AUDIO_ENCODING_SLINEAR_LE:
bmode = SB_BMODE_SIGNED;
break;
case AUDIO_ENCODING_ULINEAR_BE:
if (p->precision == 16)
swcode = swap_bytes;
/* fall into */
case AUDIO_ENCODING_ULINEAR_LE:
bmode = SB_BMODE_UNSIGNED;
break;
case AUDIO_ENCODING_ULAW:
if (mode == AUMODE_PLAY) {
swcode = mulaw_to_ulinear16;
factor = 2;
m = &sbpmodes[PLAY16];
} else
swcode = ulinear8_to_mulaw;
bmode = SB_BMODE_UNSIGNED;
break;
case AUDIO_ENCODING_ALAW:
if (mode == AUMODE_PLAY) {
swcode = alaw_to_ulinear16;
factor = 2;
m = &sbpmodes[PLAY16];
} else
swcode = ulinear8_to_alaw;
bmode = SB_BMODE_UNSIGNED;
break;
default:
return EINVAL;
}
if (p->channels == 2)
bmode |= SB_BMODE_STEREO;
} else if (m->model == SB_JAZZ && m->precision == 16) {
switch (p->encoding) {
case AUDIO_ENCODING_SLINEAR_LE:
break;
case AUDIO_ENCODING_ULINEAR_LE:
swcode = change_sign16;
break;
case AUDIO_ENCODING_SLINEAR_BE:
swcode = swap_bytes;
/* fall into */
case AUDIO_ENCODING_SLINEAR_LE:
bmode = SB_BMODE_SIGNED;
break;
case AUDIO_ENCODING_ULINEAR_BE:
if (p->precision == 16)
swcode = swap_bytes;
/* fall into */
case AUDIO_ENCODING_ULINEAR_LE:
bmode = SB_BMODE_UNSIGNED;
break;
case AUDIO_ENCODING_ULAW:
if (mode == AUMODE_PLAY) {
swcode = mulaw_to_ulinear16;
factor = 2;
m = &sbpmodes[PLAY16];
} else
swcode = ulinear8_to_mulaw;
bmode = SB_BMODE_UNSIGNED;
break;
case AUDIO_ENCODING_ALAW:
if (mode == AUMODE_PLAY) {
swcode = alaw_to_ulinear16;
factor = 2;
m = &sbpmodes[PLAY16];
} else
swcode = ulinear8_to_alaw;
bmode = SB_BMODE_UNSIGNED;
break;
default:
return EINVAL;
break;
case AUDIO_ENCODING_ULINEAR_BE:
swcode = mode == AUMODE_PLAY ?
swap_bytes_change_sign16 : change_sign16_swap_bytes;
break;
case AUDIO_ENCODING_ULAW:
swcode = mode == AUMODE_PLAY ?
mulaw_to_ulinear8 : ulinear8_to_mulaw;
break;
case AUDIO_ENCODING_ALAW:
swcode = mode == AUMODE_PLAY ?
alaw_to_ulinear8 : ulinear8_to_alaw;
break;
default:
return EINVAL;
}
tc = SB_RATE_TO_TC(p->sample_rate * p->channels);
p->sample_rate = SB_TC_TO_RATE(tc) / p->channels;
} else {
switch (p->encoding) {
case AUDIO_ENCODING_SLINEAR_BE:
case AUDIO_ENCODING_SLINEAR_LE:
swcode = change_sign8;
break;
case AUDIO_ENCODING_ULINEAR_BE:
case AUDIO_ENCODING_ULINEAR_LE:
break;
case AUDIO_ENCODING_ULAW:
swcode = mode == AUMODE_PLAY ?
mulaw_to_ulinear8 : ulinear8_to_mulaw;
break;
case AUDIO_ENCODING_ALAW:
swcode = mode == AUMODE_PLAY ?
alaw_to_ulinear8 : ulinear8_to_alaw;
break;
default:
return EINVAL;
}
tc = SB_RATE_TO_TC(p->sample_rate * p->channels);
p->sample_rate = SB_TC_TO_RATE(tc) / p->channels;
}
if (p->channels == 2)
bmode |= SB_BMODE_STEREO;
} else if (m->model == SB_JAZZ && m->precision == 16) {
switch (p->encoding) {
case AUDIO_ENCODING_SLINEAR_LE:
break;
case AUDIO_ENCODING_ULINEAR_LE:
swcode = change_sign16;
break;
case AUDIO_ENCODING_SLINEAR_BE:
swcode = swap_bytes;
break;
case AUDIO_ENCODING_ULINEAR_BE:
swcode = mode == AUMODE_PLAY ?
swap_bytes_change_sign16 : change_sign16_swap_bytes;
break;
case AUDIO_ENCODING_ULAW:
swcode = mode == AUMODE_PLAY ?
mulaw_to_ulinear8 : ulinear8_to_mulaw;
break;
case AUDIO_ENCODING_ALAW:
swcode = mode == AUMODE_PLAY ?
alaw_to_ulinear8 : ulinear8_to_alaw;
break;
default:
return EINVAL;
if (mode == AUMODE_PLAY) {
sc->sc_orate = rate;
sc->sc_otc = tc;
sc->sc_omodep = m;
sc->sc_obmode = bmode;
} else {
sc->sc_irate = rate;
sc->sc_itc = tc;
sc->sc_imodep = m;
sc->sc_ibmode = bmode;
}
tc = SB_RATE_TO_TC(p->sample_rate * p->channels);
p->sample_rate = SB_TC_TO_RATE(tc) / p->channels;
} else {
switch (p->encoding) {
case AUDIO_ENCODING_SLINEAR_BE:
case AUDIO_ENCODING_SLINEAR_LE:
swcode = change_sign8;
break;
case AUDIO_ENCODING_ULINEAR_BE:
case AUDIO_ENCODING_ULINEAR_LE:
break;
case AUDIO_ENCODING_ULAW:
swcode = mode == AUMODE_PLAY ?
mulaw_to_ulinear8 : ulinear8_to_mulaw;
break;
case AUDIO_ENCODING_ALAW:
swcode = mode == AUMODE_PLAY ?
alaw_to_ulinear8 : ulinear8_to_alaw;
break;
default:
return EINVAL;
}
tc = SB_RATE_TO_TC(p->sample_rate * p->channels);
p->sample_rate = SB_TC_TO_RATE(tc) / p->channels;
p->sw_code = swcode;
p->factor = factor;
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, factor));
}
if (mode == AUMODE_PLAY) {
sc->sc_orate = rate;
sc->sc_otc = tc;
sc->sc_omodep = m;
sc->sc_obmode = bmode;
} else {
sc->sc_irate = rate;
sc->sc_itc = tc;
sc->sc_imodep = m;
sc->sc_ibmode = bmode;
}
p->sw_code = swcode;
p->factor = factor;
/* Update setting for the other mode. */
q->encoding = p->encoding;
q->channels = p->channels;
q->precision = p->precision;
/*
* XXX
* Should wait for chip to be idle.
*/
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, factor=%d\n",
sc->sc_model, mode, p->sample_rate, p->precision, p->channels,
p->encoding, tc, m->cmd, bmode, m->cmdchan, swcode, factor));
return 0;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: sbdspvar.h,v 1.28 1997/08/04 09:29:57 augustss Exp $ */
/* $NetBSD: sbdspvar.h,v 1.29 1997/08/24 22:31:36 augustss Exp $ */
/*
* Copyright (c) 1991-1993 Regents of the University of California.
@ -169,7 +169,7 @@ int sbdsp_get_out_gain __P((void *));
int sbdsp_set_monitor_gain __P((void *, u_int));
int sbdsp_get_monitor_gain __P((void *));
int sbdsp_query_encoding __P((void *, struct audio_encoding *));
int sbdsp_set_params __P((void *, int, struct audio_params *, struct audio_params *));
int sbdsp_set_params __P((void *, int, int, struct audio_params *, struct audio_params *));
int sbdsp_round_blocksize __P((void *, int));
int sbdsp_set_out_port __P((void *, int));
int sbdsp_get_out_port __P((void *));

View File

@ -1,4 +1,4 @@
/* $NetBSD: audioio.h,v 1.12 1997/07/27 01:17:10 augustss Exp $ */
/* $NetBSD: audioio.h,v 1.13 1997/08/24 22:31:37 augustss Exp $ */
/*
* Copyright (c) 1991-1993 Regents of the University of California.
@ -151,6 +151,7 @@ typedef struct audio_encoding {
#define AUDIO_GETPROPS _IOR('A', 34, int)
#define AUDIO_PROP_FULLDUPLEX 0x01
#define AUDIO_PROP_MMAP 0x02
#define AUDIO_PROP_INDEPENDENT 0x04
/*
* Mixer device
@ -258,6 +259,7 @@ typedef struct mixer_ctrl {
#define AudioNwave "wave"
#define AudioNmidi "midi"
#define AudioNmixerout "mixerout"
#define AudioNswap "swap"
#define AudioEmulaw "mulaw"
#define AudioEalaw "alaw"