channelmix: Prepare for generating LFE channel

Add channelmix.lfe-cutoff property, 0 is disabled
Disable upmix by default
This commit is contained in:
Wim Taymans 2021-03-17 11:09:19 +01:00
parent 4200ca98d6
commit e51cc5b537
7 changed files with 27 additions and 20 deletions

View file

@ -238,6 +238,7 @@ channelmix_f32_2_3p1_c(struct channelmix *mix, uint32_t n_dst, void * SPA_RESTRI
const float v0 = mix->matrix[0][0];
const float v1 = mix->matrix[1][1];
const float v2 = (mix->matrix[2][0] + mix->matrix[2][1]) * 0.5f;
const float v3 = (mix->matrix[3][0] + mix->matrix[3][1]) * 0.5f;
if (SPA_FLAG_IS_SET(mix->flags, CHANNELMIX_FLAG_ZERO)) {
for (i = 0; i < n_dst; i++)
@ -245,18 +246,20 @@ channelmix_f32_2_3p1_c(struct channelmix *mix, uint32_t n_dst, void * SPA_RESTRI
}
else if (v0 == 1.0f && v1 == 1.0f) {
for (n = 0; n < n_samples; n++) {
float c = s[0][n] + s[1][n];
d[0][n] = s[0][n];
d[1][n] = s[1][n];
d[2][n] = (s[0][n] + s[1][n]) * v2;
d[3][n] = 0.0f;
d[2][n] = c * v2;
d[3][n] = c * v3;
}
}
else {
for (n = 0; n < n_samples; n++) {
float c = s[0][n] + s[1][n];
d[0][n] = s[0][n] * v0;
d[1][n] = s[1][n] * v1;
d[2][n] = (d[0][n] + d[1][n]) * v2;
d[3][n] = 0.0f;
d[2][n] = c * v2;
d[3][n] = c * v3;
}
}
}
@ -272,6 +275,7 @@ channelmix_f32_2_5p1_c(struct channelmix *mix, uint32_t n_dst, void * SPA_RESTRI
const float v0 = mix->matrix[0][0];
const float v1 = mix->matrix[1][1];
const float v2 = (mix->matrix[2][0] + mix->matrix[2][1]) * 0.5f;
const float v3 = (mix->matrix[3][0] + mix->matrix[3][1]) * 0.5f;
const float v4 = mix->matrix[4][0];
const float v5 = mix->matrix[5][1];
@ -281,18 +285,20 @@ channelmix_f32_2_5p1_c(struct channelmix *mix, uint32_t n_dst, void * SPA_RESTRI
}
else if (v0 == 1.0f && v1 == 1.0f && v4 == 1.0f && v5 == 1.0f) {
for (n = 0; n < n_samples; n++) {
float c = s[0][n] + s[1][n];
d[0][n] = d[4][n] = s[0][n];
d[1][n] = d[5][n] = s[1][n];
d[2][n] = (s[0][n] + s[1][n]) * v2;
d[3][n] = 0.0f;
d[2][n] = c * v2;
d[3][n] = c * v3;
}
}
else {
for (n = 0; n < n_samples; n++) {
float c = s[0][n] + s[1][n];
d[0][n] = s[0][n] * v0;
d[1][n] = s[1][n] * v1;
d[2][n] = (d[0][n] + d[1][n]) * v2;
d[3][n] = 0.0f;
d[2][n] = c * v2;
d[3][n] = c * v3;
d[4][n] = s[0][n] * v4;
d[5][n] = s[1][n] * v5;
}

View file

@ -385,8 +385,7 @@ static int make_matrix(struct channelmix *mix)
spa_log_warn(mix->log, "can't produce FC");
}
}
if (unassigned & _MASK(LFE) &&
SPA_FLAG_IS_SET(mix->options, CHANNELMIX_OPTION_FILTER_LFE)) {
if (unassigned & _MASK(LFE) && mix->lfe_cutoff > 0.0f) {
if ((src_mask & STEREO) == STEREO) {
spa_log_debug(mix->log, "produce LFE from STEREO");
matrix[LFE][FL] += llev;

View file

@ -49,7 +49,6 @@ struct channelmix {
#define CHANNELMIX_OPTION_MIX_LFE (1<<0) /**< mix LFE */
#define CHANNELMIX_OPTION_NORMALIZE (1<<1) /**< normalize volumes */
#define CHANNELMIX_OPTION_UPMIX (1<<2) /**< do simple upmixing */
#define CHANNELMIX_OPTION_FILTER_LFE (1<<3) /**< generate and filter LFE */
uint32_t options;
struct spa_log *log;
@ -62,6 +61,9 @@ struct channelmix {
float matrix_orig[SPA_AUDIO_MAX_CHANNELS][SPA_AUDIO_MAX_CHANNELS];
float matrix[SPA_AUDIO_MAX_CHANNELS][SPA_AUDIO_MAX_CHANNELS];
float freq; /* sample frequency */
float lfe_cutoff; /* in Hz, 0 is disabled */
void (*process) (struct channelmix *mix, uint32_t n_dst, void * SPA_RESTRICT dst[n_dst],
uint32_t n_src, const void * SPA_RESTRICT src[n_src], uint32_t n_samples);
void (*set_volume) (struct channelmix *mix, float volume, bool mute,

View file

@ -303,6 +303,7 @@ static int setup_convert(struct impl *this,
this->mix.dst_mask = dst_mask;
this->mix.cpu_flags = this->cpu_flags;
this->mix.log = this->log;
this->mix.freq = src_info->info.raw.rate;
if ((res = channelmix_init(&this->mix)) < 0)
return res;
@ -1273,9 +1274,8 @@ impl_init(const struct spa_handle_factory *factory,
if ((str = spa_dict_lookup(info, "channelmix.upmix")) != NULL &&
(strcmp(str, "true") == 0 || atoi(str) != 0))
this->mix.options |= CHANNELMIX_OPTION_UPMIX;
if ((str = spa_dict_lookup(info, "channelmix.filter-lfe")) != NULL &&
(strcmp(str, "true") == 0 || atoi(str) != 0))
this->mix.options |= CHANNELMIX_OPTION_FILTER_LFE;
if ((str = spa_dict_lookup(info, "channelmix.lfe-cutoff")) != NULL)
this->mix.lfe_cutoff = atoi(str);
if ((str = spa_dict_lookup(info, SPA_KEY_AUDIO_POSITION)) != NULL) {
size_t len;
const char *p = str;

View file

@ -73,6 +73,6 @@ stream.properties = {
#resample.quality = 4
#channelmix.normalize = false
#channelmix.mix-lfe = true
channelmix.upmix = true
#channelmix.filter-lfe = false
#channelmix.upmix = false
#channelmix.lfe-cutoff = 0
}

View file

@ -62,6 +62,6 @@ stream.properties = {
#resample.quality = 4
#channelmix.normalize = false
#channelmix.mix-lfe = false
channelmix.upmix = true
#channelmix.filter-lfe = false
#channelmix.upmix = false
#channelmix.lfe-cutoff = 0
}

View file

@ -49,6 +49,6 @@ stream.properties = {
#resample.quality = 4
#channelmix.normalize = false
#channelmix.mix-lfe = false
channelmix.upmix = true
#channelmix.filter-lfe = false
#channelmix.upmix = false
#channelmix.lfe-cutoff = 0
}