channelmix: only filter FC and LFE when upmixed

When we have an original source with LFE and FC, don't try to mix
it but pass it unmodified.

Fixes #2280
This commit is contained in:
Wim Taymans 2022-04-12 11:51:01 +02:00
parent b97327e1f6
commit e12e4295cf

View file

@ -157,6 +157,7 @@ static int make_matrix(struct channelmix *mix)
float slev = SQRT1_2; float slev = SQRT1_2;
float llev = 0.5f; float llev = 0.5f;
float maxsum = 0.0f; float maxsum = 0.0f;
bool filter_fc = false, filter_lfe = false;
#define _MATRIX(s,d) matrix[_CH(s)][_CH(d)] #define _MATRIX(s,d) matrix[_CH(s)][_CH(d)]
spa_log_debug(mix->log, "src-mask:%08"PRIx64" dst-mask:%08"PRIx64 spa_log_debug(mix->log, "src-mask:%08"PRIx64" dst-mask:%08"PRIx64
@ -399,6 +400,7 @@ static int make_matrix(struct channelmix *mix)
spa_log_debug(mix->log, "produce FC from STEREO"); spa_log_debug(mix->log, "produce FC from STEREO");
_MATRIX(FC,FL) += clev; _MATRIX(FC,FL) += clev;
_MATRIX(FC,FR) += clev; _MATRIX(FC,FR) += clev;
filter_fc = true;
} else { } else {
spa_log_warn(mix->log, "can't produce FC"); spa_log_warn(mix->log, "can't produce FC");
} }
@ -408,9 +410,11 @@ static int make_matrix(struct channelmix *mix)
spa_log_debug(mix->log, "produce LFE from STEREO"); spa_log_debug(mix->log, "produce LFE from STEREO");
_MATRIX(LFE,FL) += llev; _MATRIX(LFE,FL) += llev;
_MATRIX(LFE,FR) += llev; _MATRIX(LFE,FR) += llev;
filter_lfe = true;
} else if ((src_mask & FRONT) == FRONT) { } else if ((src_mask & FRONT) == FRONT) {
spa_log_debug(mix->log, "produce LFE from FC"); spa_log_debug(mix->log, "produce LFE from FC");
_MATRIX(LFE,FC) += llev; _MATRIX(LFE,FC) += llev;
filter_lfe = true;
} else { } else {
spa_log_warn(mix->log, "can't produce LFE"); spa_log_warn(mix->log, "can't produce LFE");
} }
@ -458,11 +462,11 @@ done:
sum += fabs(matrix[i][j]); sum += fabs(matrix[i][j]);
} }
maxsum = SPA_MAX(maxsum, sum); maxsum = SPA_MAX(maxsum, sum);
if (i == _CH(LFE) && mix->lfe_cutoff > 0.0f) { if (i == _CH(LFE) && mix->lfe_cutoff > 0.0f && filter_lfe) {
spa_log_debug(mix->log, "channel %d is LFE cutoff:%f", ic, mix->lfe_cutoff); spa_log_info(mix->log, "channel %d is LFE cutoff:%f", ic, mix->lfe_cutoff);
lr4_set(&mix->lr4[ic], BQ_LOWPASS, mix->lfe_cutoff / mix->freq); lr4_set(&mix->lr4[ic], BQ_LOWPASS, mix->lfe_cutoff / mix->freq);
} else if (i == _CH(FC) && mix->fc_cutoff > 0.0f) { } else if (i == _CH(FC) && mix->fc_cutoff > 0.0f && filter_fc) {
spa_log_debug(mix->log, "channel %d is FC cutoff:%f", ic, mix->fc_cutoff); spa_log_info(mix->log, "channel %d is FC cutoff:%f", ic, mix->fc_cutoff);
lr4_set(&mix->lr4[ic], BQ_LOWPASS, mix->fc_cutoff / mix->freq); lr4_set(&mix->lr4[ic], BQ_LOWPASS, mix->fc_cutoff / mix->freq);
} else { } else {
mix->lr4[ic].active = false; mix->lr4[ic].active = false;