diff --git a/spa/plugins/audioconvert/channelmix-ops-sse.c b/spa/plugins/audioconvert/channelmix-ops-sse.c index 43a9af54a..ccc9e3a72 100644 --- a/spa/plugins/audioconvert/channelmix-ops-sse.c +++ b/spa/plugins/audioconvert/channelmix-ops-sse.c @@ -21,13 +21,11 @@ static void channelmix_copy_sse(void *data, int n_dst, void *dst[n_dst], - int n_src, const void *src[n_src], void *matrix, int n_bytes) + int n_src, const void *src[n_src], void *matrix, float v, int n_bytes) { int i, n, n_samples = n_bytes / sizeof(float), unrolled, remain; float **d = (float **)dst; float **s = (float **)src; - float *m = matrix; - float v = m[0]; __m128 vol = _mm_set1_ps(v); if (v <= VOLUME_MIN) { @@ -55,13 +53,11 @@ channelmix_copy_sse(void *data, int n_dst, void *dst[n_dst], static void channelmix_f32_2_4_sse(void *data, int n_dst, void *dst[n_dst], - int n_src, const void *src[n_src], void *matrix, int n_bytes) + int n_src, const void *src[n_src], void *matrix, float v, int n_bytes) { int i, n, n_samples = n_bytes / sizeof(float), unrolled, remain; float **d = (float **)dst; float **s = (float **)src; - float *m = matrix; - float v = m[0]; __m128 vol = _mm_set1_ps(v); __m128 in; float *dFL = d[0], *dFR = d[1], *dRL = d[2], *dRR = d[3]; @@ -118,13 +114,12 @@ channelmix_f32_2_4_sse(void *data, int n_dst, void *dst[n_dst], /* FL+FR+FC+LFE+SL+SR -> FL+FR */ static void channelmix_f32_5p1_2_sse(void *data, int n_dst, void *dst[n_dst], - int n_src, const void *src[n_src], void *matrix, int n_bytes) + int n_src, const void *src[n_src], void *matrix, float v, int n_bytes) { int n, n_samples = n_bytes / sizeof(float), unrolled, remain; float **d = (float **) dst; float **s = (float **) src; float *m = matrix; - float v = m[0]; __m128 clev = _mm_set1_ps(m[2]); __m128 llev = _mm_set1_ps(m[3]); __m128 slev = _mm_set1_ps(m[4]); @@ -205,13 +200,12 @@ channelmix_f32_5p1_2_sse(void *data, int n_dst, void *dst[n_dst], /* FL+FR+FC+LFE+SL+SR -> FL+FR+RL+RR*/ static void channelmix_f32_5p1_4_sse(void *data, int n_dst, void *dst[n_dst], - int n_src, const void *src[n_src], void *matrix, int n_bytes) + int n_src, const void *src[n_src], void *matrix, float v, int n_bytes) { int i, n, n_samples = n_bytes / sizeof(float), unrolled, remain; float **d = (float **) dst; float **s = (float **) src; float *m = matrix; - float v = m[0]; __m128 clev = _mm_set1_ps(m[2]); __m128 llev = _mm_set1_ps(m[3]); __m128 vol = _mm_set1_ps(v); diff --git a/spa/plugins/audioconvert/channelmix-ops.c b/spa/plugins/audioconvert/channelmix-ops.c index 1e47823f3..1be5bfdd8 100644 --- a/spa/plugins/audioconvert/channelmix-ops.c +++ b/spa/plugins/audioconvert/channelmix-ops.c @@ -31,13 +31,11 @@ static void channelmix_copy(void *data, int n_dst, void *dst[n_dst], - int n_src, const void *src[n_src], void *matrix, int n_bytes) + int n_src, const void *src[n_src], void *matrix, float v, int n_bytes) { int i, n, n_samples = n_bytes / sizeof(float); float **d = (float **)dst; float **s = (float **)src; - float *m = matrix; - float v = m[0]; if (v <= VOLUME_MIN) { for (i = 0; i < n_dst; i++) @@ -58,7 +56,7 @@ channelmix_copy(void *data, int n_dst, void *dst[n_dst], static void channelmix_f32_n_m(void *data, int n_dst, void *dst[n_dst], - int n_src, const void *src[n_src], void *matrix, int n_bytes) + int n_src, const void *src[n_src], void *matrix, float v, int n_bytes) { int i, j, n, n_samples = n_bytes / sizeof(float); float **d = (float **) dst; @@ -69,7 +67,7 @@ channelmix_f32_n_m(void *data, int n_dst, void *dst[n_dst], for (i = 0; i < n_dst; i++) { float sum = 0.0f; for (j = 0; j < n_src; j++) - sum += s[j][n] * m[i * n_src + j]; + sum += s[j][n] * m[i * n_src + j] * v; d[i][n] = sum; } } @@ -80,13 +78,11 @@ channelmix_f32_n_m(void *data, int n_dst, void *dst[n_dst], static void channelmix_f32_1_2(void *data, int n_dst, void *dst[n_dst], - int n_src, const void *src[n_src], void *matrix, int n_bytes) + int n_src, const void *src[n_src], void *matrix, float v, int n_bytes) { int n, n_samples = n_bytes / sizeof(float); float **d = (float **)dst; float **s = (float **)src; - float *m = matrix; - float v = m[0]; if (v <= VOLUME_MIN) { memset(d[0], 0, n_bytes); @@ -104,13 +100,11 @@ channelmix_f32_1_2(void *data, int n_dst, void *dst[n_dst], static void channelmix_f32_2_1(void *data, int n_dst, void *dst[n_dst], - int n_src, const void *src[n_src], void *matrix, int n_bytes) + int n_src, const void *src[n_src], void *matrix, float v, int n_bytes) { int n, n_samples = n_bytes / sizeof(float); float **d = (float **)dst; float **s = (float **)src; - float *m = matrix; - float v = m[0]; if (v <= VOLUME_MIN) { memset(d[0], 0, n_bytes); @@ -127,13 +121,11 @@ channelmix_f32_2_1(void *data, int n_dst, void *dst[n_dst], static void channelmix_f32_2_4(void *data, int n_dst, void *dst[n_dst], - int n_src, const void *src[n_src], void *matrix, int n_bytes) + int n_src, const void *src[n_src], void *matrix, float v, int n_bytes) { int i, n, n_samples = n_bytes / sizeof(float); float **d = (float **)dst; float **s = (float **)src; - float *m = matrix; - float v = m[0]; if (v <= VOLUME_MIN) { for (i = 0; i < n_dst; i++) @@ -156,13 +148,11 @@ channelmix_f32_2_4(void *data, int n_dst, void *dst[n_dst], #define MASK_3_1 _M(FL)|_M(FR)|_M(FC)|_M(LFE) static void channelmix_f32_2_3p1(void *data, int n_dst, void *dst[n_dst], - int n_src, const void *src[n_src], void *matrix, int n_bytes) + int n_src, const void *src[n_src], void *matrix, float v, int n_bytes) { int i, n, n_samples = n_bytes / sizeof(float); float **d = (float **)dst; float **s = (float **)src; - float *m = matrix; - float v = m[0]; if (v <= VOLUME_MIN) { for (i = 0; i < n_dst; i++) @@ -190,13 +180,11 @@ channelmix_f32_2_3p1(void *data, int n_dst, void *dst[n_dst], #define MASK_5_1 _M(FL)|_M(FR)|_M(FC)|_M(LFE)|_M(SL)|_M(SR)|_M(RL)|_M(RR) static void channelmix_f32_2_5p1(void *data, int n_dst, void *dst[n_dst], - int n_src, const void *src[n_src], void *matrix, int n_bytes) + int n_src, const void *src[n_src], void *matrix, float v, int n_bytes) { int i, n, n_samples = n_bytes / sizeof(float); float **d = (float **)dst; float **s = (float **)src; - float *m = matrix; - float v = m[0]; if (v <= VOLUME_MIN) { for (i = 0; i < n_dst; i++) @@ -224,13 +212,12 @@ channelmix_f32_2_5p1(void *data, int n_dst, void *dst[n_dst], /* FL+FR+FC+LFE+SL+SR -> FL+FR */ static void channelmix_f32_5p1_2(void *data, int n_dst, void *dst[n_dst], - int n_src, const void *src[n_src], void *matrix, int n_bytes) + int n_src, const void *src[n_src], void *matrix, float v, int n_bytes) { int n, n_samples = n_bytes / sizeof(float); float **d = (float **) dst; float **s = (float **) src; float *m = matrix; - float v = m[0]; const float clev = m[2]; const float llev = m[3]; const float slev = m[4]; @@ -258,13 +245,11 @@ channelmix_f32_5p1_2(void *data, int n_dst, void *dst[n_dst], /* FL+FR+FC+LFE+SL+SR -> FL+FR+FC+LFE*/ static void channelmix_f32_5p1_3p1(void *data, int n_dst, void *dst[n_dst], - int n_src, const void *src[n_src], void *matrix, int n_bytes) + int n_src, const void *src[n_src], void *matrix, float v, int n_bytes) { int i, n, n_samples; float **d = (float **) dst; float **s = (float **) src; - float *m = matrix; - float v = m[0]; n_samples = n_bytes / sizeof(float); if (v <= VOLUME_MIN) { @@ -285,13 +270,12 @@ channelmix_f32_5p1_3p1(void *data, int n_dst, void *dst[n_dst], /* FL+FR+FC+LFE+SL+SR -> FL+FR+RL+RR*/ static void channelmix_f32_5p1_4(void *data, int n_dst, void *dst[n_dst], - int n_src, const void *src[n_src], void *matrix, int n_bytes) + int n_src, const void *src[n_src], void *matrix, float v, int n_bytes) { int i, n, n_samples; float **d = (float **) dst; float **s = (float **) src; float *m = matrix; - float v = m[0]; const float clev = m[2]; const float llev = m[3]; @@ -325,13 +309,12 @@ channelmix_f32_5p1_4(void *data, int n_dst, void *dst[n_dst], /* FL+FR+FC+LFE+SL+SR+RL+RR -> FL+FR */ static void channelmix_f32_7p1_2(void *data, int n_dst, void *dst[n_dst], - int n_src, const void *src[n_src], void *matrix, int n_bytes) + int n_src, const void *src[n_src], void *matrix, float v, int n_bytes) { int n, n_samples = n_bytes / sizeof(float); float **d = (float **) dst; float **s = (float **) src; float *m = matrix; - float v = m[0]; const float clev = m[2]; const float llev = m[3]; const float slev = m[4]; @@ -359,13 +342,11 @@ channelmix_f32_7p1_2(void *data, int n_dst, void *dst[n_dst], /* FL+FR+FC+LFE+SL+SR+RL+RR -> FL+FR+FC+LFE*/ static void channelmix_f32_7p1_3p1(void *data, int n_dst, void *dst[n_dst], - int n_src, const void *src[n_src], void *matrix, int n_bytes) + int n_src, const void *src[n_src], void *matrix, float v, int n_bytes) { int i, n, n_samples; float **d = (float **) dst; float **s = (float **) src; - float *m = matrix; - float v = m[0]; n_samples = n_bytes / sizeof(float); if (v <= VOLUME_MIN) { @@ -386,13 +367,12 @@ channelmix_f32_7p1_3p1(void *data, int n_dst, void *dst[n_dst], /* FL+FR+FC+LFE+SL+SR+RL+RR -> FL+FR+RL+RR*/ static void channelmix_f32_7p1_4(void *data, int n_dst, void *dst[n_dst], - int n_src, const void *src[n_src], void *matrix, int n_bytes) + int n_src, const void *src[n_src], void *matrix, float v, int n_bytes) { int i, n, n_samples; float **d = (float **) dst; float **s = (float **) src; float *m = matrix; - float v = m[0]; const float clev = m[2]; const float llev = m[3]; const float slev = m[4]; @@ -428,7 +408,7 @@ channelmix_f32_7p1_4(void *data, int n_dst, void *dst[n_dst], typedef void (*channelmix_func_t) (void *data, int n_dst, void *dst[n_dst], int n_src, const void *src[n_src], - void *matrix, int n_bytes); + void *matrix, float v, int n_bytes); static const struct channelmix_info { diff --git a/spa/plugins/audioconvert/channelmix.c b/spa/plugins/audioconvert/channelmix.c index cf287eca2..1da591bd2 100644 --- a/spa/plugins/audioconvert/channelmix.c +++ b/spa/plugins/audioconvert/channelmix.c @@ -41,14 +41,17 @@ struct impl; +#define DEFAULT_MUTE false #define DEFAULT_VOLUME 1.0 struct props { float volume; + bool mute; }; static void props_reset(struct props *props) { + props->mute = DEFAULT_MUTE; props->volume = DEFAULT_VOLUME; } @@ -98,6 +101,7 @@ struct impl { bool started; channelmix_func_t convert; + uint32_t n_matrix; float matrix[4096]; }; @@ -340,6 +344,7 @@ static int make_matrix(struct impl *this, } max = SPA_MAX(max, sum); } + this->n_matrix = c; for (i = 0; i < dst_chan; i++) { for (j = 0; j < src_chan; j++) { spa_log_debug(this->log, "%d %d: %f", i, j, this->matrix[i * src_chan + j]); @@ -412,10 +417,47 @@ static int impl_node_enum_params(struct spa_node *node, return -ENOTSUP; } +static int apply_props(struct impl *this, const struct spa_pod *param) +{ + struct spa_pod_prop *prop; + struct spa_pod_object *obj = (struct spa_pod_object *) param; + struct props *p = &this->props; + + SPA_POD_OBJECT_FOREACH(obj, prop) { + float volume; + bool mute; + switch (prop->key) { + case SPA_PROP_volume: + volume = SPA_POD_VALUE(struct spa_pod_float, &prop->value); + p->volume = volume; + break; + case SPA_PROP_mute: + mute = SPA_POD_VALUE(struct spa_pod_bool, &prop->value); + p->mute = mute; + break; + default: + break; + } + } + return 0; +} + static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flags, const struct spa_pod *param) { - return -ENOTSUP; + struct impl *this; + + spa_return_val_if_fail(node != NULL, -EINVAL); + + this = SPA_CONTAINER_OF(node, struct impl, node); + + switch (id) { + case SPA_PARAM_Props: + return apply_props(this, param); + default: + return -ENOENT; + } + return 0; } static int impl_node_send_command(struct spa_node *node, const struct spa_command *command) @@ -941,26 +983,8 @@ static int process_control(struct impl *this, struct port *port, struct spa_pod_ SPA_POD_SEQUENCE_FOREACH(sequence, c) { switch (c->type) { case SPA_CONTROL_Properties: - { - struct props *p = &this->props; - float volume = p->volume; - struct spa_pod_prop *prop; - struct spa_pod_object *obj = (struct spa_pod_object *) &c->value; - - SPA_POD_OBJECT_FOREACH(obj, prop) { - switch (prop->key) { - case SPA_PROP_volume: - volume = SPA_POD_VALUE(struct spa_pod_float, &prop->value); - if (volume != p->volume) - this->matrix[0] = p->volume = volume; - break; - default: - break; - } - } - + apply_props(this, (const struct spa_pod *) &c->value); break; - } default: break; } @@ -1033,7 +1057,8 @@ static int impl_node_process(struct spa_node *node) this->convert(this, n_dst_datas, dst_datas, n_src_datas, src_datas, - this->matrix, n_bytes); + this->matrix, this->props.mute ? 0.0 : this->props.volume, + n_bytes); } outio->status = SPA_STATUS_HAVE_BUFFER;