Subject: Re: Propose: improve audio driver
To: None <kent@netbsd.org>
From: Tetsuya Isaki <isaki@par.odn.ne.jp>
List: tech-kern
Date: 03/03/2002 20:46:21
----Next_Part(Sun_Mar__3_20:42:42_2002_542)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
On Sat, 02 Mar 2002 13:02:55 +0900,
In Re: Propose: improve audio driver,
Tetsuya Isaki <isaki@par.odn.ne.jp> wrote:
> > The following patch contains such audio data conversion with
> > padding.
> >
> > http://www.hauN.org/kent/audio-20020227.diff
>
> I'll check it. thanks.
I remade a patch for your patch. Please review it.
---
Tetsuya Isaki <isaki@par.odn.ne.jp / isaki@NetBSD.org>
----Next_Part(Sun_Mar__3_20:42:42_2002_542)--
Content-Type: Text/Plain; charset=iso-2022-jp
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="vs-reduce-for-kent-20020303.diff"
Index: audio.c
===================================================================
RCS file: /home/isaki/cvsroot/vs/src/sys/dev/audio.c,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 audio.c
--- audio.c 2002/03/02 05:03:37 1.1.2.1
+++ audio.c 2002/03/03 08:36:33
@@ -187,7 +187,7 @@
/* The default audio mode: 8 kHz mono ulaw */
struct audio_params audio_default =
- { 8000, AUDIO_ENCODING_ULAW, 8, 1, 0, 1 };
+ { 8000, AUDIO_ENCODING_ULAW, 8, 1, 0, 1, 1 };
struct cfattach audio_ca = {
sizeof(struct audio_softc), audioprobe, audioattach,
@@ -1131,7 +1131,7 @@
u_char *outp;
int error, s, used, cc, n;
const struct audio_params *params;
- int hw_bytes_per_sample, required;
+ int hw_bits_per_sample, required;
if (cb->mmapped)
return EINVAL;
@@ -1140,6 +1140,7 @@
(unsigned long)uio->uio_resid, sc->sc_mode));
params = &sc->sc_rparams;
+#if 0
switch (params->hw_encoding) {
case AUDIO_ENCODING_SLINEAR_LE:
case AUDIO_ENCODING_SLINEAR_BE:
@@ -1151,8 +1152,12 @@
default:
hw_bytes_per_sample = 1 * params->factor;
}
+#else
+ hw_bits_per_sample = params->hw_channels * params->precision
+ * params->factor;
+#endif
required = ((params->hw_sample_rate / params->sample_rate) + 1)
- * hw_bytes_per_sample;
+ * hw_bits_per_sample / 8;
error = 0;
/*
* If hardware is half-duplex and currently playing, return
@@ -1232,11 +1237,11 @@
if (cc > sc->sc_rconvbuffer_size)
cc = sc->sc_rconvbuffer_size;
/* cc must be aligned by the sample size */
- cc = (cc / hw_bytes_per_sample) * hw_bytes_per_sample;
+ cc = (cc * 8 / hw_bits_per_sample) * hw_bits_per_sample / 8;
#ifdef DIAGNOSTIC
if (cc == 0)
printf("audio_read: cc=0 hw_sample_size=%d\n",
- hw_bytes_per_sample);
+ hw_bits_per_sample / 8);
#endif
/*
@@ -1267,11 +1272,11 @@
": cc=%d factor=%d\n", cc,
params->factor);
#endif
- cc /= params->factor;
+ cc = cc * params->factor_denom / params->factor;
#ifdef DIAGNOSTIC
if (cc == 0)
- printf("audio_read: cc=0 factor=%d\n",
- params->factor);
+ printf("audio_read: cc=0 factor=%d/%d\n",
+ params->factor, params->factor_denom);
#endif
sc->sc_rconvbuffer_end = cc;
params->sw_code(sc->hw_hdl, sc->sc_rconvbuffer,
@@ -1441,7 +1446,7 @@
u_char *inp, *einp;
int saveerror, error, s, n, cc, used;
struct audio_params *params;
- int samples, hw_bytes_per_sample, user_bytes_per_sample;
+ int samples, hw_bits_per_sample, user_bits_per_sample;
int input_remain, space;
DPRINTFN(2,("audio_write: sc=%p count=%lu used=%d(hi=%d)\n",
@@ -1484,6 +1489,7 @@
sc->sc_pparams.precision, sc->sc_pparams.channels,
sc->sc_pparams.sw_code, sc->sc_pparams.factor));
+#if 0
/*
* For some encodings, $B%5%s%W%k$NBg$-$5$K(B align $B$7$F=hM}$9$k(B
*/
@@ -1492,27 +1498,32 @@
case AUDIO_ENCODING_SLINEAR_BE:
case AUDIO_ENCODING_ULINEAR_LE:
case AUDIO_ENCODING_ULINEAR_BE:
- hw_bytes_per_sample = params->hw_channels * params->precision/8
+ hw_bits_per_sample = params->hw_channels * params->precision
* params->factor;
- user_bytes_per_sample = params->channels * params->precision/8;
+ user_bits_per_sample = params->channels * params->precision;
break;
default:
- hw_bytes_per_sample = 1 * params->factor;
- user_bytes_per_sample = 1;
+ hw_bits_per_sample = 8 * params->factor;
+ user_bits_per_sample = 8;
}
+#else
+ hw_bits_per_sample = params->hw_channels * params->precision
+ * params->factor / params->factor_denom;
+ user_bits_per_sample = params->channels * params->precision;
+#endif
#ifdef DIAGNOSTIC
- if (hw_bytes_per_sample > MAX_SAMPLE_SIZE) {
+ if (hw_bits_per_sample > MAX_SAMPLE_SIZE * 8) {
printf("%s(): Invalid sample size: cur=%d max=%d\n",
- __func__, hw_bytes_per_sample, MAX_SAMPLE_SIZE);
+ __func__, hw_bits_per_sample, MAX_SAMPLE_SIZE);
}
#endif
space = ((params->hw_sample_rate / params->sample_rate) + 1)
- * hw_bytes_per_sample;
+ * hw_bits_per_sample / 8;
error = 0;
while ((input_remain = uio->uio_resid + sc->sc_input_fragment_length) > 0
&& !error) {
s = splaudio();
- if (input_remain < user_bytes_per_sample) {
+ if (input_remain < user_bits_per_sample / 8) {
n = uio->uio_resid;
DPRINTF(("audio_write: fragment uiomove length=%d\n", n));
error = uiomove(sc->sc_input_fragment
@@ -1549,25 +1560,25 @@
cc = cb->end - cb->start;
/* cc: $B%j%s%0%P%C%U%!$KF~$k%P%$%H?t(B */
- samples = cc / hw_bytes_per_sample;
+ samples = cc * 8 / hw_bits_per_sample;
if (samples == 0)
printf("a_w: samples(1) == 0\n");
/* samples: $B%j%s%0%P%C%U%!$KF~$k%5%s%W%k?t(B */
samples = samples * params->sample_rate / params->hw_sample_rate;
if (samples == 0)
printf("a_w: samples(2) == 0 usedhigh-used=%d cc/hw_bps=%d/%d rate/hw_rate=%ld/%ld space=%d\n",
- cb->usedhigh - cb->used, cc, hw_bytes_per_sample, params->sample_rate, params->hw_sample_rate, space);
+ cb->usedhigh - cb->used, cc, hw_bits_per_sample / 8, params->sample_rate, params->hw_sample_rate, space);
/* samples: $B%j%s%0%P%C%U%!$KF~$k!"%=!<%9$G$N%5%s%W%k?t(B */
- cc = samples * user_bytes_per_sample;
+ cc = samples * user_bits_per_sample / 8;
/* cc: $B%j%s%0%P%C%U%!$KF~$k:GBg$N%=!<%9%P%$%H?t(B */
if (input_remain < cc) /* and no more than we have */
- cc = (input_remain / user_bytes_per_sample)
- * user_bytes_per_sample;
+ cc = (input_remain * 8 / user_bits_per_sample)
+ * user_bits_per_sample / 8;
if (cc == 0)
printf("a_w: cc(1) == 0\n");
if (cc * params->factor > sc->sc_pconvbuffer_size) {
- cc = (sc->sc_pconvbuffer_size / params->factor
- / user_bytes_per_sample) * user_bytes_per_sample;
+ cc = (sc->sc_pconvbuffer_size * 8 / params->factor
+ / user_bits_per_sample) * user_bits_per_sample / 8;
}
#ifdef DIAGNOSTIC
@@ -1579,8 +1590,8 @@
printf("audio_write: cc == 0, swcode=%p, factor=%d "
"remain=%d u_bps=%d hw_bps=%d\n",
sc->sc_pparams.sw_code, sc->sc_pparams.factor,
- input_remain, user_bytes_per_sample,
- hw_bytes_per_sample);
+ input_remain, user_bits_per_sample,
+ hw_bits_per_sample);
cb->copying = 0;
return EINVAL;
}
@@ -1619,7 +1630,7 @@
sc->sc_pparams.sw_code(sc->hw_hdl,
sc->sc_pconvbuffer, cc);
/* Adjust count after the expansion. */
- cc *= sc->sc_pparams.factor;
+ cc = cc * sc->sc_pparams.factor / sc->sc_pparams.factor_denom;
DPRINTFN(1, ("audio_write: expanded cc=%d\n", cc));
}
/*
Index: audio_if.h
===================================================================
RCS file: /home/isaki/cvsroot/vs/src/sys/dev/audio_if.h,v
retrieving revision 1.1.2.1
retrieving revision 1.7
diff -u -r1.1.2.1 -r1.7
--- audio_if.h 2002/03/02 05:03:38 1.1.2.1
+++ audio_if.h 2002/03/03 05:32:23 1.7
@@ -51,6 +51,7 @@
/* Software en/decode functions, set if SW coding required by HW */
void (*sw_code)(void *, u_char *, int);
int factor; /* coding space change */
+ int factor_denom; /* coding space change smaller */
/*
* The following four members represent what format is used in a
* hardware. If hw_sample_rate != sample_rate || hw_channels !=
Index: msm6258.c
===================================================================
RCS file: /home/isaki/cvsroot/vs/src/sys/dev/ic/msm6258.c,v
retrieving revision 1.1.1.2
retrieving revision 1.4
diff -u -r1.1.1.2 -r1.4
--- msm6258.c 2001/11/17 12:00:28 1.1.1.2
+++ msm6258.c 2002/03/02 14:11:54 1.4
@@ -44,8 +44,8 @@
#include <sys/audioio.h>
#include <dev/audio_if.h>
-#include <dev/audiovar.h>
#include <dev/auconv.h>
+#include <dev/audiovar.h>
#include <dev/mulaw.h>
#include <dev/ic/msm6258var.h>
@@ -135,11 +135,12 @@
char *x = &(mc->mc_estim);
short *y = &(mc->mc_amp);
register int i;
+ u_char *d = p;
u_char f;
- for (i = 0; i < cc; i++) {
- f = pcm2adpcm_step(p[i], y, x);
- p[i] = f + (pcm2adpcm_step(p[i], y, x) << 4);
+ for (i = 0; i < cc; ) {
+ f = pcm2adpcm_step(p[i++], y, x);
+ *d++ = f + (pcm2adpcm_step(p[i++], y, x) << 4);
}
}
Index: msm6258var.h
===================================================================
RCS file: /home/isaki/cvsroot/vs/src/sys/dev/ic/msm6258var.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- msm6258var.h 2001/11/04 13:28:49 1.1.1.1
+++ msm6258var.h 2002/03/02 14:11:54 1.2
@@ -34,8 +34,6 @@
* OKI MSM6258 ADPCM voice synthesizer codec.
*/
-#include <dev/auconv.h>
-
void *msm6258_codec_init (void);
void msm6258_ulinear8_to_adpcm (void *, u_char *, int);
void msm6258_mulaw_to_adpcm (void *, u_char *, int);
Index: vs.c
===================================================================
RCS file: /home/isaki/cvsroot/vs/src/sys/arch/x68k/dev/vs.c,v
retrieving revision 1.1.1.3
diff -u -r1.1.1.3 vs.c
--- vs.c 2001/12/24 09:31:20 1.1.1.3
+++ vs.c 2002/03/03 08:33:17
@@ -388,14 +388,18 @@
rate = p->sample_rate;
p->sw_code = NULL;
- p->factor = 1;
+ p->factor = p->factor_denom = 1;
+ p->hw_precision = 4;
+ p->hw_encoding = AUDIO_ENCODING_ADPCM;
+ DPRINTF(1, ("vs_set_params: encoding=%d, precision=%d\n",
+ p->encoding, p->precision));
switch (p->encoding) {
case AUDIO_ENCODING_ULAW:
if (p->precision != 8)
return EINVAL;
if (mode == AUMODE_PLAY) {
p->sw_code = msm6258_mulaw_to_adpcm;
- rate = p->sample_rate * 2;
+ p->factor_denom = 2;
} else {
p->sw_code = msm6258_adpcm_to_mulaw;
p->factor = 2;
@@ -407,7 +411,7 @@
return EINVAL;
if (mode == AUMODE_PLAY) {
p->sw_code = msm6258_ulinear8_to_adpcm;
- rate = p->sample_rate * 2;
+ p->factor_denom = 2;
} else {
p->sw_code = msm6258_adpcm_to_ulinear8;
p->factor = 2;
----Next_Part(Sun_Mar__3_20:42:42_2002_542)----