Module Name: src Committed By: isaki Date: Wed Mar 4 14:19:41 UTC 2020
Modified Files: src/sys/dev/audio: audio.c Log Message: 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.61 -r1.62 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.61 src/sys/dev/audio/audio.c:1.62 --- src/sys/dev/audio/audio.c:1.61 Sun Mar 1 07:42:07 2020 +++ src/sys/dev/audio/audio.c Wed Mar 4 14:19:41 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: audio.c,v 1.61 2020/03/01 07:42:07 isaki Exp $ */ +/* $NetBSD: audio.c,v 1.62 2020/03/04 14:19:41 isaki Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -142,7 +142,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.61 2020/03/01 07:42:07 isaki Exp $"); +__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.62 2020/03/04 14:19:41 isaki 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 *, @@ -6745,20 +6745,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)) { /* @@ -6777,39 +6787,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) - TRACET(1, ptrack, "check play.params failed: " - "%s %ubit %uch %uHz", - audio_encoding_name(pi->encoding), - pi->precision, - pi->channels, - pi->sample_rate); + 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) - TRACET(1, rtrack, "check record.params failed: " - "%s %ubit %uch %uHz", - audio_encoding_name(ri->encoding), - ri->precision, - ri->channels, - ri->sample_rate); + 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; } /* @@ -6819,16 +6825,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 } @@ -6838,15 +6855,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); @@ -6854,18 +6875,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); @@ -6873,8 +6898,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; @@ -6887,15 +6912,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); @@ -6905,14 +6932,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; @@ -6940,8 +6969,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; } @@ -7213,62 +7253,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 @@ -7288,6 +7317,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);