diff options
author | Wim Taymans <wtaymans@redhat.com> | 2020-09-04 13:41:24 +0200 |
---|---|---|
committer | Wim Taymans <wtaymans@redhat.com> | 2020-09-04 13:41:24 +0200 |
commit | 9a7cbeea831062ed0b110f31173213596afc011f (patch) | |
tree | a2682bd4b8e7c22ef7005ab4b242e2655ff08264 | |
parent | 6f4f9e5abb5f7c53dc9d6231e0e7283a2bad6f2e (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.c | 25 | ||||
-rw-r--r-- | spa/plugins/audioconvert/channelmix-ops.c | 19 | ||||
-rw-r--r-- | spa/plugins/audioconvert/channelmix-ops.h | 1 |
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]; |