mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-02 09:01:46 -05:00
Don't mix front-center into rear channels
If there's a center channel on input that is not available on output make sure we mix front-center only into front-left/right and rear-center into rear-left/right. Closes #400
This commit is contained in:
parent
b8fe1b683e
commit
209a8d7b55
1 changed files with 93 additions and 3 deletions
|
|
@ -510,6 +510,52 @@ static pa_bool_t on_lfe(pa_channel_position_t p) {
|
||||||
p == PA_CHANNEL_POSITION_LFE;
|
p == PA_CHANNEL_POSITION_LFE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static pa_bool_t on_front(pa_channel_position_t p) {
|
||||||
|
return
|
||||||
|
p == PA_CHANNEL_POSITION_FRONT_LEFT ||
|
||||||
|
p == PA_CHANNEL_POSITION_FRONT_RIGHT ||
|
||||||
|
p == PA_CHANNEL_POSITION_FRONT_CENTER ||
|
||||||
|
p == PA_CHANNEL_POSITION_TOP_FRONT_LEFT ||
|
||||||
|
p == PA_CHANNEL_POSITION_TOP_FRONT_RIGHT ||
|
||||||
|
p == PA_CHANNEL_POSITION_TOP_FRONT_CENTER ||
|
||||||
|
p == PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER ||
|
||||||
|
p == PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
static pa_bool_t on_rear(pa_channel_position_t p) {
|
||||||
|
return
|
||||||
|
p == PA_CHANNEL_POSITION_REAR_LEFT ||
|
||||||
|
p == PA_CHANNEL_POSITION_REAR_RIGHT ||
|
||||||
|
p == PA_CHANNEL_POSITION_REAR_CENTER ||
|
||||||
|
p == PA_CHANNEL_POSITION_TOP_REAR_LEFT ||
|
||||||
|
p == PA_CHANNEL_POSITION_TOP_REAR_RIGHT ||
|
||||||
|
p == PA_CHANNEL_POSITION_TOP_REAR_CENTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
static pa_bool_t on_side(pa_channel_position_t p) {
|
||||||
|
return
|
||||||
|
p == PA_CHANNEL_POSITION_SIDE_LEFT ||
|
||||||
|
p == PA_CHANNEL_POSITION_SIDE_RIGHT ||
|
||||||
|
p == PA_CHANNEL_POSITION_TOP_CENTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ON_FRONT,
|
||||||
|
ON_REAR,
|
||||||
|
ON_SIDE,
|
||||||
|
ON_OTHER
|
||||||
|
};
|
||||||
|
|
||||||
|
static int front_rear_side(pa_channel_position_t p) {
|
||||||
|
if (on_front(p))
|
||||||
|
return ON_FRONT;
|
||||||
|
if (on_rear(p))
|
||||||
|
return ON_REAR;
|
||||||
|
if (on_side(p))
|
||||||
|
return ON_SIDE;
|
||||||
|
return ON_OTHER;
|
||||||
|
}
|
||||||
|
|
||||||
static void calc_map_table(pa_resampler *r) {
|
static void calc_map_table(pa_resampler *r) {
|
||||||
unsigned oc, ic;
|
unsigned oc, ic;
|
||||||
pa_bool_t ic_connected[PA_CHANNELS_MAX];
|
pa_bool_t ic_connected[PA_CHANNELS_MAX];
|
||||||
|
|
@ -601,7 +647,9 @@ static void calc_map_table(pa_resampler *r) {
|
||||||
* D:left, all D:right, all D:center channels, gain is
|
* D:left, all D:right, all D:center channels, gain is
|
||||||
* 0.375. The current (as result of 1..6) factors
|
* 0.375. The current (as result of 1..6) factors
|
||||||
* should be multiplied by 0.75. (Alt. suggestion: 0.25
|
* should be multiplied by 0.75. (Alt. suggestion: 0.25
|
||||||
* vs. 0.5)
|
* vs. 0.5) If C-front is only mixed into
|
||||||
|
* L-front/R-front if available, otherwise into all L/R
|
||||||
|
* channels. Similarly for C-rear.
|
||||||
*
|
*
|
||||||
* S: and D: shall relate to the source resp. destination channels.
|
* S: and D: shall relate to the source resp. destination channels.
|
||||||
*
|
*
|
||||||
|
|
@ -629,6 +677,8 @@ static void calc_map_table(pa_resampler *r) {
|
||||||
if (!oc_connected && remix) {
|
if (!oc_connected && remix) {
|
||||||
/* OK, we shall remix */
|
/* OK, we shall remix */
|
||||||
|
|
||||||
|
/* Try to find matching input ports for this output port */
|
||||||
|
|
||||||
if (on_left(b)) {
|
if (on_left(b)) {
|
||||||
unsigned n = 0;
|
unsigned n = 0;
|
||||||
|
|
||||||
|
|
@ -830,17 +880,54 @@ static void calc_map_table(pa_resampler *r) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mixed_in) {
|
if (!mixed_in) {
|
||||||
|
unsigned ncenter[PA_CHANNELS_MAX];
|
||||||
|
pa_bool_t found_frs[PA_CHANNELS_MAX];
|
||||||
|
|
||||||
|
memset(ncenter, 0, sizeof(ncenter));
|
||||||
|
memset(found_frs, 0, sizeof(found_frs));
|
||||||
|
|
||||||
/* Hmm, as it appears there was no center channel we
|
/* Hmm, as it appears there was no center channel we
|
||||||
could mix our center channel in. In this case, mix
|
could mix our center channel in. In this case, mix
|
||||||
it into left and right. Using .375 and 0.75 as
|
it into left and right. Using .375 and 0.75 as
|
||||||
factors. */
|
factors. */
|
||||||
|
|
||||||
|
for (ic = 0; ic < r->i_ss.channels; ic++) {
|
||||||
|
|
||||||
|
if (ic_connected[ic])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!on_center(r->i_cm.map[ic]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (oc = 0; oc < r->o_ss.channels; oc++) {
|
||||||
|
|
||||||
|
if (!on_left(r->o_cm.map[oc]) && !on_right(r->o_cm.map[oc]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (front_rear_side(r->i_cm.map[ic]) == front_rear_side(r->o_cm.map[oc])) {
|
||||||
|
found_frs[ic] = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (oc = 0; oc < r->o_ss.channels; oc++) {
|
||||||
|
|
||||||
|
if (!on_left(r->o_cm.map[oc]) && !on_right(r->o_cm.map[oc]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!found_frs[ic] || front_rear_side(r->i_cm.map[ic]) == front_rear_side(r->o_cm.map[oc]))
|
||||||
|
ncenter[oc]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (oc = 0; oc < r->o_ss.channels; oc++) {
|
for (oc = 0; oc < r->o_ss.channels; oc++) {
|
||||||
|
|
||||||
if (!on_left(r->o_cm.map[oc]) && !on_right(r->o_cm.map[oc]))
|
if (!on_left(r->o_cm.map[oc]) && !on_right(r->o_cm.map[oc]))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (ncenter[oc] <= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
for (ic = 0; ic < r->i_ss.channels; ic++) {
|
for (ic = 0; ic < r->i_ss.channels; ic++) {
|
||||||
|
|
||||||
if (ic_connected[ic]) {
|
if (ic_connected[ic]) {
|
||||||
|
|
@ -848,8 +935,11 @@ static void calc_map_table(pa_resampler *r) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (on_center(r->i_cm.map[ic]))
|
if (!on_center(r->i_cm.map[ic]))
|
||||||
r->map_table[oc][ic] = .375f / (float) ic_unconnected_center;
|
continue;
|
||||||
|
|
||||||
|
if (!found_frs[ic] || front_rear_side(r->i_cm.map[ic]) == front_rear_side(r->o_cm.map[oc]))
|
||||||
|
r->map_table[oc][ic] = .375f / (float) ncenter[oc];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue