When this code was split from dev/pad, the "volume" member size was changed
from u_int to uint8_t. This had the unfortunate side-effect of introducing an integer overflow when adjusting samples as the largest type used was now int16_t. This change copies the volume level to a temporary u_int and uses that in the calculation. Should fix recent failures with the dev/audio/t_pad/pad_output test.
This commit is contained in:
parent
2d00f56cae
commit
c7b9f2a541
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: auvolconv.c,v 1.1 2014/11/18 01:53:17 jmcneill Exp $ */
|
/* $NetBSD: auvolconv.c,v 1.2 2014/11/23 12:23:25 jmcneill Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca>
|
* Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca>
|
||||||
@ -27,7 +27,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: auvolconv.c,v 1.1 2014/11/18 01:53:17 jmcneill Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: auvolconv.c,v 1.2 2014/11/23 12:23:25 jmcneill Exp $");
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
@ -49,10 +49,12 @@ auvolconv_slinear16_le_fetch_to(struct audio_softc *asc,
|
|||||||
stream_filter_t *this;
|
stream_filter_t *this;
|
||||||
int16_t j, *wp;
|
int16_t j, *wp;
|
||||||
int m, err;
|
int m, err;
|
||||||
|
u_int vol;
|
||||||
|
|
||||||
pf = (auvolconv_filter_t *)self;
|
pf = (auvolconv_filter_t *)self;
|
||||||
this = &pf->base;
|
this = &pf->base;
|
||||||
max_used = (max_used + 1) & ~1;
|
max_used = (max_used + 1) & ~1;
|
||||||
|
vol = *pf->vol;
|
||||||
|
|
||||||
if ((err = this->prev->fetch_to(asc, this->prev, this->src, max_used)))
|
if ((err = this->prev->fetch_to(asc, this->prev, this->src, max_used)))
|
||||||
return err;
|
return err;
|
||||||
@ -61,7 +63,7 @@ auvolconv_slinear16_le_fetch_to(struct audio_softc *asc,
|
|||||||
FILTER_LOOP_PROLOGUE(this->src, 2, dst, 2, m) {
|
FILTER_LOOP_PROLOGUE(this->src, 2, dst, 2, m) {
|
||||||
j = le16dec(s);
|
j = le16dec(s);
|
||||||
wp = (int16_t *)d;
|
wp = (int16_t *)d;
|
||||||
le16enc(wp, (j * *pf->vol) / 255);
|
le16enc(wp, (j * vol) / 255);
|
||||||
} FILTER_LOOP_EPILOGUE(this->src, dst);
|
} FILTER_LOOP_EPILOGUE(this->src, dst);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -75,10 +77,12 @@ auvolconv_slinear16_be_fetch_to(struct audio_softc *asc,
|
|||||||
stream_filter_t *this;
|
stream_filter_t *this;
|
||||||
int16_t j, *wp;
|
int16_t j, *wp;
|
||||||
int m, err;
|
int m, err;
|
||||||
|
u_int vol;
|
||||||
|
|
||||||
pf = (auvolconv_filter_t *)self;
|
pf = (auvolconv_filter_t *)self;
|
||||||
this = &pf->base;
|
this = &pf->base;
|
||||||
max_used = (max_used + 1) & ~1;
|
max_used = (max_used + 1) & ~1;
|
||||||
|
vol = *pf->vol;
|
||||||
|
|
||||||
if ((err = this->prev->fetch_to(asc, this->prev, this->src, max_used)))
|
if ((err = this->prev->fetch_to(asc, this->prev, this->src, max_used)))
|
||||||
return err;
|
return err;
|
||||||
@ -87,7 +91,7 @@ auvolconv_slinear16_be_fetch_to(struct audio_softc *asc,
|
|||||||
FILTER_LOOP_PROLOGUE(this->src, 2, dst, 2, m) {
|
FILTER_LOOP_PROLOGUE(this->src, 2, dst, 2, m) {
|
||||||
j = be16dec(s);
|
j = be16dec(s);
|
||||||
wp = (int16_t *)d;
|
wp = (int16_t *)d;
|
||||||
be16enc(wp, (j * *pf->vol) / 255);
|
be16enc(wp, (j * vol) / 255);
|
||||||
} FILTER_LOOP_EPILOGUE(this->src, dst);
|
} FILTER_LOOP_EPILOGUE(this->src, dst);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user