channelmix: add some more channelmix positions

Implement downmix of some top and rear channels as well.
This commit is contained in:
Wim Taymans 2026-01-15 16:43:43 +01:00
parent c28a85ab34
commit 06e4772864
2 changed files with 129 additions and 36 deletions

View File

@ -156,41 +156,42 @@ enum spa_audio_channel {
SPA_AUDIO_CHANNEL_MONO, /**< mono stream */
SPA_AUDIO_CHANNEL_FL, /**< front left */
SPA_AUDIO_CHANNEL_FR, /**< front right */
SPA_AUDIO_CHANNEL_FC, /**< front center */
SPA_AUDIO_CHANNEL_LFE, /**< LFE */
SPA_AUDIO_CHANNEL_SL, /**< side left */
SPA_AUDIO_CHANNEL_SR, /**< side right */
SPA_AUDIO_CHANNEL_FLC, /**< front left center */
SPA_AUDIO_CHANNEL_FRC, /**< front right center */
SPA_AUDIO_CHANNEL_RC, /**< rear center */
SPA_AUDIO_CHANNEL_RL, /**< rear left */
SPA_AUDIO_CHANNEL_RR, /**< rear right */
SPA_AUDIO_CHANNEL_TC, /**< top center */
SPA_AUDIO_CHANNEL_TFL, /**< top front left */
SPA_AUDIO_CHANNEL_TFC, /**< top front center */
SPA_AUDIO_CHANNEL_TFR, /**< top front right */
SPA_AUDIO_CHANNEL_TRL, /**< top rear left */
SPA_AUDIO_CHANNEL_TRC, /**< top rear center */
SPA_AUDIO_CHANNEL_TRR, /**< top rear right */
SPA_AUDIO_CHANNEL_RLC, /**< rear left center */
SPA_AUDIO_CHANNEL_RRC, /**< rear right center */
SPA_AUDIO_CHANNEL_FLW, /**< front left wide */
SPA_AUDIO_CHANNEL_FRW, /**< front right wide */
SPA_AUDIO_CHANNEL_LFE2, /**< LFE 2 */
SPA_AUDIO_CHANNEL_FLH, /**< front left high */
SPA_AUDIO_CHANNEL_FCH, /**< front center high */
SPA_AUDIO_CHANNEL_FRH, /**< front right high */
SPA_AUDIO_CHANNEL_TFLC, /**< top front left center */
SPA_AUDIO_CHANNEL_TFRC, /**< top front right center */
SPA_AUDIO_CHANNEL_TSL, /**< top side left */
SPA_AUDIO_CHANNEL_TSR, /**< top side right */
SPA_AUDIO_CHANNEL_LLFE, /**< left LFE */
SPA_AUDIO_CHANNEL_RLFE, /**< right LFE */
SPA_AUDIO_CHANNEL_BC, /**< bottom center */
SPA_AUDIO_CHANNEL_BLC, /**< bottom left center */
SPA_AUDIO_CHANNEL_BRC, /**< bottom right center */
/** Azimuth Elevation */
SPA_AUDIO_CHANNEL_FL, /**< front left 30 0 */
SPA_AUDIO_CHANNEL_FR, /**< front right -30 0 */
SPA_AUDIO_CHANNEL_FC, /**< front center 0 0 */
SPA_AUDIO_CHANNEL_LFE, /**< LFE 0 -30 */
SPA_AUDIO_CHANNEL_SL, /**< side left 90 0 */
SPA_AUDIO_CHANNEL_SR, /**< side right -90 0 */
SPA_AUDIO_CHANNEL_FLC, /**< front left center 22.5 0 */
SPA_AUDIO_CHANNEL_FRC, /**< front right center -22.5 0 */
SPA_AUDIO_CHANNEL_RC, /**< rear center 180 0 */
SPA_AUDIO_CHANNEL_RL, /**< rear left 110 0 */
SPA_AUDIO_CHANNEL_RR, /**< rear right -110 0 */
SPA_AUDIO_CHANNEL_TC, /**< top center 0 90 */
SPA_AUDIO_CHANNEL_TFL, /**< top front left 30 30 */
SPA_AUDIO_CHANNEL_TFC, /**< top front center 0 30 */
SPA_AUDIO_CHANNEL_TFR, /**< top front right -30 30 */
SPA_AUDIO_CHANNEL_TRL, /**< top rear left 110 30 */
SPA_AUDIO_CHANNEL_TRC, /**< top rear center 180 30 */
SPA_AUDIO_CHANNEL_TRR, /**< top rear right -110 30 */
SPA_AUDIO_CHANNEL_RLC, /**< rear left center 135 0 */
SPA_AUDIO_CHANNEL_RRC, /**< rear right center -135 0 */
SPA_AUDIO_CHANNEL_FLW, /**< front left wide 60 0 */
SPA_AUDIO_CHANNEL_FRW, /**< front right wide -60 0 */
SPA_AUDIO_CHANNEL_LFE2, /**< LFE 2 0 -30 */
SPA_AUDIO_CHANNEL_FLH, /**< front left high 22.5 30 */
SPA_AUDIO_CHANNEL_FCH, /**< front center high 0 30 */
SPA_AUDIO_CHANNEL_FRH, /**< front right high -22.5 30 */
SPA_AUDIO_CHANNEL_TFLC, /**< top front left center 45 30 */
SPA_AUDIO_CHANNEL_TFRC, /**< top front right center -45 30 */
SPA_AUDIO_CHANNEL_TSL, /**< top side left 90 0 */
SPA_AUDIO_CHANNEL_TSR, /**< top side right -90 0 */
SPA_AUDIO_CHANNEL_LLFE, /**< left LFE 45 -30 */
SPA_AUDIO_CHANNEL_RLFE, /**< right LFE -45 -30 */
SPA_AUDIO_CHANNEL_BC, /**< bottom center 0 -30 */
SPA_AUDIO_CHANNEL_BLC, /**< bottom left center 45 -30 */
SPA_AUDIO_CHANNEL_BRC, /**< bottom right center -45 -30 */
SPA_AUDIO_CHANNEL_START_Aux = 0x1000, /**< aux channels */
SPA_AUDIO_CHANNEL_AUX0 = SPA_AUDIO_CHANNEL_START_Aux,

View File

@ -117,6 +117,7 @@ static const struct channelmix_info *find_channelmix_info(uint32_t src_chan, uin
#define SQRT3_2 1.224744871f /* sqrt(3/2) */
#define SQRT1_2 0.707106781f
#define SQRT2 1.414213562f
#define HALF 0.5f
#define MATRIX_NORMAL 0
#define MATRIX_DOLBY 1
@ -127,7 +128,11 @@ static const struct channelmix_info *find_channelmix_info(uint32_t src_chan, uin
#define _MASK(ch) (1ULL << _CH(ch))
#define FRONT (_MASK(FC))
#define STEREO (_MASK(FL)|_MASK(FR))
#define TSTEREO (_MASK(TFL)|_MASK(TFR))
#define TCSTEREO (_MASK(TFLC)|_MASK(TFRC))
#define REAR (_MASK(RL)|_MASK(RR))
#define TREAR (_MASK(TRL)|_MASK(TRR))
#define CREAR (_MASK(RLC)|_MASK(RRC))
#define SIDE (_MASK(SL)|_MASK(SR))
#define CHANNEL_BITS (64u)
@ -404,7 +409,7 @@ static int make_matrix(struct channelmix *mix)
}
normalize = true;
} else {
spa_log_warn(mix->log, "can't assign RL");
spa_log_warn(mix->log, "can't assign RL+RR");
}
}
@ -499,6 +504,93 @@ static int make_matrix(struct channelmix *mix)
spa_log_warn(mix->log, "can't assign LFE");
}
}
if (unassigned & TSTEREO){
if (dst_mask & STEREO) {
spa_log_info(mix->log, "assign TSTEREO to FL+FR (%f)", HALF);
_MATRIX(FL,TFL) += HALF;
_MATRIX(FR,TFR) += HALF;
} else if (dst_mask & _MASK(MONO)){
spa_log_info(mix->log, "assign TSTEREO to MONO (%f)", 1.0f);
for (i = 0; i < MAX_CHANNELS; i++) {
matrix[i][_CH(TFL)]= 1.0f;
matrix[i][_CH(TFR)]= 1.0f;
}
normalize = true;
} else {
spa_log_warn(mix->log, "can't assign TSTEREO");
}
}
if (unassigned & TCSTEREO){
if (dst_mask & STEREO) {
spa_log_info(mix->log, "assign TCSTEREO to FL+FR (%f)", HALF);
_MATRIX(FL,TFLC) += HALF;
_MATRIX(FR,TFRC) += HALF;
} else if (dst_mask & _MASK(MONO)){
spa_log_info(mix->log, "assign TCSTEREO to MONO (%f)", 1.0f);
for (i = 0; i < MAX_CHANNELS; i++) {
matrix[i][_CH(TFLC)]= 1.0f;
matrix[i][_CH(TFRC)]= 1.0f;
}
normalize = true;
} else {
spa_log_warn(mix->log, "can't assign TCSTEREO");
}
}
if (unassigned & TREAR){
if (dst_mask & REAR) {
if (src_mask & _MASK(RL)) {
spa_log_info(mix->log, "assign TREAR to RL+RR (%f)", HALF);
_MATRIX(RL,TRL) += HALF;
_MATRIX(RR,TRR) += HALF;
} else {
spa_log_info(mix->log, "assign TREAR to RL+RR (%f)", 1.0f);
_MATRIX(RL,TRL) += 1.0f;
_MATRIX(RR,TRR) += 1.0f;
}
keep &= ~REAR;
} else if (dst_mask & STEREO) {
spa_log_info(mix->log, "assign TREAR to FL+FR (%f)", HALF);
_MATRIX(FL,TRL) += HALF;
_MATRIX(FR,TRR) += HALF;
} else if (dst_mask & _MASK(MONO)){
spa_log_info(mix->log, "assign TREAR to MONO (%f)", 1.0f);
for (i = 0; i < MAX_CHANNELS; i++) {
matrix[i][_CH(TRL)]= 1.0f;
matrix[i][_CH(TRR)]= 1.0f;
}
normalize = true;
} else {
spa_log_warn(mix->log, "can't assign TREAR");
}
}
if (unassigned & CREAR){
if (dst_mask & REAR) {
if (src_mask & _MASK(RL)) {
spa_log_info(mix->log, "assign CREAR to RL+RR (%f)", SQRT1_2);
_MATRIX(RL,RLC) += SQRT1_2;
_MATRIX(RR,RRC) += SQRT1_2;
} else {
spa_log_info(mix->log, "assign CREAR to RL+RR (%f)", 1.0f);
_MATRIX(RL,RLC) += 1.0f;
_MATRIX(RR,RRC) += 1.0f;
}
keep &= ~REAR;
} else if (dst_mask & STEREO) {
spa_log_info(mix->log, "assign CREAR to FL+FR (%f)",
SQRT1_2);
_MATRIX(FL,RLC) += SQRT1_2;
_MATRIX(FR,RRC) += SQRT1_2;
} else if (dst_mask & _MASK(MONO)){
spa_log_info(mix->log, "assign CREAR to MONO (%f)", 1.0f);
for (i = 0; i < MAX_CHANNELS; i++) {
matrix[i][_CH(RLC)]= 1.0f;
matrix[i][_CH(RRC)]= 1.0f;
}
normalize = true;
} else {
spa_log_warn(mix->log, "can't assign CREAR");
}
}
unassigned = dst_mask & ~src_mask & keep;