Improved mixing function - more expensive in cycles though.
hw.driverN.saturate is no longer needed and has been removed. Mixing function thanks to jmcneill@.
This commit is contained in:
parent
fda69a13cf
commit
c65925dd1f
@ -1,4 +1,4 @@
|
||||
.\" $NetBSD: audio.4,v 1.77 2017/04/17 20:17:08 nat Exp $
|
||||
.\" $NetBSD: audio.4,v 1.78 2017/04/17 22:40:06 nat Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1996 The NetBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
@ -112,7 +112,6 @@ variables.
|
||||
.It hw.driverN.precision
|
||||
.It hw.driverN.frequency
|
||||
.It hw.driverN.channels
|
||||
.It hw.driverN.saturate
|
||||
.It hw.driverN.multiuser
|
||||
.El
|
||||
.Pp
|
||||
@ -127,20 +126,6 @@ These variables may only be changed when the sampling device is not in use.
|
||||
.Pp
|
||||
An additional
|
||||
.Xr sysctl 8
|
||||
variable controls how the samples are combined, hw.driverN.saturate.
|
||||
.Pp
|
||||
By default is set to 16.
|
||||
This means that volumes are not adjusted for the first 16 channels to be mixed.
|
||||
All virtual channels will use the
|
||||
.Em maximum
|
||||
set master volume unless the virtual channel volume is lowered by the user.
|
||||
.Pp
|
||||
If a greater number of channels are opened all channels are
|
||||
.Em divided
|
||||
evenly in volume with respect to the master volume.
|
||||
.Pp
|
||||
An additional
|
||||
.Xr sysctl 8
|
||||
variable determines if multiple users are allowed to access the sampling
|
||||
device, hw.driverN.multiuser.
|
||||
.Pp
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: audio.c,v 1.325 2017/04/17 20:17:08 nat Exp $ */
|
||||
/* $NetBSD: audio.c,v 1.326 2017/04/17 22:40:06 nat Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2016 Nathanial Sloss <nathanialsloss@yahoo.com.au>
|
||||
@ -148,7 +148,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.325 2017/04/17 20:17:08 nat Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.326 2017/04/17 22:40:06 nat Exp $");
|
||||
|
||||
#include "audio.h"
|
||||
#if NAUDIO > 0
|
||||
@ -257,7 +257,6 @@ void audio_play_thread(void *);
|
||||
void audio_rec_thread(void *);
|
||||
void recswvol_func(struct audio_softc *, struct audio_ringbuffer *,
|
||||
size_t, struct virtual_channel *);
|
||||
void saturate_func(struct audio_softc *);
|
||||
void mix_func(struct audio_softc *, struct audio_ringbuffer *,
|
||||
struct virtual_channel *);
|
||||
void mix_write(void *);
|
||||
@ -641,7 +640,6 @@ bad_rec:
|
||||
}
|
||||
|
||||
sc->sc_lastgain = 128;
|
||||
sc->sc_saturate = 16;
|
||||
sc->sc_multiuser = false;
|
||||
mutex_exit(sc->sc_lock);
|
||||
|
||||
@ -835,15 +833,6 @@ bad_rec:
|
||||
CTL_HW, node->sysctl_num,
|
||||
CTL_CREATE, CTL_EOL);
|
||||
|
||||
sysctl_createv(&sc->sc_log, 0, NULL, NULL,
|
||||
CTLFLAG_READWRITE,
|
||||
CTLTYPE_INT, "saturate",
|
||||
SYSCTL_DESCR("saturate to max. volume this many channels"),
|
||||
NULL, 0,
|
||||
&sc->sc_saturate, 0,
|
||||
CTL_HW, node->sysctl_num,
|
||||
CTL_CREATE, CTL_EOL);
|
||||
|
||||
sysctl_createv(&sc->sc_log, 0, NULL, NULL,
|
||||
CTLFLAG_READWRITE,
|
||||
CTLTYPE_BOOL, "multiuser",
|
||||
@ -3786,8 +3775,6 @@ audio_mix(void *v)
|
||||
sc->schedule_rih = true;
|
||||
}
|
||||
mutex_enter(sc->sc_intr_lock);
|
||||
if (sc->sc_opens < sc->sc_saturate && sc->sc_opens > 1)
|
||||
saturate_func(sc);
|
||||
|
||||
vc = SIMPLEQ_FIRST(&sc->sc_audiochan)->vc;
|
||||
cb = &sc->sc_pr;
|
||||
@ -5557,12 +5544,14 @@ mix_write(void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
#define DEF_MIX_FUNC(name, type) \
|
||||
#define DEF_MIX_FUNC(name, type, MINVAL, MAXVAL) \
|
||||
static void \
|
||||
mix_func##name(struct audio_softc *sc, struct audio_ringbuffer *cb, \
|
||||
struct virtual_channel *vc) \
|
||||
{ \
|
||||
int blksize, cc, cc1, cc2, m, resid; \
|
||||
int64_t product; \
|
||||
int64_t result; \
|
||||
type *orig, *tomix; \
|
||||
\
|
||||
blksize = sc->sc_pr.blksize; \
|
||||
@ -5581,9 +5570,15 @@ mix_write(void *arg)
|
||||
cc = cc2; \
|
||||
\
|
||||
for (m = 0; m < (cc / (name / 8)); m++) { \
|
||||
orig[m] += (type)((int32_t)(tomix[m] * \
|
||||
(vc->sc_swvol + 1)) / (sc->sc_opens * \
|
||||
256)); \
|
||||
tomix[m] = tomix[m] * \
|
||||
(int32_t)(vc->sc_swvol) / 255; \
|
||||
result = orig[m] + tomix[m]; \
|
||||
product = orig[m] * tomix[m]; \
|
||||
if (orig[m] > 0 && tomix[m] > 0) \
|
||||
result -= product / MAXVAL; \
|
||||
else if (orig[m] < 0 && tomix[m] < 0) \
|
||||
result -= product / MINVAL; \
|
||||
orig[m] = result; \
|
||||
} \
|
||||
\
|
||||
if (&orig[m] >= (type *)sc->sc_pr.s.end) \
|
||||
@ -5595,9 +5590,9 @@ mix_write(void *arg)
|
||||
} \
|
||||
} \
|
||||
|
||||
DEF_MIX_FUNC(8, int8_t);
|
||||
DEF_MIX_FUNC(16, int16_t);
|
||||
DEF_MIX_FUNC(32, int32_t);
|
||||
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);
|
||||
|
||||
void
|
||||
mix_func(struct audio_softc *sc, struct audio_ringbuffer *cb,
|
||||
@ -5619,63 +5614,6 @@ mix_func(struct audio_softc *sc, struct audio_ringbuffer *cb,
|
||||
}
|
||||
}
|
||||
|
||||
#define DEF_SATURATE_FUNC(name, type, max_type, min_type) \
|
||||
static void \
|
||||
saturate_func##name(struct audio_softc *sc) \
|
||||
{ \
|
||||
int blksize, m, i, resid; \
|
||||
type *orig; \
|
||||
\
|
||||
blksize = sc->sc_pr.blksize; \
|
||||
resid = blksize; \
|
||||
if (sc->sc_trigger_started == false) \
|
||||
resid *= 2; \
|
||||
\
|
||||
orig = (type *)(sc->sc_pr.s.inp); \
|
||||
\
|
||||
for (m = 0; m < (resid / (name / 8));m++) { \
|
||||
i = 0; \
|
||||
if (&orig[m] >= (type *)sc->sc_pr.s.end) { \
|
||||
orig = (type *)sc->sc_pr.s.start; \
|
||||
resid -= m; \
|
||||
m = 0; \
|
||||
} \
|
||||
if (orig[m] != 0) { \
|
||||
if (orig[m] > 0) \
|
||||
i = max_type / orig[m]; \
|
||||
else \
|
||||
i = min_type / orig[m]; \
|
||||
} \
|
||||
if (i > sc->sc_opens) \
|
||||
i = sc->sc_opens; \
|
||||
orig[m] *= i; \
|
||||
} \
|
||||
} \
|
||||
|
||||
|
||||
DEF_SATURATE_FUNC(8, int8_t, INT8_MAX, INT8_MIN);
|
||||
DEF_SATURATE_FUNC(16, int16_t, INT16_MAX, INT16_MIN);
|
||||
DEF_SATURATE_FUNC(32, int32_t, INT32_MAX, INT32_MIN);
|
||||
|
||||
void
|
||||
saturate_func(struct audio_softc *sc)
|
||||
{
|
||||
switch (sc->sc_precision) {
|
||||
case 8:
|
||||
saturate_func8(sc);
|
||||
break;
|
||||
case 16:
|
||||
saturate_func16(sc);
|
||||
break;
|
||||
case 24:
|
||||
case 32:
|
||||
saturate_func32(sc);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#define DEF_RECSWVOL_FUNC(name, type, bigger_type) \
|
||||
static void \
|
||||
recswvol_func##name(struct audio_softc *sc, \
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: audiovar.h,v 1.52 2017/04/17 20:17:08 nat Exp $ */
|
||||
/* $NetBSD: audiovar.h,v 1.53 2017/04/17 22:40:06 nat Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002 The NetBSD Foundation, Inc.
|
||||
@ -290,7 +290,6 @@ struct audio_softc {
|
||||
int sc_channels;
|
||||
int sc_precision;
|
||||
int sc_iffreq;
|
||||
int sc_saturate;
|
||||
struct audio_info sc_ai; /* Recent info for dev sound */
|
||||
bool sc_aivalid;
|
||||
#define VAUDIO_NFORMATS 1
|
||||
|
Loading…
Reference in New Issue
Block a user