summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wtaymans@redhat.com>2020-09-04 13:41:24 +0200
committerWim Taymans <wtaymans@redhat.com>2020-09-04 13:41:24 +0200
commit9a7cbeea831062ed0b110f31173213596afc011f (patch)
treea2682bd4b8e7c22ef7005ab4b242e2655ff08264
parent6f4f9e5abb5f7c53dc9d6231e0e7283a2bad6f2e (diff)
channelmix: improve undefined channel layout
When we have no channel layout, just copy input to output channel. Optimize this case in the mixer implementation.
-rw-r--r--spa/plugins/audioconvert/channelmix-ops-c.c25
-rw-r--r--spa/plugins/audioconvert/channelmix-ops.c19
-rw-r--r--spa/plugins/audioconvert/channelmix-ops.h1
3 files changed, 35 insertions, 10 deletions
diff --git a/spa/plugins/audioconvert/channelmix-ops-c.c b/spa/plugins/audioconvert/channelmix-ops-c.c
index 710ed384..f839cbdd 100644
--- a/spa/plugins/audioconvert/channelmix-ops-c.c
+++ b/spa/plugins/audioconvert/channelmix-ops-c.c
@@ -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;
+ }
}
}
}
diff --git a/spa/plugins/audioconvert/channelmix-ops.c b/spa/plugins/audioconvert/channelmix-ops.c
index 24c03817..384f08ed 100644
--- a/spa/plugins/audioconvert/channelmix-ops.c
+++ b/spa/plugins/audioconvert/channelmix-ops.c
@@ -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);
}
diff --git a/spa/plugins/audioconvert/channelmix-ops.h b/spa/plugins/audioconvert/channelmix-ops.h
index 1f967450..4aac0554 100644
--- a/spa/plugins/audioconvert/channelmix-ops.h
+++ b/spa/plugins/audioconvert/channelmix-ops.h
@@ -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];