Module Name: src
Committed By: martin
Date: Thu Apr 30 15:43:30 UTC 2020
Modified Files:
src/sys/dev/audio [netbsd-9]: audio.c
Log Message:
Pull up following revision(s) (requested by isaki in ticket #876):
sys/dev/audio/audio.c: revision 1.60
sys/dev/audio/audio.c: revision 1.62
Fix wrong parameter displayed in debug messages.
Restore backward compatibility with netbsd-7 audio.
For sticky parameters (encoding, precision, channels, sample_rate and pause):
- AUDIO_SETINFO for nonexistent track updates sticky parameters.
- AUDIO_GETINFO for nonexistent track reads sticky parameters.
For blocksize, hiwat, lowat and {play.record}.buffer_size:
- AUDIO_SETINFO for nonexistent track does nothing.
- AUDIO_GETINFO for nonexistent track returns dummy non-zero values.
Nonexistent track is a playback track on O_RDONLY descriptor for example,
or both tracks on /dev/audioctl.
To generate a diff of this commit:
cvs rdiff -u -r1.28.2.10 -r1.28.2.11 src/sys/dev/audio/audio.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/audio/audio.c
diff -u src/sys/dev/audio/audio.c:1.28.2.10 src/sys/dev/audio/audio.c:1.28.2.11
--- src/sys/dev/audio/audio.c:1.28.2.10 Thu Apr 30 15:40:50 2020
+++ src/sys/dev/audio/audio.c Thu Apr 30 15:43:30 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: audio.c,v 1.28.2.10 2020/04/30 15:40:50 martin Exp $ */
+/* $NetBSD: audio.c,v 1.28.2.11 2020/04/30 15:43:30 martin Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -142,7 +142,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.28.2.10 2020/04/30 15:40:50 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.28.2.11 2020/04/30 15:43:30 martin Exp $");
#ifdef _KERNEL_OPT
#include "audio.h"
@@ -542,8 +542,8 @@ static int audio_query_devinfo(struct au
static __inline int audio_track_readablebytes(const audio_track_t *);
static int audio_file_setinfo(struct audio_softc *, audio_file_t *,
const struct audio_info *);
-static int audio_track_setinfo_check(audio_format2_t *,
- const struct audio_prinfo *, const audio_format2_t *);
+static int audio_track_setinfo_check(audio_track_t *,
+ audio_format2_t *, const struct audio_prinfo *);
static void audio_track_setinfo_water(audio_track_t *,
const struct audio_info *);
static int audio_hw_setinfo(struct audio_softc *, const struct audio_info *,
@@ -6779,20 +6779,30 @@ audio_file_setinfo(struct audio_softc *s
memset(&saved_pfmt, 0, sizeof(saved_pfmt));
memset(&saved_rfmt, 0, sizeof(saved_rfmt));
- /* Set default value and save current parameters */
+ /*
+ * Set default value and save current parameters.
+ * For backward compatibility, use sticky parameters for nonexistent
+ * track.
+ */
if (ptrack) {
pfmt = ptrack->usrbuf.fmt;
saved_pfmt = ptrack->usrbuf.fmt;
saved_ai.play.pause = ptrack->is_pause;
+ } else {
+ pfmt = sc->sc_sound_pparams;
}
if (rtrack) {
rfmt = rtrack->usrbuf.fmt;
saved_rfmt = rtrack->usrbuf.fmt;
saved_ai.record.pause = rtrack->is_pause;
+ } else {
+ rfmt = sc->sc_sound_rparams;
}
saved_ai.mode = file->mode;
- /* Overwrite if specified */
+ /*
+ * Overwrite if specified.
+ */
mode = file->mode;
if (SPECIFIED(ai->mode)) {
/*
@@ -6811,35 +6821,35 @@ audio_file_setinfo(struct audio_softc *s
}
}
- if (ptrack) {
- pchanges = audio_track_setinfo_check(&pfmt, pi,
- &sc->sc_pmixer->hwbuf.fmt);
- if (pchanges == -1) {
+ pchanges = audio_track_setinfo_check(ptrack, &pfmt, pi);
+ if (pchanges == -1) {
#if defined(AUDIO_DEBUG)
- char fmtbuf[64];
- audio_format2_tostr(fmtbuf, sizeof(fmtbuf), &pfmt);
- TRACET(1, ptrack, "check play.params failed: %s",
- fmtbuf);
+ TRACEF(1, file, "check play.params failed: "
+ "%s %ubit %uch %uHz",
+ audio_encoding_name(pi->encoding),
+ pi->precision,
+ pi->channels,
+ pi->sample_rate);
#endif
- return EINVAL;
- }
- if (SPECIFIED(ai->mode))
- pchanges = 1;
+ return EINVAL;
}
- if (rtrack) {
- rchanges = audio_track_setinfo_check(&rfmt, ri,
- &sc->sc_rmixer->hwbuf.fmt);
- if (rchanges == -1) {
+
+ rchanges = audio_track_setinfo_check(rtrack, &rfmt, ri);
+ if (rchanges == -1) {
#if defined(AUDIO_DEBUG)
- char fmtbuf[64];
- audio_format2_tostr(fmtbuf, sizeof(fmtbuf), &rfmt);
- TRACET(1, rtrack, "check record.params failed: %s",
- fmtbuf);
+ TRACEF(1, file, "check record.params failed: "
+ "%s %ubit %uch %uHz",
+ audio_encoding_name(ri->encoding),
+ ri->precision,
+ ri->channels,
+ ri->sample_rate);
#endif
- return EINVAL;
- }
- if (SPECIFIED(ai->mode))
- rchanges = 1;
+ return EINVAL;
+ }
+
+ if (SPECIFIED(ai->mode)) {
+ pchanges = 1;
+ rchanges = 1;
}
/*
@@ -6849,16 +6859,27 @@ audio_file_setinfo(struct audio_softc *s
if (pchanges || rchanges) {
audio_file_clear(sc, file);
#if defined(AUDIO_DEBUG)
+ char nbuf[16];
char fmtbuf[64];
if (pchanges) {
+ if (ptrack) {
+ snprintf(nbuf, sizeof(nbuf), "%d", ptrack->id);
+ } else {
+ snprintf(nbuf, sizeof(nbuf), "-");
+ }
audio_format2_tostr(fmtbuf, sizeof(fmtbuf), &pfmt);
- DPRINTF(1, "audio track#%d play mode: %s\n",
- ptrack->id, fmtbuf);
+ DPRINTF(1, "audio track#%s play mode: %s\n",
+ nbuf, fmtbuf);
}
if (rchanges) {
+ if (rtrack) {
+ snprintf(nbuf, sizeof(nbuf), "%d", rtrack->id);
+ } else {
+ snprintf(nbuf, sizeof(nbuf), "-");
+ }
audio_format2_tostr(fmtbuf, sizeof(fmtbuf), &rfmt);
- DPRINTF(1, "audio track#%d rec mode: %s\n",
- rtrack->id, fmtbuf);
+ DPRINTF(1, "audio track#%s rec mode: %s\n",
+ nbuf, fmtbuf);
}
#endif
}
@@ -6868,15 +6889,19 @@ audio_file_setinfo(struct audio_softc *s
if (error)
goto abort1;
- /* Set to track and update sticky parameters */
+ /*
+ * Set to track and update sticky parameters.
+ */
error = 0;
file->mode = mode;
- if (ptrack) {
- if (SPECIFIED_CH(pi->pause)) {
+
+ if (SPECIFIED_CH(pi->pause)) {
+ if (ptrack)
ptrack->is_pause = pi->pause;
- sc->sc_sound_ppause = pi->pause;
- }
- if (pchanges) {
+ sc->sc_sound_ppause = pi->pause;
+ }
+ if (pchanges) {
+ if (ptrack) {
audio_track_lock_enter(ptrack);
error = audio_track_set_format(ptrack, &pfmt);
audio_track_lock_exit(ptrack);
@@ -6884,18 +6909,22 @@ audio_file_setinfo(struct audio_softc *s
TRACET(1, ptrack, "set play.params failed");
goto abort2;
}
- sc->sc_sound_pparams = pfmt;
}
- /* Change water marks after initializing the buffers. */
- if (SPECIFIED(ai->hiwat) || SPECIFIED(ai->lowat))
+ sc->sc_sound_pparams = pfmt;
+ }
+ /* Change water marks after initializing the buffers. */
+ if (SPECIFIED(ai->hiwat) || SPECIFIED(ai->lowat)) {
+ if (ptrack)
audio_track_setinfo_water(ptrack, ai);
}
- if (rtrack) {
- if (SPECIFIED_CH(ri->pause)) {
+
+ if (SPECIFIED_CH(ri->pause)) {
+ if (rtrack)
rtrack->is_pause = ri->pause;
- sc->sc_sound_rpause = ri->pause;
- }
- if (rchanges) {
+ sc->sc_sound_rpause = ri->pause;
+ }
+ if (rchanges) {
+ if (rtrack) {
audio_track_lock_enter(rtrack);
error = audio_track_set_format(rtrack, &rfmt);
audio_track_lock_exit(rtrack);
@@ -6903,8 +6932,8 @@ audio_file_setinfo(struct audio_softc *s
TRACET(1, rtrack, "set record.params failed");
goto abort3;
}
- sc->sc_sound_rparams = rfmt;
}
+ sc->sc_sound_rparams = rfmt;
}
return 0;
@@ -6917,15 +6946,17 @@ abort3:
audio_track_set_format(rtrack, &saved_rfmt);
audio_track_lock_exit(rtrack);
}
+ sc->sc_sound_rpause = saved_ai.record.pause;
+ sc->sc_sound_rparams = saved_rfmt;
abort2:
if (ptrack && error != ENOMEM) {
ptrack->is_pause = saved_ai.play.pause;
audio_track_lock_enter(ptrack);
audio_track_set_format(ptrack, &saved_pfmt);
audio_track_lock_exit(ptrack);
- sc->sc_sound_pparams = saved_pfmt;
- sc->sc_sound_ppause = saved_ai.play.pause;
}
+ sc->sc_sound_ppause = saved_ai.play.pause;
+ sc->sc_sound_pparams = saved_pfmt;
file->mode = saved_ai.mode;
abort1:
audio_hw_setinfo(sc, &saved_ai, NULL);
@@ -6935,14 +6966,16 @@ abort1:
/*
* Write SPECIFIED() parameters within info back to fmt.
+ * Note that track can be NULL here.
* Return value of 1 indicates that fmt is modified.
* Return value of 0 indicates that fmt is not modified.
* Return value of -1 indicates that error EINVAL has occurred.
*/
static int
-audio_track_setinfo_check(audio_format2_t *fmt, const struct audio_prinfo *info,
- const audio_format2_t *hwfmt)
+audio_track_setinfo_check(audio_track_t *track,
+ audio_format2_t *fmt, const struct audio_prinfo *info)
{
+ const audio_format2_t *hwfmt;
int changes;
changes = 0;
@@ -6970,8 +7003,19 @@ audio_track_setinfo_check(audio_format2_
* We can reduce than the number of channels that the hardware
* supports.
*/
- if (info->channels > 2 && info->channels > hwfmt->channels)
- return -1;
+ if (info->channels > 2) {
+ if (track) {
+ hwfmt = &track->mixer->hwbuf.fmt;
+ if (info->channels > hwfmt->channels)
+ return -1;
+ } else {
+ /*
+ * This should never happen.
+ * If track == NULL, channels should be <= 2.
+ */
+ return -1;
+ }
+ }
fmt->channels = info->channels;
changes = 1;
}
@@ -7244,62 +7288,51 @@ audiogetinfo(struct audio_softc *sc, str
pi->channels = ptrack->usrbuf.fmt.channels;
pi->precision = ptrack->usrbuf.fmt.precision;
pi->encoding = ptrack->usrbuf.fmt.encoding;
+ pi->pause = ptrack->is_pause;
} else {
- /* Set default parameters if the track is not available. */
- if (ISDEVAUDIO(file->dev)) {
- pi->sample_rate = audio_default.sample_rate;
- pi->channels = audio_default.channels;
- pi->precision = audio_default.precision;
- pi->encoding = audio_default.encoding;
- } else {
- pi->sample_rate = sc->sc_sound_pparams.sample_rate;
- pi->channels = sc->sc_sound_pparams.channels;
- pi->precision = sc->sc_sound_pparams.precision;
- pi->encoding = sc->sc_sound_pparams.encoding;
- }
+ /* Use sticky parameters if the track is not available. */
+ pi->sample_rate = sc->sc_sound_pparams.sample_rate;
+ pi->channels = sc->sc_sound_pparams.channels;
+ pi->precision = sc->sc_sound_pparams.precision;
+ pi->encoding = sc->sc_sound_pparams.encoding;
+ pi->pause = sc->sc_sound_ppause;
}
if (rtrack) {
ri->sample_rate = rtrack->usrbuf.fmt.sample_rate;
ri->channels = rtrack->usrbuf.fmt.channels;
ri->precision = rtrack->usrbuf.fmt.precision;
ri->encoding = rtrack->usrbuf.fmt.encoding;
+ ri->pause = rtrack->is_pause;
} else {
- /* Set default parameters if the track is not available. */
- if (ISDEVAUDIO(file->dev)) {
- ri->sample_rate = audio_default.sample_rate;
- ri->channels = audio_default.channels;
- ri->precision = audio_default.precision;
- ri->encoding = audio_default.encoding;
- } else {
- ri->sample_rate = sc->sc_sound_rparams.sample_rate;
- ri->channels = sc->sc_sound_rparams.channels;
- ri->precision = sc->sc_sound_rparams.precision;
- ri->encoding = sc->sc_sound_rparams.encoding;
- }
+ /* Use sticky parameters if the track is not available. */
+ ri->sample_rate = sc->sc_sound_rparams.sample_rate;
+ ri->channels = sc->sc_sound_rparams.channels;
+ ri->precision = sc->sc_sound_rparams.precision;
+ ri->encoding = sc->sc_sound_rparams.encoding;
+ ri->pause = sc->sc_sound_rpause;
}
if (ptrack) {
pi->seek = ptrack->usrbuf.used;
pi->samples = ptrack->usrbuf_stamp;
pi->eof = ptrack->eofcounter;
- pi->pause = ptrack->is_pause;
pi->error = (ptrack->dropframes != 0) ? 1 : 0;
- pi->waiting = 0; /* open never hangs */
pi->open = 1;
- pi->active = sc->sc_pbusy;
pi->buffer_size = ptrack->usrbuf.capacity;
}
+ pi->waiting = 0; /* open never hangs */
+ pi->active = sc->sc_pbusy;
+
if (rtrack) {
ri->seek = rtrack->usrbuf.used;
ri->samples = rtrack->usrbuf_stamp;
ri->eof = 0;
- ri->pause = rtrack->is_pause;
ri->error = (rtrack->dropframes != 0) ? 1 : 0;
- ri->waiting = 0; /* open never hangs */
ri->open = 1;
- ri->active = sc->sc_rbusy;
ri->buffer_size = rtrack->usrbuf.capacity;
}
+ ri->waiting = 0; /* open never hangs */
+ ri->active = sc->sc_rbusy;
/*
* XXX There may be different number of channels between playback
@@ -7319,6 +7352,20 @@ audiogetinfo(struct audio_softc *sc, str
}
ai->mode = file->mode;
+ /*
+ * For backward compatibility, we have to pad these five fields
+ * a fake non-zero value even if there are no tracks.
+ */
+ if (ptrack == NULL)
+ pi->buffer_size = 65536;
+ if (rtrack == NULL)
+ ri->buffer_size = 65536;
+ if (ptrack == NULL && rtrack == NULL) {
+ ai->blocksize = 2048;
+ ai->hiwat = ai->play.buffer_size / ai->blocksize;
+ ai->lowat = ai->hiwat * 3 / 4;
+ }
+
if (need_mixerinfo) {
KASSERT(sc->sc_exlock);