channelmix: add option for stereo widen

When generating FC, add an option to subtract some of the generated
FC from the FL and FR channel to move the sound more to the center.

See #861
This commit is contained in:
Wim Taymans 2022-03-01 10:28:11 +01:00
parent 60b338d4cf
commit 5dd0a12875
7 changed files with 39 additions and 12 deletions

View file

@ -249,8 +249,9 @@ channelmix_f32_2_3p1_c(struct channelmix *mix, void * SPA_RESTRICT dst[],
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];
float w = c * mix->widen;
d[0][n] = s[0][n] - w;
d[1][n] = s[1][n] - w;
d[2][n] = c;
}
lr4_process(&mix->lr4[3], d[3], d[2], v3, n_samples);
@ -259,8 +260,9 @@ channelmix_f32_2_3p1_c(struct channelmix *mix, void * SPA_RESTRICT dst[],
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;
float w = c * mix->widen;
d[0][n] = (s[0][n] - w) * v0;
d[1][n] = (s[1][n] - w) * v1;
d[2][n] = c;
}
lr4_process(&mix->lr4[3], d[3], d[2], v3, n_samples);
@ -290,9 +292,10 @@ channelmix_f32_2_5p1_c(struct channelmix *mix, void * SPA_RESTRICT dst[],
else if (v0 == 1.0f && v1 == 1.0f) {
for (n = 0; n < n_samples; n++) {
float c = s[0][n] + s[1][n];
float w = c * mix->widen;
float m = s[0][n] - s[1][n];
d[0][n] = s[0][n];
d[1][n] = s[1][n];
d[0][n] = s[0][n] - w;
d[1][n] = s[1][n] - w;
d[3][n] = c;
d[5][n] = m;
}
@ -307,9 +310,10 @@ channelmix_f32_2_5p1_c(struct channelmix *mix, void * SPA_RESTRICT dst[],
else {
for (n = 0; n < n_samples; n++) {
float c = s[0][n] + s[1][n];
float w = c * mix->widen;
float m = s[0][n] - s[1][n];
d[0][n] = s[0][n] * v0;
d[1][n] = s[1][n] * v1;
d[0][n] = (s[0][n] - w) * v0;
d[1][n] = (s[1][n] - w) * v1;
d[3][n] = c;
d[5][n] = m;
}
@ -346,10 +350,13 @@ channelmix_f32_2_7p1_c(struct channelmix *mix, void * SPA_RESTRICT dst[],
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];
float w = c * mix->widen;
float m = 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[0][n] = s[0][n] - w;
d[1][n] = s[1][n] - w;
d[3][n] = c;
d[4][n] = s[0][n];
d[5][n] = s[1][n];
d[7][n] = m;
}
lr4_process(&mix->lr4[2], d[2], d[3], v2, n_samples);
@ -363,9 +370,10 @@ channelmix_f32_2_7p1_c(struct channelmix *mix, void * SPA_RESTRICT dst[],
else {
for (n = 0; n < n_samples; n++) {
float c = s[0][n] + s[1][n];
float w = c * mix->widen;
float m = s[0][n] - s[1][n];
d[0][n] = s[0][n] * v0;
d[1][n] = s[1][n] * v1;
d[0][n] = (s[0][n] - w) * v0;
d[1][n] = (s[1][n] - w) * v1;
d[3][n] = c;
d[4][n] = s[0][n] * v4;
d[5][n] = s[1][n] * v5;

View file

@ -72,6 +72,7 @@ struct channelmix {
float freq; /* sample frequency */
float lfe_cutoff; /* in Hz, 0 is disabled */
float rear_delay; /* in ms, 0 is disabled */
float widen; /* stereo widen. 0 is disabled */
struct lr4 lr4[SPA_AUDIO_MAX_CHANNELS];
float buffer[2][BUFFER_SIZE];

View file

@ -518,6 +518,15 @@ static int impl_node_enum_params(void *object, int seq,
this->mix.rear_delay, 0.0, 1000.0),
SPA_PROP_INFO_params, SPA_POD_Bool(true));
break;
case 14:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_PropInfo, id,
SPA_PROP_INFO_name, SPA_POD_String("channelmix.stereo-widen"),
SPA_PROP_INFO_description, SPA_POD_String("Stereo widen"),
SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Float(
this->mix.widen, 0.0, 1.0),
SPA_PROP_INFO_params, SPA_POD_Bool(true));
break;
default:
return 0;
}
@ -571,6 +580,8 @@ static int impl_node_enum_params(void *object, int seq,
spa_pod_builder_float(&b, this->mix.lfe_cutoff);
spa_pod_builder_string(&b, "channelmix.rear-delay");
spa_pod_builder_float(&b, this->mix.rear_delay);
spa_pod_builder_string(&b, "channelmix.stereo-widen");
spa_pod_builder_float(&b, this->mix.widen);
spa_pod_builder_pop(&b, &f[1]);
param = spa_pod_builder_pop(&b, &f[0]);
break;
@ -608,6 +619,8 @@ static int channelmix_set_param(struct impl *this, const char *k, const char *s)
spa_atof(s, &this->mix.lfe_cutoff);
else if (spa_streq(k, "channelmix.rear-delay"))
spa_atof(s, &this->mix.rear_delay);
else if (spa_streq(k, "channelmix.stereo-widen"))
spa_atof(s, &this->mix.widen);
else
return 0;
return 1;

View file

@ -86,4 +86,5 @@ stream.properties = {
#channelmix.upmix = false
#channelmix.lfe-cutoff = 0
#channelmix.rear-delay = 12.0
#channelmix.stereo-widen = 0.0
}

View file

@ -76,4 +76,5 @@ stream.properties = {
#channelmix.upmix = false
#channelmix.lfe-cutoff = 0
#channelmix.rear-delay = 12.0
#channelmix.stereo-widen = 0.0
}

View file

@ -207,6 +207,7 @@ context.objects = [
#channelmix.upmix = false
#channelmix.lfe-cutoff = 0
#channelmix.rear-delay = 12.0
#channelmix.stereo-widen = 0.0
channelmix.disable = true
#node.param.Props = {
# params = [
@ -263,6 +264,7 @@ context.objects = [
#channelmix.upmix = false
#channelmix.lfe-cutoff = 0
#channelmix.rear-delay = 12.0
#channelmix.stereo-widen = 0.0
channelmix.disable = true
#node.param.Props = {
# params = [

View file

@ -86,6 +86,7 @@ stream.properties = {
#channelmix.upmix = false
#channelmix.lfe-cutoff = 0
#channelmix.rear-delay = 12.0
#channelmix.stereo-widen = 0.0
}
# client/stream specific properties