Module Name:    src
Committed By:   snj
Date:           Fri Jun 30 06:43:07 UTC 2017

Modified Files:
        src/sys/dev [netbsd-8]: audio.c audiovar.h

Log Message:
Pull up following revision(s) (requested by nat in ticket #71):
        sys/dev/audio.c: 1.359-1.366
        sys/dev/audiovar.h: 1.56
No need to reset the audioinfo whem dealing with the hardware ring.  This
avoids a panic with some audio devices.
Ok christos@.
--
sc_iffreq -> sc_frequency.  NFCI.
Ok christos@.
--
Allow for bigger data types to mix into to avoid overflow.
--
Check hardare precision in vchan_autoconfig.  Passes atf test again.
--
Use pustream params when clearing the next block in the mixring.
--
Check validbits against precision in vchan_autoconfig.  At present
validbits != precision is not supported.
This change will most likely break autoconfig on vs(4), for these machines
the parameters can be set to the paramaters reported at attach time via
sysctl.
--
Don't start playback or recording on the hw ring only stream ring buffers.
--
Don't autoconfig for 24 bits precision.  It does not work as yet.


To generate a diff of this commit:
cvs rdiff -u -r1.357.2.1 -r1.357.2.2 src/sys/dev/audio.c
cvs rdiff -u -r1.55 -r1.55.2.1 src/sys/dev/audiovar.h

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.c
diff -u src/sys/dev/audio.c:1.357.2.1 src/sys/dev/audio.c:1.357.2.2
--- src/sys/dev/audio.c:1.357.2.1	Fri Jun  9 17:00:46 2017
+++ src/sys/dev/audio.c	Fri Jun 30 06:43:07 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: audio.c,v 1.357.2.1 2017/06/09 17:00:46 snj Exp $	*/
+/*	$NetBSD: audio.c,v 1.357.2.2 2017/06/30 06:43:07 snj Exp $	*/
 
 /*-
  * Copyright (c) 2016 Nathanial Sloss <nathanialsl...@yahoo.com.au>
@@ -148,7 +148,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.357.2.1 2017/06/09 17:00:46 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.357.2.2 2017/06/30 06:43:07 snj Exp $");
 
 #ifdef _KERNEL_OPT
 #include "audio.h"
@@ -447,7 +447,7 @@ const struct audio_params audio_default 
 	.channels = 1,
 };
 
-int auto_config_precision[] = { 32, 24, 16, 8 };
+int auto_config_precision[] = { 32, 16, 8 };
 int auto_config_channels[] = { 32, 24, 16, 8, 6, 4, 2, 1};
 int auto_config_freq[] = { 48000, 44100, 96000, 192000, 32000,
 			   22050, 16000, 11025, 8000, 4000 };
@@ -535,7 +535,7 @@ audioattach(device_t parent, device_t se
 	vc->sc_lastinfovalid = false;
 	vc->sc_swvol = 255;
 	vc->sc_recswvol = 255;
-	sc->sc_iffreq = 44100;
+	sc->sc_frequency = 44100;
 	sc->sc_precision = 16;
 	sc->sc_channels = 2;
 
@@ -3485,6 +3485,7 @@ int
 audiostartr(struct audio_softc *sc, struct virtual_channel *vc)
 {
 
+	struct audio_chan *chan;
 	int error;
 
 	KASSERT(mutex_owned(sc->sc_lock));
@@ -3493,8 +3494,11 @@ audiostartr(struct audio_softc *sc, stru
 		 vc->sc_mrr.s.start, audio_stream_get_used(&vc->sc_mrr.s),
 		 vc->sc_mrr.usedhigh, vc->sc_mrr.mmapped));
 
+	chan = SIMPLEQ_FIRST(&sc->sc_audiochan);
 	if (!audio_can_capture(sc))
 		return EINVAL;
+	if (vc == chan->vc)
+		return 0;
 
 	error = 0;
 	if (sc->sc_rec_started == false) {
@@ -3525,6 +3529,8 @@ audiostartp(struct audio_softc *sc, stru
 
 	if (!audio_can_playback(sc))
 		return EINVAL;
+	if (vc == chan->vc)
+		return 0;
 
 	if (!vc->sc_mpr.mmapped && used < vc->sc_mpr.blksize) {
 		cv_broadcast(&sc->sc_wchan);
@@ -3874,7 +3880,7 @@ audio_mix(void *v)
 	cc = blksize - (inp - cb->s.start) % blksize;
 	if (sc->sc_writeme == false) {
 		DPRINTFN(3, ("MIX RING EMPTY - INSERT SILENCE\n"));
-		audio_fill_silence(&vc->sc_mpr.s.param, inp, cc);
+		audio_fill_silence(&vc->sc_pustream->param, inp, cc);
 		sc->sc_pr.drops += cc;
 	} else
 		cc = blksize;
@@ -3882,11 +3888,11 @@ audio_mix(void *v)
 	cc = blksize;
 	cc1 = sc->sc_pr.s.end - sc->sc_pr.s.inp;
 	if (cc1 < cc) {
-		audio_fill_silence(&vc->sc_mpr.s.param, sc->sc_pr.s.inp, cc1);
+		audio_fill_silence(&vc->sc_pustream->param, sc->sc_pr.s.inp, cc1);
 		cc -= cc1;
-		audio_fill_silence(&vc->sc_mpr.s.param, sc->sc_pr.s.start, cc);
+		audio_fill_silence(&vc->sc_pustream->param, sc->sc_pr.s.start, cc);
 	} else
-		audio_fill_silence(&vc->sc_mpr.s.param, sc->sc_pr.s.inp, cc);
+		audio_fill_silence(&vc->sc_pustream->param, sc->sc_pr.s.inp, cc);
 	mutex_exit(sc->sc_intr_lock);
 
 	kpreempt_disable();
@@ -4149,7 +4155,7 @@ audio_set_vchan_defaults(struct audio_so
 		return EINVAL;
 	vc = chan->vc;
 
-	sc->sc_vchan_params.sample_rate = sc->sc_iffreq;
+	sc->sc_vchan_params.sample_rate = sc->sc_frequency;
 #if BYTE_ORDER == LITTLE_ENDIAN
 	sc->sc_vchan_params.encoding = AUDIO_ENCODING_SLINEAR_LE;
 #else
@@ -4165,12 +4171,12 @@ audio_set_vchan_defaults(struct audio_so
 	vc->sc_blkset = false;
 
 	AUDIO_INITINFO(&ai);
-	ai.record.sample_rate = sc->sc_iffreq;
+	ai.record.sample_rate = sc->sc_frequency;
 	ai.record.encoding    = format->encoding;
 	ai.record.channels    = sc->sc_channels;
 	ai.record.precision   = sc->sc_precision;
 	ai.record.pause	      = false;
-	ai.play.sample_rate   = sc->sc_iffreq;
+	ai.play.sample_rate   = sc->sc_frequency;
 	ai.play.encoding      = format->encoding;
 	ai.play.channels      = sc->sc_channels;
 	ai.play.precision     = sc->sc_precision;
@@ -4180,14 +4186,14 @@ audio_set_vchan_defaults(struct audio_so
 	sc->sc_format->channels = sc->sc_channels;
 	sc->sc_format->precision = sc->sc_precision;
 	sc->sc_format->validbits = sc->sc_precision;
-	sc->sc_format->frequency[0] = sc->sc_iffreq;
+	sc->sc_format->frequency[0] = sc->sc_frequency;
 
 	auconv_delete_encodings(sc->sc_encodings);
 	error = auconv_create_encodings(sc->sc_format, VAUDIO_NFORMATS,
 	    &sc->sc_encodings);
 
 	if (error == 0)
-		error = audiosetinfo(sc, &ai, true, vc);
+		error = audiosetinfo(sc, &ai, false, vc);
 
 	return error;
 }
@@ -5608,8 +5614,8 @@ done:
 	return error;
 }
 
-#define DEF_MIX_FUNC(name, type, MINVAL, MAXVAL)		\
-	static void						\
+#define DEF_MIX_FUNC(name, type, bigger_type, MINVAL, MAXVAL)		\
+	static void							\
 	mix_func##name(struct audio_softc *sc, struct audio_ringbuffer *cb, \
 		  struct virtual_channel *vc)				\
 	{								\
@@ -5633,9 +5639,9 @@ done:
 			if (cc > cc2)					\
 				cc = cc2;				\
 									\
-			for (m = 0; m < (cc / (name / 8)); m++) {	\
-				tomix[m] = tomix[m] *			\
-				    (int32_t)(vc->sc_swvol) / 255;	\
+			for (m = 0; m < (cc / (name / NBBY)); m++) {	\
+				tomix[m] = (bigger_type)tomix[m] *	\
+				    (bigger_type)(vc->sc_swvol) / 255;	\
 				result = orig[m] + tomix[m];		\
 				product = orig[m] * tomix[m];		\
 				if (orig[m] > 0 && tomix[m] > 0)	\
@@ -5654,9 +5660,9 @@ done:
 		}							\
 	}								\
 
-DEF_MIX_FUNC(8, int8_t, INT8_MIN, INT8_MAX);
-DEF_MIX_FUNC(16, int16_t, INT16_MIN, INT16_MAX);
-DEF_MIX_FUNC(32, int32_t, INT32_MIN, INT32_MAX);
+DEF_MIX_FUNC(8, int8_t, int32_t, INT8_MIN, INT8_MAX);
+DEF_MIX_FUNC(16, int16_t, int32_t, INT16_MIN, INT16_MAX);
+DEF_MIX_FUNC(32, int32_t, int64_t, INT32_MIN, INT32_MAX);
 
 void
 mix_func(struct audio_softc *sc, struct audio_ringbuffer *cb,
@@ -5941,7 +5947,7 @@ audio_sysctl_frequency(SYSCTLFN_ARGS)
 	node = *rnode;
 	sc = node.sysctl_data;
 
-	t = sc->sc_iffreq;
+	t = sc->sc_frequency;
 	node.sysctl_data = &t;
 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
 	if (error || newp == NULL)
@@ -5960,7 +5966,7 @@ audio_sysctl_frequency(SYSCTLFN_ARGS)
 		return EINVAL;
 	}
 
-	sc->sc_iffreq = t;
+	sc->sc_frequency = t;
 	error = audio_set_vchan_defaults(sc, AUMODE_PLAY | AUMODE_PLAY_ALL
 	    | AUMODE_RECORD, &sc->sc_format[0]);
 	if (error)
@@ -6082,13 +6088,17 @@ vchan_autoconfig(struct audio_softc *sc)
 		for (j = 0; j < __arraycount(auto_config_channels); j++) {
 			sc->sc_channels = auto_config_channels[j];
 			for (k = 0; k < __arraycount(auto_config_freq); k++) {
-				sc->sc_iffreq = auto_config_freq[k];
+				sc->sc_frequency = auto_config_freq[k];
 				error = audio_set_vchan_defaults(sc,
 				    AUMODE_PLAY | AUMODE_PLAY_ALL |
 				    AUMODE_RECORD, &sc->sc_format[0]);
 				if (vc->sc_npfilters > 0 &&
-				    (vc->sc_mpr.s.param.
-					sample_rate != sc->sc_iffreq ||
+				    (vc->sc_mpr.s.param.precision !=
+							sc->sc_precision ||
+				    vc->sc_mpr.s.param.validbits !=
+							sc->sc_precision ||
+				    vc->sc_mpr.s.param.
+					sample_rate != sc->sc_frequency ||
 				    vc->sc_mpr.s.param.
 					 channels != sc->sc_channels))
 					error = EINVAL;
@@ -6099,7 +6109,7 @@ vchan_autoconfig(struct audio_softc *sc)
 					    "Format SLINEAR, precision %d, "
 					    "channels %d, frequency %d\n",
 					    sc->sc_precision, sc->sc_channels,
-					    sc->sc_iffreq);
+					    sc->sc_frequency);
 					mutex_exit(sc->sc_lock);
 
 					return 0;

Index: src/sys/dev/audiovar.h
diff -u src/sys/dev/audiovar.h:1.55 src/sys/dev/audiovar.h:1.55.2.1
--- src/sys/dev/audiovar.h:1.55	Sun May  7 08:19:39 2017
+++ src/sys/dev/audiovar.h	Fri Jun 30 06:43:07 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: audiovar.h,v 1.55 2017/05/07 08:19:39 nat Exp $	*/
+/*	$NetBSD: audiovar.h,v 1.55.2.1 2017/06/30 06:43:07 snj Exp $	*/
 
 /*-
  * Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -291,7 +291,7 @@ struct audio_softc {
 	struct sysctllog	*sc_log;	/* sysctl log */
 	int		sc_channels;
 	int		sc_precision;
-	int		sc_iffreq;
+	int		sc_frequency;
 	struct audio_info 	sc_ai;		/* Recent info for  dev sound */
 	bool			sc_aivalid;
 #define VAUDIO_NFORMATS	1

Reply via email to