mirror of
https://gitlab.freedesktop.org/pipewire/pipewire
synced 2024-09-06 16:56:00 +00:00
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:
parent
6f4f9e5abb
commit
9a7cbeea83
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
Loading…
Reference in a new issue