Add common audio converters for software volume control. Only supports

slinear16_le and slinear16_be for now.

Convert pad(4) to use the new converters.
This commit is contained in:
jmcneill 2014-11-18 01:53:17 +00:00
parent 770df61b0d
commit dd9a139587
6 changed files with 88 additions and 80 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: padvol.c,v 1.6 2011/11/23 23:07:33 jmcneill Exp $ */
/* $NetBSD: auvolconv.c,v 1.1 2014/11/18 01:53:17 jmcneill Exp $ */
/*-
* Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca>
@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: padvol.c,v 1.6 2011/11/23 23:07:33 jmcneill Exp $");
__KERNEL_RCSID(0, "$NetBSD: auvolconv.c,v 1.1 2014/11/18 01:53:17 jmcneill Exp $");
#include <sys/types.h>
#include <sys/param.h>
@ -39,49 +39,18 @@ __KERNEL_RCSID(0, "$NetBSD: padvol.c,v 1.6 2011/11/23 23:07:33 jmcneill Exp $");
#include <dev/audiovar.h>
#include <dev/auconv.h>
#include <dev/auvolconv.h>
#include <dev/pad/padvar.h>
#include <dev/pad/padvol.h>
typedef struct pad_filter {
stream_filter_t base;
struct audio_softc *audiosc;
} pad_filter_t;
static void
pad_filter_dtor(stream_filter_t *this)
int
auvolconv_slinear16_le_fetch_to(struct audio_softc *asc,
stream_fetcher_t *self, audio_stream_t *dst, int max_used)
{
if (this)
kmem_free(this, sizeof(pad_filter_t));
}
static stream_filter_t *
pad_filter_factory(struct audio_softc *sc,
int (*fetch_to)(struct audio_softc *, stream_fetcher_t *,
audio_stream_t *, int))
{
pad_filter_t *this;
this = kmem_alloc(sizeof(pad_filter_t), KM_SLEEP);
this->base.base.fetch_to = fetch_to;
this->base.dtor = pad_filter_dtor;
this->base.set_fetcher = stream_filter_set_fetcher;
this->base.set_inputbuffer = stream_filter_set_inputbuffer;
this->audiosc = sc;
return (stream_filter_t *)this;
}
PAD_DEFINE_FILTER(pad_vol_slinear16_le)
{
pad_filter_t *pf;
pad_softc_t *sc;
auvolconv_filter_t *pf;
stream_filter_t *this;
int16_t j, *wp;
int m, err;
pf = (pad_filter_t *)self;
sc = device_private(pf->audiosc->sc_dev);
pf = (auvolconv_filter_t *)self;
this = &pf->base;
max_used = (max_used + 1) & ~1;
@ -92,22 +61,22 @@ PAD_DEFINE_FILTER(pad_vol_slinear16_le)
FILTER_LOOP_PROLOGUE(this->src, 2, dst, 2, m) {
j = le16dec(s);
wp = (int16_t *)d;
le16enc(wp, (j * sc->sc_swvol) / 255);
le16enc(wp, (j * *pf->vol) / 255);
} FILTER_LOOP_EPILOGUE(this->src, dst);
return 0;
}
PAD_DEFINE_FILTER(pad_vol_slinear16_be)
int
auvolconv_slinear16_be_fetch_to(struct audio_softc *asc,
stream_fetcher_t *self, audio_stream_t *dst, int max_used)
{
pad_filter_t *pf;
pad_softc_t *sc;
auvolconv_filter_t *pf;
stream_filter_t *this;
int16_t j, *wp;
int m, err;
pf = (pad_filter_t *)self;
sc = device_private(pf->audiosc->sc_dev);
pf = (auvolconv_filter_t *)self;
this = &pf->base;
max_used = (max_used + 1) & ~1;
@ -118,7 +87,7 @@ PAD_DEFINE_FILTER(pad_vol_slinear16_be)
FILTER_LOOP_PROLOGUE(this->src, 2, dst, 2, m) {
j = be16dec(s);
wp = (int16_t *)d;
be16enc(wp, (j * sc->sc_swvol) / 255);
be16enc(wp, (j * *pf->vol) / 255);
} FILTER_LOOP_EPILOGUE(this->src, dst);
return 0;

View File

@ -1,4 +1,4 @@
/* $NetBSD: padvol.h,v 1.3 2011/11/23 23:07:33 jmcneill Exp $ */
/* $NetBSD: auvolconv.h,v 1.1 2014/11/18 01:53:17 jmcneill Exp $ */
/*-
* Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca>
@ -26,28 +26,17 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _SYS_DEV_PAD_PADVOL_H
#define _SYS_DEV_PAD_PADVOL_H
#ifndef _SYS_DEV_AUVOLCONV_H
#define _SYS_DEV_AUVOLCONV_H
stream_filter_t * pad_vol_slinear16_le(struct audio_softc *,
const audio_params_t *, const audio_params_t *);
stream_filter_t * pad_vol_slinear16_be(struct audio_softc *,
const audio_params_t *, const audio_params_t *);
int auvolconv_slinear16_le_fetch_to(struct audio_softc *,
stream_fetcher_t *, audio_stream_t *, int);
int auvolconv_slinear16_be_fetch_to(struct audio_softc *,
stream_fetcher_t *, audio_stream_t *, int);
#define PAD_DEFINE_FILTER(name) \
static int \
name##_fetch_to(struct audio_softc *, stream_fetcher_t *, \
audio_stream_t *, int); \
stream_filter_t * name(struct audio_softc *, \
const audio_params_t *, const audio_params_t *); \
stream_filter_t * \
name(struct audio_softc *asc, const audio_params_t *from, \
const audio_params_t *to) \
{ \
return pad_filter_factory(asc, name##_fetch_to); \
} \
static int \
name##_fetch_to(struct audio_softc *asc, stream_fetcher_t *self, \
audio_stream_t *dst, int max_used)
typedef struct auvolconv_filter {
stream_filter_t base;
uint8_t *vol;
} auvolconv_filter_t;
#endif /* !_SYS_DEV_PAD_PADVOL_H */
#endif /* !_SYS_DEV_AUVOLCONV_H */

View File

@ -1,4 +1,4 @@
# $NetBSD: files.audio,v 1.2 2014/10/10 17:21:20 uebayasi Exp $
# $NetBSD: files.audio,v 1.3 2014/11/18 01:53:17 jmcneill Exp $
define audiobus { }
define midibus { }
@ -9,6 +9,7 @@ define midisyn
define mulaw: auconv
define auconv
define aurateconv
define auvolconv
# audio and midi devices, attaches to audio hardware driver
#
@ -25,6 +26,7 @@ file dev/auconv.c auconv
file dev/audio.c audio needs-flag
file dev/audiobell.c audiobell
file dev/aurateconv.c aurateconv needs-flag
file dev/auvolconv.c auvolconv
file dev/midi.c midi needs-flag
file dev/midictl.c midisyn
file dev/midisyn.c midisyn

View File

@ -1,5 +1,4 @@
# $NetBSD: files.pad,v 1.4 2009/09/08 09:47:42 jmcneill Exp $
# $NetBSD: files.pad,v 1.5 2014/11/18 01:53:17 jmcneill Exp $
defpseudodev pad: audiobus, auconv, aurateconv, mulaw
defpseudodev pad: audiobus, auconv, aurateconv, auvolconv, mulaw
file dev/pad/pad.c pad
file dev/pad/padvol.c pad

View File

@ -1,4 +1,4 @@
/* $NetBSD: pad.c,v 1.21 2014/07/25 08:10:38 dholland Exp $ */
/* $NetBSD: pad.c,v 1.22 2014/11/18 01:53:17 jmcneill Exp $ */
/*-
* Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca>
@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: pad.c,v 1.21 2014/07/25 08:10:38 dholland Exp $");
__KERNEL_RCSID(0, "$NetBSD: pad.c,v 1.22 2014/11/18 01:53:17 jmcneill Exp $");
#include <sys/types.h>
#include <sys/param.h>
@ -47,9 +47,9 @@ __KERNEL_RCSID(0, "$NetBSD: pad.c,v 1.21 2014/07/25 08:10:38 dholland Exp $");
#include <dev/audio_if.h>
#include <dev/audiovar.h>
#include <dev/auconv.h>
#include <dev/auvolconv.h>
#include <dev/pad/padvar.h>
#include <dev/pad/padvol.h>
#define PADUNIT(x) minor(x)
@ -91,6 +91,12 @@ static int pad_get_props(void *);
static int pad_round_blocksize(void *, int, int, const audio_params_t *);
static void pad_get_locks(void *, kmutex_t **, kmutex_t **);
static stream_filter_t *pad_swvol_filter_le(struct audio_softc *,
const audio_params_t *, const audio_params_t *);
static stream_filter_t *pad_swvol_filter_be(struct audio_softc *,
const audio_params_t *, const audio_params_t *);
static void pad_swvol_dtor(stream_filter_t *);
static const struct audio_hw_if pad_hw_if = {
.query_encoding = pad_query_encoding,
.set_params = pad_set_params,
@ -420,11 +426,11 @@ pad_set_params(void *opaque, int setmode, int usemode,
switch (play->encoding) {
case AUDIO_ENCODING_SLINEAR_LE:
if (play->precision == 16 && play->validbits == 16)
pfil->prepend(pfil, pad_vol_slinear16_le, play);
pfil->prepend(pfil, pad_swvol_filter_le, play);
break;
case AUDIO_ENCODING_SLINEAR_BE:
if (play->precision == 16 && play->validbits == 16)
pfil->prepend(pfil, pad_vol_slinear16_be, play);
pfil->prepend(pfil, pad_swvol_filter_be, play);
break;
default:
break;
@ -623,6 +629,49 @@ pad_get_locks(void *opaque, kmutex_t **intr, kmutex_t **thread)
*thread = &sc->sc_lock;
}
static stream_filter_t *
pad_swvol_filter_le(struct audio_softc *asc,
const audio_params_t *from, const audio_params_t *to)
{
auvolconv_filter_t *this;
device_t dev = audio_get_device(asc);
struct pad_softc *sc = device_private(dev);
this = kmem_alloc(sizeof(auvolconv_filter_t), KM_SLEEP);
this->base.base.fetch_to = auvolconv_slinear16_le_fetch_to;
this->base.dtor = pad_swvol_dtor;
this->base.set_fetcher = stream_filter_set_fetcher;
this->base.set_inputbuffer = stream_filter_set_inputbuffer;
this->vol = &sc->sc_swvol;
return (stream_filter_t *)this;
}
static stream_filter_t *
pad_swvol_filter_be(struct audio_softc *asc,
const audio_params_t *from, const audio_params_t *to)
{
auvolconv_filter_t *this;
device_t dev = audio_get_device(asc);
struct pad_softc *sc = device_private(dev);
this = kmem_alloc(sizeof(auvolconv_filter_t), KM_SLEEP);
this->base.base.fetch_to = auvolconv_slinear16_be_fetch_to;
this->base.dtor = pad_swvol_dtor;
this->base.set_fetcher = stream_filter_set_fetcher;
this->base.set_inputbuffer = stream_filter_set_inputbuffer;
this->vol = &sc->sc_swvol;
return (stream_filter_t *)this;
}
static void
pad_swvol_dtor(stream_filter_t *this)
{
if (this)
kmem_free(this, sizeof(auvolconv_filter_t));
}
#ifdef _MODULE
MODULE(MODULE_CLASS_DRIVER, pad, NULL);

View File

@ -1,4 +1,4 @@
/* $NetBSD: padvar.h,v 1.4 2011/11/23 23:07:33 jmcneill Exp $ */
/* $NetBSD: padvar.h,v 1.5 2014/11/18 01:53:17 jmcneill Exp $ */
/*-
* Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca>
@ -50,7 +50,7 @@ typedef struct pad_softc {
uint32_t sc_buflen;
uint32_t sc_rpos, sc_wpos;
u_int sc_swvol;
uint8_t sc_swvol;
} pad_softc_t;
#endif /* !_SYS_DEV_PAD_PADVAR_H */