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