channelmix: improve undefined channel layout

When we have no channel layout, just copy input to output
channel.
Optimize this case in the mixer implementation.
This commit is contained in:
Wim Taymans 2020-09-04 13:41:24 +02:00
parent 6f4f9e5abb
commit 9a7cbeea83
3 changed files with 35 additions and 10 deletions

View file

@ -58,12 +58,25 @@ channelmix_f32_n_m_c(struct channelmix *mix, uint32_t n_dst, void * SPA_RESTRICT
float **d = (float **) dst;
const float **s = (const float **) src;
for (n = 0; n < n_samples; n++) {
for (i = 0; i < n_dst; i++) {
float sum = 0.0f;
for (j = 0; j < n_src; j++)
sum += s[j][n] * mix->matrix[i][j];
d[i][n] = sum;
if (SPA_FLAG_IS_SET(mix->flags, CHANNELMIX_FLAG_ZERO)) {
for (i = 0; i < n_dst; i++)
memset(d[i], 0, n_samples * sizeof(float));
}
else if (SPA_FLAG_IS_SET(mix->flags, CHANNELMIX_FLAG_COPY)) {
uint32_t copy = SPA_MIN(n_dst, n_src);
for (i = 0; i < copy; i++)
spa_memcpy(d[i], s[i], n_samples * sizeof(float));
for (; i < n_dst; i++)
memset(d[i], 0, n_samples * sizeof(float));
}
else {
for (n = 0; n < n_samples; n++) {
for (i = 0; i < n_dst; i++) {
float sum = 0.0f;
for (j = 0; j < n_src; j++)
sum += s[j][n] * mix->matrix[i][j];
d[i][n] = sum;
}
}
}
}

View file

@ -175,9 +175,16 @@ static int make_matrix(struct channelmix *mix)
if ((dst_mask & _MASK(MONO)) == _MASK(MONO))
dst_mask = _MASK(FC);
for (i = 0; i < NUM_CHAN; i++) {
if (src_mask & dst_mask & (1ULL << (i + 2)))
if (src_mask == 0 || dst_mask == 0) {
src_mask = dst_mask = ~0LU;
for (i = 0; i < NUM_CHAN; i++)
matrix[i][i]= 1.0f;
goto done;
} else {
for (i = 0; i < NUM_CHAN; i++) {
if ((src_mask & dst_mask & (1ULL << (i + 2))))
matrix[i][i]= 1.0f;
}
}
unassigned = src_mask & ~dst_mask;
@ -329,6 +336,7 @@ static int make_matrix(struct channelmix *mix)
spa_log_warn(mix->log, "can't assign LFE");
}
}
done:
for (ic = 0, i = 0; i < NUM_CHAN; i++) {
float sum = 0.0f;
if ((dst_mask & (1UL << (i + 2))) == 0)
@ -377,7 +385,7 @@ static void impl_channelmix_set_volume(struct channelmix *mix, float volume, boo
SPA_FLAG_SET(mix->flags, CHANNELMIX_FLAG_ZERO);
SPA_FLAG_SET(mix->flags, CHANNELMIX_FLAG_EQUAL);
SPA_FLAG_UPDATE(mix->flags, CHANNELMIX_FLAG_IDENTITY, dst_chan == src_chan);
SPA_FLAG_SET(mix->flags, CHANNELMIX_FLAG_COPY);
t = 0.0;
for (i = 0; i < dst_chan; i++) {
@ -392,9 +400,12 @@ static void impl_channelmix_set_volume(struct channelmix *mix, float volume, boo
SPA_FLAG_CLEAR(mix->flags, CHANNELMIX_FLAG_ZERO);
if ((i == j && v != 1.0f) ||
(i != j && v != 0.0f))
SPA_FLAG_CLEAR(mix->flags, CHANNELMIX_FLAG_IDENTITY);
SPA_FLAG_CLEAR(mix->flags, CHANNELMIX_FLAG_COPY);
}
}
SPA_FLAG_UPDATE(mix->flags, CHANNELMIX_FLAG_IDENTITY,
dst_chan == src_chan && SPA_FLAG_IS_SET(mix->flags, CHANNELMIX_FLAG_COPY));
spa_log_debug(mix->log, "flags:%08x", mix->flags);
}

View file

@ -54,6 +54,7 @@ struct channelmix {
#define CHANNELMIX_FLAG_ZERO (1<<0) /**< all zero components */
#define CHANNELMIX_FLAG_IDENTITY (1<<1) /**< identity matrix */
#define CHANNELMIX_FLAG_EQUAL (1<<2) /**< all values are equal */
#define CHANNELMIX_FLAG_COPY (1<<3) /**< 1 on diagonal, can be nxm */
uint32_t flags;
float matrix_orig[SPA_AUDIO_MAX_CHANNELS][SPA_AUDIO_MAX_CHANNELS];
float matrix[SPA_AUDIO_MAX_CHANNELS][SPA_AUDIO_MAX_CHANNELS];