mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-03 09:01:54 -05:00
channelmix: provide some more upmix options
If nothing else is possible, also try to upmix from FC See #1237
This commit is contained in:
parent
06cf1e1c00
commit
70722c0741
1 changed files with 24 additions and 14 deletions
|
|
@ -135,6 +135,7 @@ static const struct channelmix_info *find_channelmix_info(uint32_t src_chan, uin
|
||||||
|
|
||||||
#define _CH(ch) ((SPA_AUDIO_CHANNEL_ ## ch)-3)
|
#define _CH(ch) ((SPA_AUDIO_CHANNEL_ ## ch)-3)
|
||||||
#define _MASK(ch) (1ULL << _CH(ch))
|
#define _MASK(ch) (1ULL << _CH(ch))
|
||||||
|
#define FRONT (_MASK(FC))
|
||||||
#define STEREO (_MASK(FL)|_MASK(FR))
|
#define STEREO (_MASK(FL)|_MASK(FR))
|
||||||
#define REAR (_MASK(RL)|_MASK(RR))
|
#define REAR (_MASK(RL)|_MASK(RR))
|
||||||
#define SIDE (_MASK(SL)|_MASK(SR))
|
#define SIDE (_MASK(SL)|_MASK(SR))
|
||||||
|
|
@ -156,7 +157,7 @@ static int make_matrix(struct channelmix *mix)
|
||||||
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,
|
||||||
src_mask, dst_mask);
|
src_mask, dst_mask);
|
||||||
|
|
||||||
/* move the MONO mask to FC so that the lower bits can be shifted
|
/* move the MONO mask to FRONT so that the lower bits can be shifted
|
||||||
* away. */
|
* away. */
|
||||||
if ((src_mask & (1Ull << SPA_AUDIO_CHANNEL_MONO)) != 0)
|
if ((src_mask & (1Ull << SPA_AUDIO_CHANNEL_MONO)) != 0)
|
||||||
src_mask |= (1ULL << SPA_AUDIO_CHANNEL_FC);
|
src_mask |= (1ULL << SPA_AUDIO_CHANNEL_FC);
|
||||||
|
|
@ -168,12 +169,12 @@ static int make_matrix(struct channelmix *mix)
|
||||||
dst_mask >>= 3;
|
dst_mask >>= 3;
|
||||||
|
|
||||||
if (src_mask == 0 || dst_mask == 0) {
|
if (src_mask == 0 || dst_mask == 0) {
|
||||||
if (src_mask == _MASK(FC) && mix->src_chan == 1) {
|
if (src_mask == FRONT && mix->src_chan == 1) {
|
||||||
/* one FC/MONO src goes everywhere */
|
/* one FC/MONO src goes everywhere */
|
||||||
spa_log_debug(mix->log, "distribute FC/MONO");
|
spa_log_debug(mix->log, "distribute FC/MONO");
|
||||||
for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++)
|
for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++)
|
||||||
matrix[i][0]= 1.0f;
|
matrix[i][0]= 1.0f;
|
||||||
} else if (dst_mask == _MASK(FC) && mix->dst_chan == 1) {
|
} else if (dst_mask == FRONT && mix->dst_chan == 1) {
|
||||||
/* one FC/MONO dst get average of everything */
|
/* one FC/MONO dst get average of everything */
|
||||||
spa_log_debug(mix->log, "average FC/MONO");
|
spa_log_debug(mix->log, "average FC/MONO");
|
||||||
for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++)
|
for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++)
|
||||||
|
|
@ -200,7 +201,7 @@ static int make_matrix(struct channelmix *mix)
|
||||||
|
|
||||||
spa_log_debug(mix->log, "unassigned downmix %08" PRIx64, unassigned);
|
spa_log_debug(mix->log, "unassigned downmix %08" PRIx64, unassigned);
|
||||||
|
|
||||||
if (unassigned & _MASK(FC)){
|
if (unassigned & FRONT){
|
||||||
if ((dst_mask & STEREO) == STEREO){
|
if ((dst_mask & STEREO) == STEREO){
|
||||||
spa_log_debug(mix->log, "assign FC to STEREO");
|
spa_log_debug(mix->log, "assign FC to STEREO");
|
||||||
if(src_mask & STEREO) {
|
if(src_mask & STEREO) {
|
||||||
|
|
@ -216,11 +217,11 @@ static int make_matrix(struct channelmix *mix)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unassigned & STEREO){
|
if (unassigned & STEREO){
|
||||||
if (dst_mask & _MASK(FC)) {
|
if (dst_mask & FRONT) {
|
||||||
spa_log_debug(mix->log, "assign STEREO to FC");
|
spa_log_debug(mix->log, "assign STEREO to FC");
|
||||||
_MATRIX(FC,FL) += SQRT1_2;
|
_MATRIX(FC,FL) += SQRT1_2;
|
||||||
_MATRIX(FC,FR) += SQRT1_2;
|
_MATRIX(FC,FR) += SQRT1_2;
|
||||||
if (src_mask & _MASK(FC))
|
if (src_mask & FRONT)
|
||||||
_MATRIX(FC,FC) = clev * SQRT2;
|
_MATRIX(FC,FC) = clev * SQRT2;
|
||||||
} else {
|
} else {
|
||||||
spa_log_warn(mix->log, "can't assign STEREO");
|
spa_log_warn(mix->log, "can't assign STEREO");
|
||||||
|
|
@ -251,7 +252,7 @@ static int make_matrix(struct channelmix *mix)
|
||||||
_MATRIX(FL,RC) += slev * SQRT1_2;
|
_MATRIX(FL,RC) += slev * SQRT1_2;
|
||||||
_MATRIX(FR,RC) += slev * SQRT1_2;
|
_MATRIX(FR,RC) += slev * SQRT1_2;
|
||||||
}
|
}
|
||||||
} else if (dst_mask & _MASK(FC)) {
|
} else if (dst_mask & FRONT) {
|
||||||
spa_log_debug(mix->log, "assign RC to FC");
|
spa_log_debug(mix->log, "assign RC to FC");
|
||||||
_MATRIX(FC,RC) += slev * SQRT1_2;
|
_MATRIX(FC,RC) += slev * SQRT1_2;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -289,7 +290,7 @@ static int make_matrix(struct channelmix *mix)
|
||||||
_MATRIX(FL,RL) += slev;
|
_MATRIX(FL,RL) += slev;
|
||||||
_MATRIX(FR,RR) += slev;
|
_MATRIX(FR,RR) += slev;
|
||||||
}
|
}
|
||||||
} else if (dst_mask & _MASK(FC)) {
|
} else if (dst_mask & FRONT) {
|
||||||
spa_log_debug(mix->log, "assign RL+RR to FC");
|
spa_log_debug(mix->log, "assign RL+RR to FC");
|
||||||
_MATRIX(FC,RL)+= slev * SQRT1_2;
|
_MATRIX(FC,RL)+= slev * SQRT1_2;
|
||||||
_MATRIX(FC,RR)+= slev * SQRT1_2;
|
_MATRIX(FC,RR)+= slev * SQRT1_2;
|
||||||
|
|
@ -328,7 +329,7 @@ static int make_matrix(struct channelmix *mix)
|
||||||
_MATRIX(FL,SL) += slev;
|
_MATRIX(FL,SL) += slev;
|
||||||
_MATRIX(FR,SR) += slev;
|
_MATRIX(FR,SR) += slev;
|
||||||
}
|
}
|
||||||
} else if (dst_mask & _MASK(FC)) {
|
} else if (dst_mask & FRONT) {
|
||||||
spa_log_debug(mix->log, "assign SL+SR to FC");
|
spa_log_debug(mix->log, "assign SL+SR to FC");
|
||||||
_MATRIX(FC,SL) += slev * SQRT1_2;
|
_MATRIX(FC,SL) += slev * SQRT1_2;
|
||||||
_MATRIX(FC,SR) += slev * SQRT1_2;
|
_MATRIX(FC,SR) += slev * SQRT1_2;
|
||||||
|
|
@ -342,7 +343,7 @@ static int make_matrix(struct channelmix *mix)
|
||||||
spa_log_debug(mix->log, "assign FLC+FRC to FL+FR");
|
spa_log_debug(mix->log, "assign FLC+FRC to FL+FR");
|
||||||
_MATRIX(FL,FLC)+= 1.0f;
|
_MATRIX(FL,FLC)+= 1.0f;
|
||||||
_MATRIX(FR,FRC)+= 1.0f;
|
_MATRIX(FR,FRC)+= 1.0f;
|
||||||
} else if(dst_mask & _MASK(FC)) {
|
} else if(dst_mask & FRONT) {
|
||||||
spa_log_debug(mix->log, "assign FLC+FRC to FC");
|
spa_log_debug(mix->log, "assign FLC+FRC to FC");
|
||||||
_MATRIX(FC,FLC)+= SQRT1_2;
|
_MATRIX(FC,FLC)+= SQRT1_2;
|
||||||
_MATRIX(FC,FRC)+= SQRT1_2;
|
_MATRIX(FC,FRC)+= SQRT1_2;
|
||||||
|
|
@ -352,7 +353,7 @@ static int make_matrix(struct channelmix *mix)
|
||||||
}
|
}
|
||||||
if (unassigned & _MASK(LFE) &&
|
if (unassigned & _MASK(LFE) &&
|
||||||
SPA_FLAG_IS_SET(mix->options, CHANNELMIX_OPTION_MIX_LFE)) {
|
SPA_FLAG_IS_SET(mix->options, CHANNELMIX_OPTION_MIX_LFE)) {
|
||||||
if (dst_mask & _MASK(FC)) {
|
if (dst_mask & FRONT) {
|
||||||
spa_log_debug(mix->log, "assign LFE to FC");
|
spa_log_debug(mix->log, "assign LFE to FC");
|
||||||
_MATRIX(FC,LFE) += llev;
|
_MATRIX(FC,LFE) += llev;
|
||||||
} else if (dst_mask & STEREO) {
|
} else if (dst_mask & STEREO) {
|
||||||
|
|
@ -371,7 +372,7 @@ static int make_matrix(struct channelmix *mix)
|
||||||
|
|
||||||
spa_log_debug(mix->log, "unassigned upmix %08" PRIx64, unassigned);
|
spa_log_debug(mix->log, "unassigned upmix %08" PRIx64, unassigned);
|
||||||
|
|
||||||
if (unassigned & _MASK(FC)) {
|
if (unassigned & FRONT) {
|
||||||
if ((src_mask & STEREO) == STEREO) {
|
if ((src_mask & STEREO) == STEREO) {
|
||||||
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;
|
||||||
|
|
@ -385,6 +386,9 @@ 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;
|
||||||
|
} else if ((src_mask & FRONT) == FRONT) {
|
||||||
|
spa_log_debug(mix->log, "produce LFE from FC");
|
||||||
|
_MATRIX(LFE,FC) += llev;
|
||||||
} else {
|
} else {
|
||||||
spa_log_warn(mix->log, "can't produce LFE");
|
spa_log_warn(mix->log, "can't produce LFE");
|
||||||
}
|
}
|
||||||
|
|
@ -394,11 +398,14 @@ static int make_matrix(struct channelmix *mix)
|
||||||
spa_log_debug(mix->log, "produce SIDE from REAR");
|
spa_log_debug(mix->log, "produce SIDE from REAR");
|
||||||
_MATRIX(SL,RL) += 1.0f;
|
_MATRIX(SL,RL) += 1.0f;
|
||||||
_MATRIX(SR,RR) += 1.0f;
|
_MATRIX(SR,RR) += 1.0f;
|
||||||
|
|
||||||
} else if ((src_mask & STEREO) == STEREO) {
|
} else if ((src_mask & STEREO) == STEREO) {
|
||||||
spa_log_debug(mix->log, "produce SIDE from STEREO");
|
spa_log_debug(mix->log, "produce SIDE from STEREO");
|
||||||
_MATRIX(SL,FL) += 1.0f;
|
_MATRIX(SL,FL) += 1.0f;
|
||||||
_MATRIX(SR,FR) += 1.0f;
|
_MATRIX(SR,FR) += 1.0f;
|
||||||
|
} else if ((src_mask & FRONT) == FRONT) {
|
||||||
|
spa_log_debug(mix->log, "produce SIDE from FC");
|
||||||
|
_MATRIX(SL,FC) += clev;
|
||||||
|
_MATRIX(SR,FC) += clev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (unassigned & REAR) {
|
if (unassigned & REAR) {
|
||||||
|
|
@ -406,11 +413,14 @@ static int make_matrix(struct channelmix *mix)
|
||||||
spa_log_debug(mix->log, "produce REAR from SIDE");
|
spa_log_debug(mix->log, "produce REAR from SIDE");
|
||||||
_MATRIX(RL,SL) += 1.0f;
|
_MATRIX(RL,SL) += 1.0f;
|
||||||
_MATRIX(RR,SR) += 1.0f;
|
_MATRIX(RR,SR) += 1.0f;
|
||||||
|
|
||||||
} else if ((src_mask & STEREO) == STEREO) {
|
} else if ((src_mask & STEREO) == STEREO) {
|
||||||
spa_log_debug(mix->log, "produce REAR from STEREO");
|
spa_log_debug(mix->log, "produce REAR from STEREO");
|
||||||
_MATRIX(RL,FL) += 1.0f;
|
_MATRIX(RL,FL) += 1.0f;
|
||||||
_MATRIX(RR,FR) += 1.0f;
|
_MATRIX(RR,FR) += 1.0f;
|
||||||
|
} else if ((src_mask & FRONT) == FRONT) {
|
||||||
|
spa_log_debug(mix->log, "produce REAR from FC");
|
||||||
|
_MATRIX(RL,FC) += clev;
|
||||||
|
_MATRIX(RR,FC) += clev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue