Subject: Re: kern/15845: audio drivers without auconv attribute won't link
To: None <tech-kern@netbsd.org>
From: TAMURA Kent <kent@netbsd.org>
List: tech-kern
Date: 03/10/2002 00:09:41
In message "kern/15845: audio drivers without auconv attribute won't link"
    on 02/03/09, Ben Harris <bjh21@netbsd.org> writes:
> device  vidcaudio: audio
> attach  vidcaudio at vidc
> 
> Since it doesn't have the "auconv" attribute, dev/auconv.c doesn't get
> included in the kernel, and hence the auconv_* functions aren't defined.
> 
> Presumably audio devices without auconv are meant to work, or there
> wouldn't be any point in making it a separate attribute.

How about the following patch?  It adds AUCONV_SAMPLINGRATE
kernel option.

Index: conf/files
===================================================================
RCS file: /cvsroot/syssrc/sys/conf/files,v
retrieving revision 1.499
diff -u -r1.499 files
--- conf/files	2002/03/04 13:24:11	1.499
+++ conf/files	2002/03/09 15:00:43
@@ -185,6 +185,10 @@
 
 defparam opt_mdsize.h		MINIROOTSIZE
 
+# audio option
+#
+defflag	opt_audio.h		AUCONV_SAMPLINGRATE
+
 # device classes
 #
 devclass disk
Index: dev/auconv.c
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/auconv.c,v
retrieving revision 1.8
diff -u -r1.8 auconv.c
--- dev/auconv.c	2002/03/07 14:37:02	1.8
+++ dev/auconv.c	2002/03/09 15:00:43
@@ -51,6 +51,7 @@
 #define DPRINTF(x)
 #endif
 
+#ifdef AUCONV_SAMPLINGRATE
 static int auconv_play_slinear16_le(struct auconv_context *,
 	const struct audio_params *, uint8_t *, const uint8_t *, int);
 static int auconv_play_slinear16_channels_le(struct auconv_context *,
@@ -68,6 +69,7 @@
 	const struct audio_params *, uint8_t *, const uint8_t *, int);
 static int auconv_record_slinear24_channels_le(struct auconv_context *,
 	const struct audio_params *, uint8_t *, const uint8_t *, int);
+#endif /* AUCONV_SAMPLINGRATE */
 
 
 void
@@ -248,6 +250,7 @@
 	}
 }
 
+#ifdef AUCONV_SAMPLINGRATE
 int
 auconv_check_params(const struct audio_params *params)
 {
@@ -859,3 +862,4 @@
 AUCONV_RECORD_SLINEAR_LE(24)
 AUCONV_RECORD_SLINEAR_CHANNELS_LE(16)
 AUCONV_RECORD_SLINEAR_CHANNELS_LE(24)
+#endif /* AUCONV_SAMPLINGRATE */
Index: dev/auconv.h
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/auconv.h,v
retrieving revision 1.8
diff -u -r1.8 auconv.h
--- dev/auconv.h	2002/03/07 14:37:02	1.8
+++ dev/auconv.h	2002/03/09 15:00:43
@@ -39,6 +39,8 @@
 #ifndef _DEV_AUCONV_H_
 #define _DEV_AUCONV_H_
 
+#include "opt_audio.h"
+
 /* Convert between signed and unsigned. */
 extern void change_sign8(void *, u_char *, int);
 extern void change_sign16_le(void *, u_char *, int);
@@ -62,18 +64,20 @@
 
 /* Sampling rate conversion */
 #define AUDIO_MAX_CHANNELS	6
+#ifdef AUCONV_SAMPLINGRATE
 struct auconv_context {
 	long	count;
 	int32_t	prev[AUDIO_MAX_CHANNELS];
 	uint8_t	*ring_start;
 	uint8_t	*ring_end;
 };
-extern int auconv_check_params(const struct audio_params *);
 extern void auconv_init_context(struct auconv_context *, long, long, uint8_t *,
 				uint8_t *);
 extern int auconv_play(struct auconv_context *, const struct audio_params *,
 		       uint8_t *, const uint8_t *, int);
 extern int auconv_record(struct auconv_context *, const struct audio_params *,
 			 uint8_t *, const uint8_t *, int);
+#endif /* AUCONV_SAMPLINGRATE */
+extern int auconv_check_params(const struct audio_params *);
 
 #endif /* !_DEV_AUCONV_H_ */
Index: dev/audio.c
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/audio.c,v
retrieving revision 1.147
diff -u -r1.147 audio.c
--- dev/audio.c	2002/03/08 02:30:54	1.147
+++ dev/audio.c	2002/03/09 15:00:44
@@ -776,9 +776,11 @@
 
 	DPRINTF(("audio_initbufs: mode=0x%x\n", sc->sc_mode));
 	audio_init_ringbuffer(&sc->sc_rr);
+#ifdef AUCONV_SAMPLINGRATE
 	auconv_init_context(&sc->sc_rconv, sc->sc_rparams.hw_sample_rate,
 			    sc->sc_rparams.sample_rate,
 			    sc->sc_rr.start, sc->sc_rr.end);
+#endif
 	sc->sc_rconvbuffer_begin = 0;
 	sc->sc_rconvbuffer_end = 0;
 	if (hw->init_input && (sc->sc_mode & AUMODE_RECORD)) {
@@ -789,9 +791,11 @@
 	}
 
 	audio_init_ringbuffer(&sc->sc_pr);
+#ifdef AUCONV_SAMPLINGRATE
 	auconv_init_context(&sc->sc_pconv, sc->sc_pparams.sample_rate,
 			    sc->sc_pparams.hw_sample_rate,
 			    sc->sc_pr.start, sc->sc_pr.end);
+#endif
 	sc->sc_sil_count = 0;
 	if (hw->init_output && (sc->sc_mode & AUMODE_PLAY)) {
 		error = hw->init_output(sc->hw_hdl, sc->sc_pr.start,
@@ -1235,9 +1239,21 @@
 			 * The format of data in the ring buffer is
 			 * [hw_sample_rate, hw_encoding, hw_precision, hw_channels]
 			 */
+#ifdef AUCONV_SAMPLINGRATE
 			sc->sc_rconvbuffer_end =
 				auconv_record(&sc->sc_rconv, params,
 					      sc->sc_rconvbuffer, outp, cc);
+#else
+			n = cb->end - outp;
+			if (cc <= n) {
+				memcpy(sc->sc_rconvbuffer, outp, cc);
+			} else {
+				memcpy(sc->sc_rconvbuffer, outp, n);
+				memcpy(sc->sc_rconvbuffer + n, cb->start,
+				       cc - n);
+			}
+			sc->sc_rconvbuffer_end = cc;
+#endif /* !AUCONV_SAMPLINGRATE */
 			/*
 			 * The format of data in sc_rconvbuffer is
 			 * [sample_rate, hw_encoding, hw_precision, channels]
@@ -1627,8 +1643,18 @@
 		 * The format of data in sc_pconvbuffer is:
 		 * [sample_rate, hw_encoding, hw_precision, channels]
 		 */
+#ifdef AUCONV_SAMPLINGRATE
 		cc = auconv_play(&sc->sc_pconv, params, inp,
 				 sc->sc_pconvbuffer, cc);
+#else
+		n = cb->end - inp;
+		if (cc <= n) {
+			memcpy(inp, sc->sc_pconvbuffer, cc);
+		} else {
+			memcpy(inp, sc->sc_pconvbuffer, n);
+			memcpy(cb->start, sc->sc_pconvbuffer + n, cc - n);
+		}
+#endif /* !AUCONV_SAMPLINGRATE */
 		/*
 		 * The format of data in inp is:
 		 * [hw_sample_rate, hw_encoding, hw_precision, hw_channels]
@@ -2563,6 +2589,18 @@
 	}
 	return aumask;
 }
+
+#ifndef AUCONV_SAMPLINGRATE
+/* dummy function for the case that auconv.o is not linked */
+int
+auconv_check_params(const struct audio_params *params)
+{
+	if (params->hw_channels == params->channels
+	    && params->hw_sample_rate == params->sample_rate)
+		return 0;	/* No conversion */
+	return (EINVAL);
+}
+#endif /* !AUCONV_SAMPLING_RATE */
 
 int
 audiosetinfo(struct audio_softc *sc, struct audio_info *ai)
Index: dev/audiovar.h
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/audiovar.h,v
retrieving revision 1.21
diff -u -r1.21 audiovar.h
--- dev/audiovar.h	2002/03/07 14:37:02	1.21
+++ dev/audiovar.h	2002/03/09 15:00:44
@@ -119,13 +119,17 @@
 	u_char	sc_input_fragment[MAX_SAMPLE_SIZE];
 	int	sc_pconvbuffer_size;
 	u_char	*sc_pconvbuffer;
+#ifdef AUCONV_SAMPLINGRATE
 	struct auconv_context sc_pconv;
+#endif
 
 	int	sc_rconvbuffer_size;
 	int	sc_rconvbuffer_begin;
 	int	sc_rconvbuffer_end;
 	u_char	*sc_rconvbuffer;
+#ifdef AUCONV_SAMPLINGRATE
 	struct auconv_context sc_rconv;
+#endif
 
 	u_char	sc_blkset;	/* Blocksize has been set */
 
Index: arch/i386/conf/GENERIC
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/i386/conf/GENERIC,v
retrieving revision 1.474
diff -u -r1.474 GENERIC
--- arch/i386/conf/GENERIC	2002/03/04 13:24:10	1.474
+++ arch/i386/conf/GENERIC	2002/03/09 15:00:44
@@ -840,6 +840,8 @@
 
 # Audio Devices
 
+options AUCONV_SAMPLINGRATE	# Sampling rate conversion for some devices
+
 # PCI audio devices
 auich*	at pci? dev ? function ?	# Intel ICH integrated AC'97 Audio
 autri*	at pci? dev ? function ?	# Trident 4DWAVE based AC'97 Audio
Index: arch/i386/conf/GENERIC_LAPTOP
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/i386/conf/GENERIC_LAPTOP,v
retrieving revision 1.43
diff -u -r1.43 GENERIC_LAPTOP
--- arch/i386/conf/GENERIC_LAPTOP	2002/03/04 13:24:10	1.43
+++ arch/i386/conf/GENERIC_LAPTOP	2002/03/09 15:00:45
@@ -594,6 +594,8 @@
 
 # Audio Devices
 
+options AUCONV_SAMPLINGRATE	# Sampling rate conversion for some devices
+
 # PCI audio devices
 auich*	at pci? dev ? function ?	# Intel ICH integrated AC'97 Audio
 autri*	at pci? dev ? function ?	# Trident 4DWAVE based AC'97 Audio