summaryrefslogtreecommitdiff
path: root/sys/dev/audio.c
diff options
context:
space:
mode:
authorJacob Meuser <jakemsr@cvs.openbsd.org>2010-07-15 03:43:13 +0000
committerJacob Meuser <jakemsr@cvs.openbsd.org>2010-07-15 03:43:13 +0000
commit59cb4ff01f7202d2e69dd3011fd755605b7cc8da (patch)
tree454f4c2562bc96d6f292a0ddccc5df0e49f30ea2 /sys/dev/audio.c
parenta6e9a1c865707ccd6904e98b221c6be74b97f4d9 (diff)
add two new members to structs audio_encoding and audio_prinfo.
for both structs, the new members are 'bps' and 'msb', which describe the number of bytes per sample and data alignment in the sample, respectively. drivers must properly set these fields in the 'query_encoding', 'set_parameters' and 'get_default_params' hardware interface methods. discussed with ratchov, deraadt
Diffstat (limited to 'sys/dev/audio.c')
-rw-r--r--sys/dev/audio.c75
1 files changed, 53 insertions, 22 deletions
diff --git a/sys/dev/audio.c b/sys/dev/audio.c
index e3244dc6997..91fdddd069e 100644
--- a/sys/dev/audio.c
+++ b/sys/dev/audio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: audio.c,v 1.107 2009/11/09 17:53:39 nicm Exp $ */
+/* $OpenBSD: audio.c,v 1.108 2010/07/15 03:43:11 jakemsr Exp $ */
/* $NetBSD: audio.c,v 1.119 1999/11/09 16:50:47 augustss Exp $ */
/*
@@ -100,8 +100,6 @@ int audiodebug = 0;
#define ROUNDSIZE(x) x &= -16 /* round to nice boundary */
-#define AUDIO_BPS(bits) ((bits) <= 8 ? 1 : (((bits) <= 16) ? 2 : 4))
-
int audio_blk_ms = AUDIO_BLK_MS;
int audiosetinfo(struct audio_softc *, struct audio_info *);
@@ -218,7 +216,7 @@ int au_portof(struct audio_softc *, char *);
/* The default audio mode: 8 kHz mono ulaw */
struct audio_params audio_default =
- { 8000, AUDIO_ENCODING_ULAW, 8, 1, 0, 1 };
+ { 8000, AUDIO_ENCODING_ULAW, 8, 1, 1, 1, 0, 1 };
struct cfattach audio_ca = {
sizeof(struct audio_softc), audioprobe, audioattach,
@@ -568,8 +566,8 @@ audio_printsc(struct audio_softc *sc)
void
audio_print_params(char *s, struct audio_params *p)
{
- printf("audio: %s sr=%ld, enc=%d, chan=%d, prec=%d\n", s,
- p->sample_rate, p->encoding, p->channels, p->precision);
+ printf("audio: %s sr=%ld, enc=%d, chan=%d, prec=%d bps=%d\n", s,
+ p->sample_rate, p->encoding, p->channels, p->precision, p->bps);
}
#endif
@@ -891,7 +889,7 @@ audio_initbufs(struct audio_softc *sc)
sc->sc_pnintr = 0;
sc->sc_pblktime = (u_long)(
(u_long)sc->sc_pr.blksize * 100000 /
- (u_long)(AUDIO_BPS(sc->sc_pparams.precision) *
+ (u_long)(sc->sc_pparams.bps *
sc->sc_pparams.channels *
sc->sc_pparams.sample_rate)) * 10;
DPRINTF(("audio: play blktime = %lu for %d\n",
@@ -899,7 +897,7 @@ audio_initbufs(struct audio_softc *sc)
sc->sc_rnintr = 0;
sc->sc_rblktime = (u_long)(
(u_long)sc->sc_rr.blksize * 100000 /
- (u_long)(AUDIO_BPS(sc->sc_rparams.precision) *
+ (u_long)(sc->sc_rparams.bps *
sc->sc_rparams.channels *
sc->sc_rparams.sample_rate)) * 10;
DPRINTF(("audio: record blktime = %lu for %d\n",
@@ -1041,11 +1039,15 @@ audio_open(dev_t dev, struct audio_softc *sc, int flags, int ifmt,
ai.record.encoding = sc->sc_rparams.encoding;
ai.record.channels = sc->sc_rparams.channels;
ai.record.precision = sc->sc_rparams.precision;
+ ai.record.bps = sc->sc_rparams.bps;
+ ai.record.msb = sc->sc_rparams.msb;
ai.record.pause = 0;
ai.play.sample_rate = sc->sc_pparams.sample_rate;
- ai.play.encoding = sc->sc_pparams.encoding;
+ ai.play.encoding = sc->sc_pparams.encoding;
ai.play.channels = sc->sc_pparams.channels;
ai.play.precision = sc->sc_pparams.precision;
+ ai.play.bps = sc->sc_pparams.bps;
+ ai.play.msb = sc->sc_pparams.msb;
ai.play.pause = 0;
ai.mode = mode;
sc->sc_rr.blkset = sc->sc_pr.blkset = 0; /* Block sizes not set yet */
@@ -1351,7 +1353,7 @@ audio_set_blksize(struct audio_softc *sc, int mode, int fpb) {
rb = &sc->sc_rr;
}
- fs = parm->channels * AUDIO_BPS(parm->precision);
+ fs = parm->channels * parm->bps;
bs = fpb * fs;
maxbs = rb->bufsize / 2;
if (bs > maxbs)
@@ -1387,7 +1389,7 @@ void
audio_fill_silence(struct audio_params *params, u_char *start, u_char *p, int n)
{
size_t rounderr;
- int i, samplesz, nsamples;
+ int i, nsamples;
u_char auzero[4] = {0, 0, 0, 0};
/*
@@ -1395,11 +1397,10 @@ audio_fill_silence(struct audio_params *params, u_char *start, u_char *p, int n)
* beginning of the sample, so we overwrite partially written
* ones.
*/
- samplesz = AUDIO_BPS(params->precision);
- rounderr = (p - start) % samplesz;
+ rounderr = (p - start) % params->bps;
p -= rounderr;
n += rounderr;
- nsamples = n / samplesz;
+ nsamples = n / params->bps;
switch (params->encoding) {
case AUDIO_ENCODING_SLINEAR_LE:
@@ -1412,10 +1413,16 @@ audio_fill_silence(struct audio_params *params, u_char *start, u_char *p, int n)
auzero[0] = 0x55;
break;
case AUDIO_ENCODING_ULINEAR_LE:
- auzero[samplesz - 1] = 0x80;
+ if (params->msb == 1)
+ auzero[params->bps - 1] = 0x80;
+ else
+ auzero[params->bps - 1] = 1 << ((params->precision + 7) % NBBY);
break;
case AUDIO_ENCODING_ULINEAR_BE:
- auzero[0] = 0x80;
+ if (params->msb == 1)
+ auzero[0] = 0x80;
+ else
+ auzero[0] = 1 << ((params->precision + 7) % NBBY);
break;
case AUDIO_ENCODING_MPEG_L1_STREAM:
case AUDIO_ENCODING_MPEG_L1_PACKETS:
@@ -1430,7 +1437,7 @@ audio_fill_silence(struct audio_params *params, u_char *start, u_char *p, int n)
break;
}
while (--nsamples >= 0) {
- for (i = 0; i < samplesz; i++)
+ for (i = 0; i < params->bps; i++)
*p++ = auzero[i];
}
}
@@ -1617,18 +1624,18 @@ audio_ioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
* original formula:
* sc->sc_rr.drops /
* sc->sc_rparams.factor /
- * (sc->sc_rparams.channels * AUDIO_BPS(sc->sc_rparams.precision))
+ * (sc->sc_rparams.channels * sc->sc_rparams.bps)
*/
case AUDIO_RERROR:
*(int *)addr = sc->sc_rr.drops /
(sc->sc_rparams.factor * sc->sc_rparams.channels *
- AUDIO_BPS(sc->sc_rparams.precision));
+ sc->sc_rparams.bps);
break;
case AUDIO_PERROR:
*(int *)addr = sc->sc_pr.drops /
(sc->sc_pparams.factor * sc->sc_pparams.channels *
- AUDIO_BPS(sc->sc_pparams.precision));
+ sc->sc_pparams.bps);
break;
/*
@@ -2603,6 +2610,22 @@ audiosetinfo(struct audio_softc *sc, struct audio_info *ai)
rp.precision = r->precision;
nr++;
}
+ if (p->bps != ~0) {
+ pp.bps = p->bps;
+ np++;
+ }
+ if (r->bps != ~0) {
+ rp.bps = r->bps;
+ nr++;
+ }
+ if (p->msb != ~0) {
+ pp.msb = p->msb;
+ np++;
+ }
+ if (r->msb != ~0) {
+ rp.msb = r->msb;
+ nr++;
+ }
if (p->channels != ~0) {
pp.channels = p->channels;
np++;
@@ -2669,11 +2692,15 @@ audiosetinfo(struct audio_softc *sc, struct audio_info *ai)
pp.encoding = rp.encoding;
pp.channels = rp.channels;
pp.precision = rp.precision;
+ pp.bps = rp.bps;
+ pp.msb = rp.msb;
} else if (setmode == AUMODE_PLAY) {
rp.sample_rate = pp.sample_rate;
rp.encoding = pp.encoding;
rp.channels = pp.channels;
rp.precision = pp.precision;
+ rp.bps = pp.bps;
+ rp.msb = pp.msb;
}
}
sc->sc_rparams = rp;
@@ -2711,7 +2738,7 @@ audiosetinfo(struct audio_softc *sc, struct audio_info *ai)
if (r->block_size == ~0 || r->block_size == 0) {
fpb = rp.sample_rate * audio_blk_ms / 1000;
} else {
- fs = rp.channels * AUDIO_BPS(rp.precision);
+ fs = rp.channels * rp.bps;
fpb = (r->block_size * rp.factor) / fs;
}
if (sc->sc_rr.blkset == 0)
@@ -2721,7 +2748,7 @@ audiosetinfo(struct audio_softc *sc, struct audio_info *ai)
if (p->block_size == ~0 || p->block_size == 0) {
fpb = pp.sample_rate * audio_blk_ms / 1000;
} else {
- fs = pp.channels * AUDIO_BPS(pp.precision);
+ fs = pp.channels * pp.bps;
fpb = (p->block_size * pp.factor) / fs;
}
if (sc->sc_pr.blkset == 0)
@@ -2894,6 +2921,10 @@ audiogetinfo(struct audio_softc *sc, struct audio_info *ai)
r->channels = sc->sc_rparams.channels;
p->precision = sc->sc_pparams.precision;
r->precision = sc->sc_rparams.precision;
+ p->bps = sc->sc_pparams.bps;
+ r->bps = sc->sc_rparams.bps;
+ p->msb = sc->sc_pparams.msb;
+ r->msb = sc->sc_rparams.msb;
p->encoding = sc->sc_pparams.encoding;
r->encoding = sc->sc_rparams.encoding;