From c86b4790a839a9e02f7ed95f229d41d829c09c99 Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 19 Sep 2014 21:16:42 +0200 Subject: af_hrtf: initialize coefficient arrays Sometimes, --af=hrtf produces heavy artifacts or silence. It's possible that this commit fixes these issues. My theory is that usually, the uninitialized coefficients quickly converge to sane values as more audio is filtered, which would explain why there are often artifacts on init, with normal playback after that. It's also possible that sometimes, the uninitialized values were NaN or inf, so that the artifacts (or silence) would never go away. Fix this by initializing the coefficients to 0. I'm not sure if this is correct, but certainly better than before. See issue #1104. --- audio/filter/af_hrtf.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/audio/filter/af_hrtf.c b/audio/filter/af_hrtf.c index 9ffda62448..4fb382aff4 100644 --- a/audio/filter/af_hrtf.c +++ b/audio/filter/af_hrtf.c @@ -284,6 +284,27 @@ static inline void update_ch(af_hrtf_t *s, short *in, const int k) s->ba_r[k] = in[4] + in[1] + in[3]; } +static void clear_coeff(af_hrtf_t *s, float *c) +{ + memset(c, 0, s->dlbuflen * sizeof(float)); +} + +static void reset(af_hrtf_t *s) +{ + clear_coeff(s, s->lf); + clear_coeff(s, s->rf); + clear_coeff(s, s->lr); + clear_coeff(s, s->rr); + clear_coeff(s, s->cf); + clear_coeff(s, s->cr); + clear_coeff(s, s->ba_l); + clear_coeff(s, s->ba_r); + clear_coeff(s, s->fwrbuf_l); + clear_coeff(s, s->fwrbuf_r); + clear_coeff(s, s->fwrbuf_lr); + clear_coeff(s, s->fwrbuf_rr); +} + /* Initialization and runtime control */ static int control(struct af_instance *af, int cmd, void* arg) { @@ -292,6 +313,7 @@ static int control(struct af_instance *af, int cmd, void* arg) switch(cmd) { case AF_CONTROL_REINIT: + reset(s); af->data->rate = 48000; mp_audio_set_channels_old(af->data, ((struct mp_audio*)arg)->nch); if(af->data->nch == 2) { @@ -309,6 +331,9 @@ static int control(struct af_instance *af, int cmd, void* arg) mp_audio_set_num_channels(af->data, 2); s->print_flag = 1; return test_output_res; + case AF_CONTROL_RESET: + reset(s); + return AF_OK; } return AF_UNKNOWN; -- cgit v1.2.3