Skip to content

Commit 43b6186

Browse files
committed
matrix4{,_mb}: Use laterally symmetric directional boost (yet again).
Independent boost distorts phantom source location somewhat when panned between left/right and center, but eliminates pumping of the opposite channel with hard-panned elements. What I'm not sure of is whether this pumping is ever audible with normal program material (i.e. not contrived test signals), and, if it is audible, which defect is actually preferable.
1 parent 7c38a54 commit 43b6186

File tree

3 files changed

+38
-57
lines changed

3 files changed

+38
-57
lines changed

matrix4.c

+9-11
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,14 @@ struct matrix4_state {
4040
struct event_config evc;
4141
struct axes ax, ax_ev;
4242
sample_t norm_mult, surr_mult;
43-
struct smf_state dir_boost_smooth[2];
43+
struct smf_state dir_boost_smooth;
4444
ssize_t len, p, drain_frames, fade_frames, fade_p;
4545
};
4646

4747
sample_t * matrix4_effect_run(struct effect *e, ssize_t *frames, sample_t *ibuf, sample_t *obuf)
4848
{
4949
ssize_t i, k, oframes = 0;
50-
double fl_boost = 0.0, fr_boost = 0.0;
50+
double dir_boost = 0.0;
5151
struct matrix4_state *state = (struct matrix4_state *) e->data;
5252

5353
for (i = 0; i < *frames; ++i) {
@@ -78,11 +78,10 @@ sample_t * matrix4_effect_run(struct effect *e, ssize_t *frames, sample_t *ibuf,
7878

7979
struct matrix_coefs m = {0};
8080
calc_matrix_coefs(&state->ax, state->do_dir_boost, norm_mult, surr_mult, &m);
81-
fl_boost = smf_asym_run(&state->dir_boost_smooth[0], m.fl_boost);
82-
fr_boost = smf_asym_run(&state->dir_boost_smooth[1], m.fr_boost);
81+
dir_boost = smf_asym_run(&state->dir_boost_smooth, m.dir_boost);
8382

84-
const double ll_m = norm_mult + fl_boost;
85-
const double rr_m = norm_mult + fr_boost;
83+
const double ll_m = norm_mult + dir_boost;
84+
const double rr_m = norm_mult + dir_boost;
8685
const double lr_m = 0.0, rl_m = 0.0;
8786

8887
const sample_t out_l = s0_d*ll_m + s1_d*lr_m;
@@ -125,9 +124,9 @@ sample_t * matrix4_effect_run(struct effect *e, ssize_t *frames, sample_t *ibuf,
125124
/* TODO: Implement a proper way for effects to show status lines. */
126125
if (state->show_status) {
127126
dsp_log_acquire();
128-
dsp_log_printf("\n%s%s: lr: %+06.2f (%+06.2f); cs: %+06.2f (%+06.2f); dir_boost: l:%05.3f r:%05.3f; adj: %05.3f; ord: %zd; diff: %zd; early: %zd\033[K\r\033[A",
127+
dsp_log_printf("\n%s%s: lr: %+06.2f (%+06.2f); cs: %+06.2f (%+06.2f); dir_boost: %05.3f; adj: %05.3f; ord: %zd; diff: %zd; early: %zd\033[K\r\033[A",
129128
e->name, (state->disable) ? " [off]" : "", TO_DEGREES(state->ax.lr), TO_DEGREES(state->ax_ev.lr), TO_DEGREES(state->ax.cs), TO_DEGREES(state->ax_ev.cs),
130-
fl_boost, fr_boost, state->ev.adj, state->ev.ord_count, state->ev.diff_count, state->ev.early_count);
129+
dir_boost, state->ev.adj, state->ev.ord_count, state->ev.diff_count, state->ev.early_count);
131130
dsp_log_release();
132131
}
133132
#endif
@@ -237,9 +236,8 @@ struct effect * matrix4_effect_init(const struct effect_info *ei, const struct s
237236
}
238237
smooth_state_init(&state->sm, istream);
239238
event_state_init(&state->ev, istream);
240-
for (int i = 0; i < 2; ++i)
241-
smf_asym_init(&state->dir_boost_smooth[i], istream->fs,
242-
SMF_RISE_TIME(DIR_BOOST_RT0), DIR_BOOST_SENS_RISE, DIR_BOOST_SENS_FALL);
239+
smf_asym_init(&state->dir_boost_smooth, istream->fs,
240+
SMF_RISE_TIME(DIR_BOOST_RT0), DIR_BOOST_SENS_RISE, DIR_BOOST_SENS_FALL);
243241

244242
state->len = TIME_TO_FRAMES(DELAY_TIME, istream->fs);
245243
state->bufs = calloc(istream->channels, sizeof(sample_t *));

matrix4_common.h

+5-10
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ struct axes {
9191

9292
struct matrix_coefs {
9393
double lsl, lsr, rsl, rsr;
94-
double fl_boost, fr_boost;
94+
double dir_boost;
9595
};
9696

9797
struct event_state {
@@ -611,21 +611,16 @@ static void calc_matrix_coefs(const struct axes *ax, int do_dir_boost, double no
611611
m->rsl *= rs_m_scale;
612612
m->rsr *= rs_m_scale;
613613

614-
m->fl_boost = 0.0;
615-
m->fr_boost = 0.0;
614+
m->dir_boost = 0.0;
616615
if (do_dir_boost) {
617616
const double b_norm = 1.0-norm_mult;
618-
const double b_lr = b_norm*gsl;
619617
if (cs > 0.0) {
620618
const double b_gl = 1.0+tan(abs_lr+cs-M_PI_4);
621-
const double b = b_norm*b_gl*b_gl;
622-
m->fl_boost = (lr >= 0.0) ? b : b - b_lr;
623-
m->fr_boost = (lr <= 0.0) ? b : b - b_lr;
619+
m->dir_boost = b_norm*b_gl*b_gl;
624620
}
625621
else {
626-
const double b = (cs > -M_PI_4/2) ? b_lr*cos(3.0*cs) : b_lr*cos(cs-M_PI_4);
627-
m->fl_boost = (lr > 0.0) ? b : 0.0;
628-
m->fr_boost = (lr < 0.0) ? b : 0.0;
622+
const double b_lr = b_norm*gsl;
623+
m->dir_boost = (cs > -M_PI_4/2) ? b_lr*cos(3.0*cs) : b_lr*cos(cs-M_PI_4);
629624
}
630625
}
631626
}

matrix4_mb.c

+24-36
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ struct matrix4_band {
7474
struct smooth_state sm;
7575
struct event_state ev;
7676
struct axes ax, ax_ev;
77-
double fl_boost, fr_boost;
77+
double dir_boost;
7878
#if DOWNSAMPLE_FACTOR > 1
7979
struct cs_interp_state lsl_m, lsr_m;
8080
struct cs_interp_state rsl_m, rsr_m;
@@ -91,11 +91,11 @@ struct matrix4_mb_state {
9191
sample_t norm_mult, surr_mult;
9292
struct event_config evc;
9393
#if DOWNSAMPLE_FACTOR > 1
94-
struct cs_interp_state fl_boost, fr_boost;
94+
struct cs_interp_state dir_boost;
9595
#else
96-
double fl_boost, fr_boost;
96+
double dir_boost;
9797
#endif
98-
struct smf_state dir_boost_smooth[2];
98+
struct smf_state dir_boost_smooth;
9999
ssize_t len, p, drain_frames, fade_frames, fade_p;
100100
};
101101

@@ -255,7 +255,7 @@ sample_t * matrix4_mb_effect_run(struct effect *e, ssize_t *frames, sample_t *ib
255255

256256
for (i = 0; i < *frames; ++i) {
257257
double norm_mult = state->norm_mult, surr_mult = state->surr_mult;
258-
double fl_boost = 0.0, fr_boost = 0.0, f_boost_norm = 0.0;
258+
double dir_boost = 0.0, dir_boost_norm = 0.0;
259259
sample_t out_ls = 0.0, out_rs = 0.0;
260260
const sample_t s0 = ibuf[i*e->istream.channels + state->c0];
261261
const sample_t s1 = ibuf[i*e->istream.channels + state->c1];
@@ -299,13 +299,11 @@ sample_t * matrix4_mb_effect_run(struct effect *e, ssize_t *frames, sample_t *ib
299299

300300
struct matrix_coefs m = {0};
301301
calc_matrix_coefs(&band->ax, state->do_dir_boost, norm_mult, surr_mult, &m);
302-
band->fl_boost = m.fl_boost;
303-
band->fr_boost = m.fr_boost;
302+
band->dir_boost = m.dir_boost;
304303

305304
const double weight = pwr_env_d.sum * fb_weights[k];
306-
fl_boost += m.fl_boost * m.fl_boost * weight;
307-
fr_boost += m.fr_boost * m.fr_boost * weight;
308-
f_boost_norm += weight;
305+
dir_boost += m.dir_boost * m.dir_boost * weight;
306+
dir_boost_norm += weight;
309307

310308
#if DOWNSAMPLE_FACTOR > 1
311309
cs_interp_insert(&band->lsl_m, m.lsl);
@@ -324,27 +322,18 @@ sample_t * matrix4_mb_effect_run(struct effect *e, ssize_t *frames, sample_t *ib
324322
#if DOWNSAMPLE_FACTOR > 1
325323
if (state->s == 0) {
326324
#endif
327-
if (f_boost_norm > 0.0) {
328-
fl_boost = sqrt(fl_boost / f_boost_norm);
329-
fr_boost = sqrt(fr_boost / f_boost_norm);
330-
}
331-
else {
332-
fl_boost = 0.0;
333-
fr_boost = 0.0;
334-
}
335-
fl_boost = smf_asym_run(&state->dir_boost_smooth[0], fl_boost);
336-
fr_boost = smf_asym_run(&state->dir_boost_smooth[1], fr_boost);
325+
dir_boost = smf_asym_run(&state->dir_boost_smooth,
326+
(dir_boost_norm > 0.0) ? sqrt(dir_boost / dir_boost_norm) : 0.0);
337327
#if DOWNSAMPLE_FACTOR > 1
338-
cs_interp_insert(&state->fl_boost, fl_boost);
339-
cs_interp_insert(&state->fr_boost, fr_boost);
328+
cs_interp_insert(&state->dir_boost, dir_boost);
340329
}
341-
const double ll_m = norm_mult + cs_interp(&state->fl_boost, state->s);
342-
const double rr_m = norm_mult + cs_interp(&state->fr_boost, state->s);
330+
const double dir_boost_interp = cs_interp(&state->dir_boost, state->s);
331+
const double ll_m = norm_mult + dir_boost_interp;
332+
const double rr_m = norm_mult + dir_boost_interp;
343333
#else
344-
state->fl_boost = fl_boost;
345-
state->fr_boost = fr_boost;
346-
const double ll_m = norm_mult + fl_boost;
347-
const double rr_m = norm_mult + fr_boost;
334+
state->dir_boost = dir_boost;
335+
const double ll_m = norm_mult + dir_boost;
336+
const double rr_m = norm_mult + dir_boost;
348337
#endif
349338
const double lr_m = 0.0, rl_m = 0.0;
350339

@@ -387,17 +376,17 @@ sample_t * matrix4_mb_effect_run(struct effect *e, ssize_t *frames, sample_t *ib
387376
if (state->show_status) {
388377
dsp_log_acquire();
389378
for (i = 0; i < N_BANDS; ++i) {
390-
dsp_log_printf("\n%s%s: band %zd: lr: %+06.2f (%+06.2f); cs: %+06.2f (%+06.2f); dir_boost: l:%05.3f r:%05.3f; adj: %05.3f; ord: %zd; diff: %zd; early: %zd\033[K\r",
379+
dsp_log_printf("\n%s%s: band %zd: lr: %+06.2f (%+06.2f); cs: %+06.2f (%+06.2f); dir_boost: %05.3f; adj: %05.3f; ord: %zd; diff: %zd; early: %zd\033[K\r",
391380
e->name, (state->disable) ? " [off]" : "", i,
392381
TO_DEGREES(state->band[i].ax.lr), TO_DEGREES(state->band[i].ax_ev.lr), TO_DEGREES(state->band[i].ax.cs), TO_DEGREES(state->band[i].ax_ev.cs),
393-
state->band[i].fl_boost, state->band[i].fr_boost, state->band[i].ev.adj, state->band[i].ev.ord_count, state->band[i].ev.diff_count, state->band[i].ev.early_count);
382+
state->band[i].dir_boost, state->band[i].ev.adj, state->band[i].ev.ord_count, state->band[i].ev.diff_count, state->band[i].ev.early_count);
394383
}
395-
dsp_log_printf("\n%s%s: weighted RMS dir_boost: l:%05.3f r:%05.3f\033[K\r",
384+
dsp_log_printf("\n%s%s: weighted RMS dir_boost: %05.3f\033[K\r",
396385
e->name, (state->disable) ? " [off]" : "",
397386
#if DOWNSAMPLE_FACTOR > 1
398-
CS_INTERP_PEEK(&state->fl_boost), CS_INTERP_PEEK(&state->fr_boost));
387+
CS_INTERP_PEEK(&state->dir_boost));
399388
#else
400-
state->fl_boost, state->fr_boost);
389+
state->dir_boost);
401390
#endif
402391
dsp_log_printf("\033[%zdA", i+1);
403392
dsp_log_release();
@@ -521,9 +510,8 @@ struct effect * matrix4_mb_effect_init(const struct effect_info *ei, const struc
521510
smooth_state_init(&state->band[k].sm, istream);
522511
event_state_init(&state->band[k].ev, istream);
523512
}
524-
for (int i = 0; i < 2; ++i)
525-
smf_asym_init(&state->dir_boost_smooth[i], DOWNSAMPLED_FS(istream->fs),
526-
SMF_RISE_TIME(DIR_BOOST_RT0), DIR_BOOST_SENS_RISE, DIR_BOOST_SENS_FALL);
513+
smf_asym_init(&state->dir_boost_smooth, DOWNSAMPLED_FS(istream->fs),
514+
SMF_RISE_TIME(DIR_BOOST_RT0), DIR_BOOST_SENS_RISE, DIR_BOOST_SENS_FALL);
527515

528516
#if DOWNSAMPLE_FACTOR > 1
529517
state->len = TIME_TO_FRAMES(DELAY_TIME, istream->fs) + CS_INTERP_DELAY_FRAMES;

0 commit comments

Comments
 (0)