mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-10-31 22:25:33 -04: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;
|
||||
}
|
||||
|
||||
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) {
|
||||
unsigned oc, ic;
|
||||
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
|
||||
* 0.375. The current (as result of 1..6) factors
|
||||
* 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.
|
||||
*
|
||||
|
|
@ -629,6 +677,8 @@ static void calc_map_table(pa_resampler *r) {
|
|||
if (!oc_connected && remix) {
|
||||
/* OK, we shall remix */
|
||||
|
||||
/* Try to find matching input ports for this output port */
|
||||
|
||||
if (on_left(b)) {
|
||||
unsigned n = 0;
|
||||
|
||||
|
|
@ -830,17 +880,54 @@ static void calc_map_table(pa_resampler *r) {
|
|||
}
|
||||
|
||||
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
|
||||
could mix our center channel in. In this case, mix
|
||||
it into left and right. Using .375 and 0.75 as
|
||||
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++) {
|
||||
|
||||
if (!on_left(r->o_cm.map[oc]) && !on_right(r->o_cm.map[oc]))
|
||||
continue;
|
||||
|
||||
if (ncenter[oc] <= 0)
|
||||
continue;
|
||||
|
||||
for (ic = 0; ic < r->i_ss.channels; ic++) {
|
||||
|
||||
if (ic_connected[ic]) {
|
||||
|
|
@ -848,8 +935,11 @@ static void calc_map_table(pa_resampler *r) {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (on_center(r->i_cm.map[ic]))
|
||||
r->map_table[oc][ic] = .375f / (float) ic_unconnected_center;
|
||||
if (!on_center(r->i_cm.map[ic]))
|
||||
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