diff --git a/spa/plugins/audioconvert/channelmix-ops-avx.c b/spa/plugins/audioconvert/channelmix-ops-avx.c index 08d8e2b00..f5b84821d 100644 --- a/spa/plugins/audioconvert/channelmix-ops-avx.c +++ b/spa/plugins/audioconvert/channelmix-ops-avx.c @@ -55,9 +55,10 @@ static inline void vol_avx(float *d, const float *s, float vol, uint32_t n_sampl void channelmix_copy_avx(struct channelmix *mix, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], uint32_t n_samples) { + CHANNELMIX_DEF_MATRIX(matrix, mix, matrix); uint32_t i, n_dst = mix->dst_chan; float **d = (float **)dst; const float **s = (const float **)src; for (i = 0; i < n_dst; i++) - vol_avx(d[i], s[i], mix->matrix[i][i], n_samples); + vol_avx(d[i], s[i], matrix[i][i], n_samples); } diff --git a/spa/plugins/audioconvert/channelmix-ops-c.c b/spa/plugins/audioconvert/channelmix-ops-c.c index 6e0113b5e..c8d079de6 100644 --- a/spa/plugins/audioconvert/channelmix-ops-c.c +++ b/spa/plugins/audioconvert/channelmix-ops-c.c @@ -59,11 +59,12 @@ void channelmix_copy_c(struct channelmix *mix, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], uint32_t n_samples) { + CHANNELMIX_DEF_MATRIX(matrix, mix, matrix); uint32_t i, n_dst = mix->dst_chan; float **d = (float **)dst; const float **s = (const float **)src; for (i = 0; i < n_dst; i++) - vol_c(d[i], s[i], mix->matrix[i][i], n_samples); + vol_c(d[i], s[i], matrix[i][i], n_samples); } static void lr4_process_c(struct lr4 *lr4, float *dst, const float *src, const float vol, int samples) @@ -139,6 +140,7 @@ void channelmix_f32_n_m_c(struct channelmix *mix, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], uint32_t n_samples) { + CHANNELMIX_DEF_MATRIX(matrix, mix, matrix); uint32_t i, j, n_dst = mix->dst_chan, n_src = mix->src_chan; float **d = (float **) dst; const float **s = (const float **) src; @@ -162,9 +164,9 @@ channelmix_f32_n_m_c(struct channelmix *mix, void * SPA_RESTRICT dst[], uint32_t n_j = 0; for (j = 0; j < n_src; j++) { - if (mix->matrix[i][j] == 0.0f) + if (matrix[i][j] == 0.0f) continue; - mj[n_j] = mix->matrix[i][j]; + mj[n_j] = matrix[i][j]; sj[n_j++] = s[j]; } if (n_j == 0) { @@ -186,10 +188,11 @@ void channelmix_f32_1_2_c(struct channelmix *mix, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], uint32_t n_samples) { + CHANNELMIX_DEF_MATRIX(matrix, mix, matrix); float **d = (float **)dst; const float **s = (const float **)src; - const float v0 = mix->matrix[0][0]; - const float v1 = mix->matrix[1][0]; + const float v0 = matrix[0][0]; + const float v1 = matrix[1][0]; vol_c(d[0], s[0], v0, n_samples); vol_c(d[1], s[0], v1, n_samples); @@ -199,11 +202,12 @@ void channelmix_f32_2_1_c(struct channelmix *mix, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], uint32_t n_samples) { + CHANNELMIX_DEF_MATRIX(matrix, mix, matrix); uint32_t n; float **d = (float **)dst; const float **s = (const float **)src; - const float v0 = mix->matrix[0][0]; - const float v1 = mix->matrix[0][1]; + const float v0 = matrix[0][0]; + const float v1 = matrix[0][1]; if (SPA_FLAG_IS_SET(mix->flags, CHANNELMIX_FLAG_ZERO)) { clear_c(d[0], n_samples); @@ -221,13 +225,14 @@ void channelmix_f32_4_1_c(struct channelmix *mix, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], uint32_t n_samples) { + CHANNELMIX_DEF_MATRIX(matrix, mix, matrix); uint32_t n; float **d = (float **)dst; const float **s = (const float **)src; - const float v0 = mix->matrix[0][0]; - const float v1 = mix->matrix[0][1]; - const float v2 = mix->matrix[0][2]; - const float v3 = mix->matrix[0][3]; + const float v0 = matrix[0][0]; + const float v1 = matrix[0][1]; + const float v2 = matrix[0][2]; + const float v3 = matrix[0][3]; if (SPA_FLAG_IS_SET(mix->flags, CHANNELMIX_FLAG_ZERO)) { clear_c(d[0], n_samples); @@ -249,13 +254,14 @@ void channelmix_f32_2_4_c(struct channelmix *mix, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], uint32_t n_samples) { + CHANNELMIX_DEF_MATRIX(matrix, mix, matrix); uint32_t i, n_dst = mix->dst_chan; float **d = (float **)dst; const float **s = (const float **)src; - const float v0 = mix->matrix[0][0]; - const float v1 = mix->matrix[1][1]; - const float v2 = mix->matrix[2][0]; - const float v3 = mix->matrix[3][1]; + const float v0 = matrix[0][0]; + const float v1 = matrix[1][1]; + const float v2 = matrix[2][0]; + const float v3 = matrix[3][1]; if (SPA_FLAG_IS_SET(mix->flags, CHANNELMIX_FLAG_ZERO)) { for (i = 0; i < n_dst; i++) @@ -283,13 +289,14 @@ void channelmix_f32_2_3p1_c(struct channelmix *mix, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], uint32_t n_samples) { + CHANNELMIX_DEF_MATRIX(matrix, mix, matrix); uint32_t i, n, n_dst = mix->dst_chan; float **d = (float **)dst; const float **s = (const float **)src; - const float v0 = mix->matrix[0][0]; - const float v1 = mix->matrix[1][1]; - const float v2 = (mix->matrix[2][0] + mix->matrix[2][1]) * 0.5f; - const float v3 = (mix->matrix[3][0] + mix->matrix[3][1]) * 0.5f; + const float v0 = matrix[0][0]; + const float v1 = matrix[1][1]; + const float v2 = (matrix[2][0] + matrix[2][1]) * 0.5f; + const float v3 = (matrix[3][0] + matrix[3][1]) * 0.5f; if (SPA_FLAG_IS_SET(mix->flags, CHANNELMIX_FLAG_ZERO)) { for (i = 0; i < n_dst; i++) @@ -319,11 +326,12 @@ void channelmix_f32_2_5p1_c(struct channelmix *mix, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], uint32_t n_samples) { + CHANNELMIX_DEF_MATRIX(matrix, mix, matrix); uint32_t i, n_dst = mix->dst_chan; float **d = (float **)dst; const float **s = (const float **)src; - const float v4 = mix->matrix[4][0]; - const float v5 = mix->matrix[5][1]; + const float v4 = matrix[4][0]; + const float v5 = matrix[5][1]; if (SPA_FLAG_IS_SET(mix->flags, CHANNELMIX_FLAG_ZERO)) { for (i = 0; i < n_dst; i++) @@ -350,13 +358,14 @@ void channelmix_f32_2_7p1_c(struct channelmix *mix, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], uint32_t n_samples) { + CHANNELMIX_DEF_MATRIX(matrix, mix, matrix); uint32_t i, n_dst = mix->dst_chan; float **d = (float **)dst; const float **s = (const float **)src; - const float v4 = mix->matrix[4][0]; - const float v5 = mix->matrix[5][1]; - const float v6 = mix->matrix[6][0]; - const float v7 = mix->matrix[7][1]; + const float v4 = matrix[4][0]; + const float v5 = matrix[5][1]; + const float v6 = matrix[6][0]; + const float v7 = matrix[7][1]; if (SPA_FLAG_IS_SET(mix->flags, CHANNELMIX_FLAG_ZERO)) { for (i = 0; i < n_dst; i++) @@ -387,13 +396,14 @@ void channelmix_f32_3p1_2_c(struct channelmix *mix, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], uint32_t n_samples) { + CHANNELMIX_DEF_MATRIX(matrix, mix, matrix); uint32_t n; float **d = (float **) dst; const float **s = (const float **) src; - const float v0 = mix->matrix[0][0]; - const float v1 = mix->matrix[1][1]; - const float clev = (mix->matrix[0][2] + mix->matrix[1][2]) * 0.5f; - const float llev = (mix->matrix[0][3] + mix->matrix[1][3]) * 0.5f; + const float v0 = matrix[0][0]; + const float v1 = matrix[1][1]; + const float clev = (matrix[0][2] + matrix[1][2]) * 0.5f; + const float llev = (matrix[0][3] + matrix[1][3]) * 0.5f; if (SPA_FLAG_IS_SET(mix->flags, CHANNELMIX_FLAG_ZERO)) { clear_c(d[0], n_samples); @@ -413,15 +423,16 @@ void channelmix_f32_5p1_2_c(struct channelmix *mix, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], uint32_t n_samples) { + CHANNELMIX_DEF_MATRIX(matrix, mix, matrix); uint32_t n; float **d = (float **) dst; const float **s = (const float **) src; - const float v0 = mix->matrix[0][0]; - const float v1 = mix->matrix[1][1]; - const float clev = (mix->matrix[0][2] + mix->matrix[1][2]) * 0.5f; - const float llev = (mix->matrix[0][3] + mix->matrix[1][3]) * 0.5f; - const float slev0 = mix->matrix[0][4]; - const float slev1 = mix->matrix[1][5]; + const float v0 = matrix[0][0]; + const float v1 = matrix[1][1]; + const float clev = (matrix[0][2] + matrix[1][2]) * 0.5f; + const float llev = (matrix[0][3] + matrix[1][3]) * 0.5f; + const float slev0 = matrix[0][4]; + const float slev1 = matrix[1][5]; if (SPA_FLAG_IS_SET(mix->flags, CHANNELMIX_FLAG_ZERO)) { clear_c(d[0], n_samples); @@ -441,15 +452,16 @@ void channelmix_f32_5p1_3p1_c(struct channelmix *mix, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], uint32_t n_samples) { + CHANNELMIX_DEF_MATRIX(matrix, mix, matrix); uint32_t i, n, n_dst = mix->dst_chan; float **d = (float **) dst; const float **s = (const float **) src; - const float v0 = mix->matrix[0][0]; - const float v1 = mix->matrix[1][1]; - const float v2 = mix->matrix[2][2]; - const float v3 = mix->matrix[3][3]; - const float v4 = mix->matrix[0][4]; - const float v5 = mix->matrix[1][5]; + const float v0 = matrix[0][0]; + const float v1 = matrix[1][1]; + const float v2 = matrix[2][2]; + const float v3 = matrix[3][3]; + const float v4 = matrix[0][4]; + const float v5 = matrix[1][5]; if (SPA_FLAG_IS_SET(mix->flags, CHANNELMIX_FLAG_ZERO)) { for (i = 0; i < n_dst; i++) @@ -470,11 +482,12 @@ void channelmix_f32_5p1_4_c(struct channelmix *mix, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], uint32_t n_samples) { + CHANNELMIX_DEF_MATRIX(matrix, mix, matrix); uint32_t i, n_dst = mix->dst_chan; float **d = (float **) dst; const float **s = (const float **) src; - const float v4 = mix->matrix[2][4]; - const float v5 = mix->matrix[3][5]; + const float v4 = matrix[2][4]; + const float v5 = matrix[3][5]; if (SPA_FLAG_IS_SET(mix->flags, CHANNELMIX_FLAG_ZERO)) { for (i = 0; i < n_dst; i++) @@ -495,17 +508,18 @@ void channelmix_f32_7p1_2_c(struct channelmix *mix, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], uint32_t n_samples) { + CHANNELMIX_DEF_MATRIX(matrix, mix, matrix); uint32_t n; float **d = (float **) dst; const float **s = (const float **) src; - const float v0 = mix->matrix[0][0]; - const float v1 = mix->matrix[1][1]; - const float clev = (mix->matrix[0][2] + mix->matrix[1][2]) * 0.5f; - const float llev = (mix->matrix[0][3] + mix->matrix[1][3]) * 0.5f; - const float slev0 = mix->matrix[0][4]; - const float slev1 = mix->matrix[1][5]; - const float rlev0 = mix->matrix[0][6]; - const float rlev1 = mix->matrix[1][7]; + const float v0 = matrix[0][0]; + const float v1 = matrix[1][1]; + const float clev = (matrix[0][2] + matrix[1][2]) * 0.5f; + const float llev = (matrix[0][3] + matrix[1][3]) * 0.5f; + const float slev0 = matrix[0][4]; + const float slev1 = matrix[1][5]; + const float rlev0 = matrix[0][6]; + const float rlev1 = matrix[1][7]; if (SPA_FLAG_IS_SET(mix->flags, CHANNELMIX_FLAG_ZERO)) { clear_c(d[0], n_samples); @@ -525,15 +539,16 @@ void channelmix_f32_7p1_3p1_c(struct channelmix *mix, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], uint32_t n_samples) { + CHANNELMIX_DEF_MATRIX(matrix, mix, matrix); uint32_t i, n, n_dst = mix->dst_chan; float **d = (float **) dst; const float **s = (const float **) src; - const float v0 = mix->matrix[0][0]; - const float v1 = mix->matrix[1][1]; - const float v2 = mix->matrix[2][2]; - const float v3 = mix->matrix[3][3]; - const float v4 = (mix->matrix[0][4] + mix->matrix[0][6]) * 0.5f; - const float v5 = (mix->matrix[1][5] + mix->matrix[1][7]) * 0.5f; + const float v0 = matrix[0][0]; + const float v1 = matrix[1][1]; + const float v2 = matrix[2][2]; + const float v3 = matrix[3][3]; + const float v4 = (matrix[0][4] + matrix[0][6]) * 0.5f; + const float v5 = (matrix[1][5] + matrix[1][7]) * 0.5f; if (SPA_FLAG_IS_SET(mix->flags, CHANNELMIX_FLAG_ZERO)) { for (i = 0; i < n_dst; i++) @@ -554,17 +569,18 @@ void channelmix_f32_7p1_4_c(struct channelmix *mix, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], uint32_t n_samples) { + CHANNELMIX_DEF_MATRIX(matrix, mix, matrix); uint32_t i, n, n_dst = mix->dst_chan; float **d = (float **) dst; const float **s = (const float **) src; - const float v0 = mix->matrix[0][0]; - const float v1 = mix->matrix[1][1]; - const float clev = (mix->matrix[0][2] + mix->matrix[1][2]) * 0.5f; - const float llev = (mix->matrix[0][3] + mix->matrix[1][3]) * 0.5f; - const float slev0 = mix->matrix[2][4]; - const float slev1 = mix->matrix[3][5]; - const float rlev0 = mix->matrix[2][6]; - const float rlev1 = mix->matrix[3][7]; + const float v0 = matrix[0][0]; + const float v1 = matrix[1][1]; + const float clev = (matrix[0][2] + matrix[1][2]) * 0.5f; + const float llev = (matrix[0][3] + matrix[1][3]) * 0.5f; + const float slev0 = matrix[2][4]; + const float slev1 = matrix[3][5]; + const float rlev0 = matrix[2][6]; + const float rlev1 = matrix[3][7]; if (SPA_FLAG_IS_SET(mix->flags, CHANNELMIX_FLAG_ZERO)) { for (i = 0; i < n_dst; i++) diff --git a/spa/plugins/audioconvert/channelmix-ops-sse.c b/spa/plugins/audioconvert/channelmix-ops-sse.c index 1a34c2bb3..7c3a8c2ff 100644 --- a/spa/plugins/audioconvert/channelmix-ops-sse.c +++ b/spa/plugins/audioconvert/channelmix-ops-sse.c @@ -144,11 +144,12 @@ static inline void sub_sse(float *d, const float *s0, const float *s1, uint32_t void channelmix_copy_sse(struct channelmix *mix, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], uint32_t n_samples) { + CHANNELMIX_DEF_MATRIX(matrix, mix, matrix); uint32_t i, n_dst = mix->dst_chan; float **d = (float **)dst; const float **s = (const float **)src; for (i = 0; i < n_dst; i++) - vol_sse(d[i], s[i], mix->matrix[i][i], n_samples); + vol_sse(d[i], s[i], matrix[i][i], n_samples); } static void lr4_process_sse(struct lr4 *lr4, float *dst, const float *src, const float vol, int samples) @@ -346,6 +347,7 @@ void channelmix_f32_n_m_sse(struct channelmix *mix, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], uint32_t n_samples) { + CHANNELMIX_DEF_MATRIX(matrix, mix, matrix); float **d = (float **) dst; const float **s = (const float **) src; uint32_t i, j, n_dst = mix->dst_chan, n_src = mix->src_chan; @@ -357,9 +359,9 @@ channelmix_f32_n_m_sse(struct channelmix *mix, void * SPA_RESTRICT dst[], uint32_t n_j = 0; for (j = 0; j < n_src; j++) { - if (mix->matrix[i][j] == 0.0f) + if (matrix[i][j] == 0.0f) continue; - mj[n_j] = mix->matrix[i][j]; + mj[n_j] = matrix[i][j]; sj[n_j++] = s[j]; } if (n_j == 0) { @@ -377,13 +379,14 @@ void channelmix_f32_2_3p1_sse(struct channelmix *mix, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], uint32_t n_samples) { + CHANNELMIX_DEF_MATRIX(matrix, mix, matrix); uint32_t i, n, unrolled, n_dst = mix->dst_chan; float **d = (float **)dst; const float **s = (const float **)src; - const float v0 = mix->matrix[0][0]; - const float v1 = mix->matrix[1][1]; - const float v2 = (mix->matrix[2][0] + mix->matrix[2][1]) * 0.5f; - const float v3 = (mix->matrix[3][0] + mix->matrix[3][1]) * 0.5f; + const float v0 = matrix[0][0]; + const float v1 = matrix[1][1]; + const float v2 = (matrix[2][0] + matrix[2][1]) * 0.5f; + const float v3 = (matrix[3][0] + matrix[3][1]) * 0.5f; if (SPA_FLAG_IS_SET(mix->flags, CHANNELMIX_FLAG_ZERO)) { for (i = 0; i < n_dst; i++) @@ -395,8 +398,8 @@ channelmix_f32_2_3p1_sse(struct channelmix *mix, void * SPA_RESTRICT dst[], vol_sse(d[1], s[1], v1, n_samples); avg_sse(d[2], s[0], s[1], n_samples); } else { - const __m128 mv0 = _mm_set1_ps(mix->matrix[0][0]); - const __m128 mv1 = _mm_set1_ps(mix->matrix[1][1]); + const __m128 mv0 = _mm_set1_ps(matrix[0][0]); + const __m128 mv1 = _mm_set1_ps(matrix[1][1]); const __m128 mw = _mm_set1_ps(mix->widen); const __m128 mh = _mm_set1_ps(0.5f); __m128 t0[1], t1[1], w[1], c[1]; @@ -437,11 +440,12 @@ void channelmix_f32_2_5p1_sse(struct channelmix *mix, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], uint32_t n_samples) { + CHANNELMIX_DEF_MATRIX(matrix, mix, matrix); uint32_t i, n_dst = mix->dst_chan; float **d = (float **)dst; const float **s = (const float **)src; - const float v4 = mix->matrix[4][0]; - const float v5 = mix->matrix[5][1]; + const float v4 = matrix[4][0]; + const float v5 = matrix[5][1]; if (SPA_FLAG_IS_SET(mix->flags, CHANNELMIX_FLAG_ZERO)) { for (i = 0; i < n_dst; i++) @@ -468,13 +472,14 @@ void channelmix_f32_2_7p1_sse(struct channelmix *mix, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], uint32_t n_samples) { + CHANNELMIX_DEF_MATRIX(matrix, mix, matrix); uint32_t i, n_dst = mix->dst_chan; float **d = (float **)dst; const float **s = (const float **)src; - const float v4 = mix->matrix[4][0]; - const float v5 = mix->matrix[5][1]; - const float v6 = mix->matrix[6][0]; - const float v7 = mix->matrix[7][1]; + const float v4 = matrix[4][0]; + const float v5 = matrix[5][1]; + const float v6 = matrix[6][0]; + const float v7 = matrix[7][1]; if (SPA_FLAG_IS_SET(mix->flags, CHANNELMIX_FLAG_ZERO)) { for (i = 0; i < n_dst; i++) @@ -504,12 +509,13 @@ void channelmix_f32_3p1_2_sse(struct channelmix *mix, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], uint32_t n_samples) { + CHANNELMIX_DEF_MATRIX(matrix, mix, matrix); float **d = (float **) dst; const float **s = (const float **) src; - const float m0 = mix->matrix[0][0]; - const float m1 = mix->matrix[1][1]; - const float m2 = (mix->matrix[0][2] + mix->matrix[1][2]) * 0.5f; - const float m3 = (mix->matrix[0][3] + mix->matrix[1][3]) * 0.5f; + const float m0 = matrix[0][0]; + const float m1 = matrix[1][1]; + const float m2 = (matrix[0][2] + matrix[1][2]) * 0.5f; + const float m3 = (matrix[0][3] + matrix[1][3]) * 0.5f; if (m0 == 0.0f && m1 == 0.0f && m2 == 0.0f && m3 == 0.0f) { clear_sse(d[0], n_samples); @@ -554,15 +560,16 @@ void channelmix_f32_5p1_2_sse(struct channelmix *mix, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], uint32_t n_samples) { + CHANNELMIX_DEF_MATRIX(matrix, mix, matrix); uint32_t n, unrolled; float **d = (float **) dst; const float **s = (const float **) src; - const float m00 = mix->matrix[0][0]; - const float m11 = mix->matrix[1][1]; - const __m128 clev = _mm_set1_ps((mix->matrix[0][2] + mix->matrix[1][2]) * 0.5f); - const __m128 llev = _mm_set1_ps((mix->matrix[0][3] + mix->matrix[1][3]) * 0.5f); - const __m128 slev0 = _mm_set1_ps(mix->matrix[0][4]); - const __m128 slev1 = _mm_set1_ps(mix->matrix[1][5]); + const float m00 = matrix[0][0]; + const float m11 = matrix[1][1]; + const __m128 clev = _mm_set1_ps((matrix[0][2] + matrix[1][2]) * 0.5f); + const __m128 llev = _mm_set1_ps((matrix[0][3] + matrix[1][3]) * 0.5f); + const __m128 slev0 = _mm_set1_ps(matrix[0][4]); + const __m128 slev1 = _mm_set1_ps(matrix[1][5]); __m128 in, ctr; if (SPA_IS_ALIGNED(s[0], 16) && @@ -616,6 +623,7 @@ void channelmix_f32_5p1_3p1_sse(struct channelmix *mix, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], uint32_t n_samples) { + CHANNELMIX_DEF_MATRIX(matrix, mix, matrix); uint32_t i, n, unrolled, n_dst = mix->dst_chan; float **d = (float **) dst; const float **s = (const float **) src; @@ -639,10 +647,10 @@ channelmix_f32_5p1_3p1_sse(struct channelmix *mix, void * SPA_RESTRICT dst[], clear_sse(d[i], n_samples); } else { - const __m128 v0 = _mm_set1_ps(mix->matrix[0][0]); - const __m128 v1 = _mm_set1_ps(mix->matrix[1][1]); - const __m128 slev0 = _mm_set1_ps(mix->matrix[0][4]); - const __m128 slev1 = _mm_set1_ps(mix->matrix[1][5]); + const __m128 v0 = _mm_set1_ps(matrix[0][0]); + const __m128 v1 = _mm_set1_ps(matrix[1][1]); + const __m128 slev0 = _mm_set1_ps(matrix[0][4]); + const __m128 slev1 = _mm_set1_ps(matrix[1][5]); for(n = 0; n < unrolled; n += 4) { _mm_store_ps(&d[0][n], _mm_add_ps( @@ -662,8 +670,8 @@ channelmix_f32_5p1_3p1_sse(struct channelmix *mix, void * SPA_RESTRICT dst[], _mm_mul_ss(_mm_load_ss(&s[1][n]), v1), _mm_mul_ss(_mm_load_ss(&s[5][n]), slev1))); } - vol_sse(d[2], s[2], mix->matrix[2][2], n_samples); - vol_sse(d[3], s[3], mix->matrix[3][3], n_samples); + vol_sse(d[2], s[2], matrix[2][2], n_samples); + vol_sse(d[3], s[3], matrix[3][3], n_samples); } } @@ -672,11 +680,12 @@ void channelmix_f32_5p1_4_sse(struct channelmix *mix, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], uint32_t n_samples) { + CHANNELMIX_DEF_MATRIX(matrix, mix, matrix); uint32_t i, n_dst = mix->dst_chan; float **d = (float **) dst; const float **s = (const float **) src; - const float v4 = mix->matrix[2][4]; - const float v5 = mix->matrix[3][5]; + const float v4 = matrix[2][4]; + const float v5 = matrix[3][5]; if (SPA_FLAG_IS_SET(mix->flags, CHANNELMIX_FLAG_ZERO)) { for (i = 0; i < n_dst; i++) @@ -695,17 +704,18 @@ void channelmix_f32_7p1_2_sse(struct channelmix *mix, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], uint32_t n_samples) { + CHANNELMIX_DEF_MATRIX(matrix, mix, matrix); uint32_t n, unrolled; float **d = (float **) dst; const float **s = (const float **) src; - const __m128 v0 = _mm_set1_ps(mix->matrix[0][0]); - const __m128 v1 = _mm_set1_ps(mix->matrix[1][1]); - const __m128 clev = _mm_set1_ps((mix->matrix[0][2] + mix->matrix[1][2]) * 0.5f); - const __m128 llev = _mm_set1_ps((mix->matrix[0][3] + mix->matrix[1][3]) * 0.5f); - const __m128 slev0 = _mm_set1_ps(mix->matrix[0][4]); - const __m128 slev1 = _mm_set1_ps(mix->matrix[1][5]); - const __m128 rlev0 = _mm_set1_ps(mix->matrix[0][6]); - const __m128 rlev1 = _mm_set1_ps(mix->matrix[1][7]); + const __m128 v0 = _mm_set1_ps(matrix[0][0]); + const __m128 v1 = _mm_set1_ps(matrix[1][1]); + const __m128 clev = _mm_set1_ps((matrix[0][2] + matrix[1][2]) * 0.5f); + const __m128 llev = _mm_set1_ps((matrix[0][3] + matrix[1][3]) * 0.5f); + const __m128 slev0 = _mm_set1_ps(matrix[0][4]); + const __m128 slev1 = _mm_set1_ps(matrix[1][5]); + const __m128 rlev0 = _mm_set1_ps(matrix[0][6]); + const __m128 rlev1 = _mm_set1_ps(matrix[1][7]); __m128 in, ctr; if (SPA_IS_ALIGNED(s[0], 16) && diff --git a/spa/plugins/audioconvert/channelmix-ops.c b/spa/plugins/audioconvert/channelmix-ops.c index c5f20c26b..7f8c914f7 100644 --- a/spa/plugins/audioconvert/channelmix-ops.c +++ b/spa/plugins/audioconvert/channelmix-ops.c @@ -196,6 +196,7 @@ static bool match_mix(struct channelmix *mix, static void impl_channelmix_reconfigure(struct channelmix *mix) { + CHANNELMIX_DEF_MATRIX(matrix_orig, mix, matrix_orig); float matrix[MAX_CHANNELS][MAX_CHANNELS] = {{ 0.0f }}; uint64_t src_mask = mix->src_mask, src_paired; uint64_t dst_mask = mix->dst_mask, dst_paired; @@ -749,7 +750,7 @@ done: src_mask == 0 ? "UNK" : spa_debug_type_find_short_name(spa_type_audio_channel, j + _SH)); - mix->matrix_orig[ic][jc++] = matrix[i][j]; + matrix_orig[ic][jc++] = matrix[i][j]; sum += fabsf(matrix[i][j]); if (matrix[i][j] == 0.0f) @@ -782,13 +783,15 @@ done: spa_log_info(mix->log, "normalize %f", maxsum); for (i = 0; i < dst_chan; i++) for (j = 0; j < src_chan; j++) - mix->matrix_orig[i][j] /= maxsum; + matrix_orig[i][j] /= maxsum; } } static void impl_channelmix_set_volume(struct channelmix *mix, float volume, bool mute, uint32_t n_channel_volumes, float *channel_volumes) { + CHANNELMIX_DEF_MATRIX(matrix_orig, mix, matrix_orig); + CHANNELMIX_DEF_MATRIX(matrix, mix, matrix); float volumes[MAX_CHANNELS]; float vol = mute ? 0.0f : volume, t; uint32_t i, j; @@ -807,19 +810,19 @@ static void impl_channelmix_set_volume(struct channelmix *mix, float volume, boo if (n_channel_volumes == src_chan) { for (i = 0; i < dst_chan; i++) { for (j = 0; j < src_chan; j++) { - mix->matrix[i][j] = mix->matrix_orig[i][j] * volumes[j]; + matrix[i][j] = matrix_orig[i][j] * volumes[j]; } } } else if (n_channel_volumes == dst_chan) { for (i = 0; i < dst_chan; i++) { for (j = 0; j < src_chan; j++) { - mix->matrix[i][j] = mix->matrix_orig[i][j] * volumes[i]; + matrix[i][j] = matrix_orig[i][j] * volumes[i]; } } } else if (n_channel_volumes == 0) { for (i = 0; i < dst_chan; i++) { for (j = 0; j < src_chan; j++) { - mix->matrix[i][j] = mix->matrix_orig[i][j] * vol; + matrix[i][j] = matrix_orig[i][j] * vol; } } } @@ -831,7 +834,7 @@ static void impl_channelmix_set_volume(struct channelmix *mix, float volume, boo t = 0.0; for (i = 0; i < dst_chan; i++) { for (j = 0; j < src_chan; j++) { - float v = mix->matrix[i][j]; + float v = matrix[i][j]; if (i == 0 && j == 0) t = v; else if (t != v) @@ -854,7 +857,7 @@ static void impl_channelmix_set_volume(struct channelmix *mix, float volume, boo for (i = 0; i < dst_chan; i++) { spa_strbuf_init(&sb1, str1, sizeof(str1)); for (j = 0; j < src_chan; j++) { - float v = mix->matrix[i][j]; + float v = matrix[i][j]; if (i == 0) spa_strbuf_append(&sb2, " %03d ", j); if (v == 0.0f) @@ -899,8 +902,7 @@ int channelmix_init(struct channelmix *mix) { const struct channelmix_info *info; void *d, *b[2]; - size_t taps_size, buffer_size, alloc_size, dstptr_size, matrow_size, matrix_size, lr4_size; - uint32_t i; + size_t taps_size, buffer_size, alloc_size, matrix_size, lr4_size; if (mix->src_chan > MAX_CHANNELS || mix->dst_chan > MAX_CHANNELS) @@ -932,12 +934,10 @@ int channelmix_init(struct channelmix *mix) taps_size = SPA_ROUND_UP(mix->n_taps * sizeof(float), CHANNELMIX_OPS_MAX_ALIGN); buffer_size = SPA_ROUND_UP(mix->buffer_size*2 * sizeof(float), CHANNELMIX_OPS_MAX_ALIGN); - dstptr_size = SPA_ROUND_UP(mix->dst_chan * sizeof(void*), CHANNELMIX_OPS_MAX_ALIGN); - matrow_size = SPA_ROUND_UP(mix->src_chan * sizeof(float), CHANNELMIX_OPS_MAX_ALIGN); - matrix_size = SPA_ROUND_UP(mix->dst_chan * matrow_size, CHANNELMIX_OPS_MAX_ALIGN); + matrix_size = SPA_ROUND_UP(mix->src_chan * mix->dst_chan * sizeof(float), CHANNELMIX_OPS_MAX_ALIGN); lr4_size = SPA_ROUND_UP(mix->dst_chan * sizeof(struct lr4), CHANNELMIX_OPS_MAX_ALIGN); - alloc_size = taps_size + buffer_size*2 + dstptr_size*2 + lr4_size + matrix_size*2 + CHANNELMIX_OPS_MAX_ALIGN; + alloc_size = taps_size + buffer_size*2 + lr4_size + matrix_size*2 + CHANNELMIX_OPS_MAX_ALIGN; d = calloc(1, alloc_size); if (d == NULL) return -errno; @@ -946,18 +946,13 @@ int channelmix_init(struct channelmix *mix) mix->taps = SPA_PTR_ALIGN(d, CHANNELMIX_OPS_MAX_ALIGN, float); mix->buffer[0] = SPA_PTROFF_ALIGN(mix->taps, taps_size, CHANNELMIX_OPS_MAX_ALIGN, float); mix->buffer[1] = SPA_PTROFF_ALIGN(mix->buffer[0], buffer_size, CHANNELMIX_OPS_MAX_ALIGN, float); - mix->matrix = SPA_PTROFF_ALIGN(mix->buffer[1], buffer_size, CHANNELMIX_OPS_MAX_ALIGN, float*); - mix->matrix_orig = SPA_PTROFF_ALIGN(mix->matrix, dstptr_size, CHANNELMIX_OPS_MAX_ALIGN, float*); - mix->lr4 = SPA_PTROFF_ALIGN(mix->matrix_orig, dstptr_size, CHANNELMIX_OPS_MAX_ALIGN, struct lr4); + mix->matrix = SPA_PTROFF_ALIGN(mix->buffer[1], buffer_size, CHANNELMIX_OPS_MAX_ALIGN, float); + mix->matrix_orig = SPA_PTROFF_ALIGN(mix->matrix, matrix_size, CHANNELMIX_OPS_MAX_ALIGN, float); + mix->lr4 = SPA_PTROFF_ALIGN(mix->matrix_orig, matrix_size, CHANNELMIX_OPS_MAX_ALIGN, struct lr4); b[0] = SPA_PTROFF_ALIGN(mix->lr4, lr4_size, CHANNELMIX_OPS_MAX_ALIGN, float); b[1] = SPA_PTROFF_ALIGN(b[0], matrix_size, CHANNELMIX_OPS_MAX_ALIGN, float); - for (i = 0; i < mix->dst_chan; i++) { - mix->matrix[i] = SPA_PTROFF_ALIGN(b[0], matrow_size * i, CHANNELMIX_OPS_MAX_ALIGN, float); - mix->matrix_orig[i] = SPA_PTROFF_ALIGN(b[1], matrow_size * i, CHANNELMIX_OPS_MAX_ALIGN, float); - } - if (mix->hilbert_taps > 0) { blackman_window(mix->taps, mix->n_taps); hilbert_generate(mix->taps, mix->n_taps); diff --git a/spa/plugins/audioconvert/channelmix-ops.h b/spa/plugins/audioconvert/channelmix-ops.h index cdf828643..35e7dde39 100644 --- a/spa/plugins/audioconvert/channelmix-ops.h +++ b/spa/plugins/audioconvert/channelmix-ops.h @@ -38,6 +38,8 @@ #define CHANNELMIX_DEFAULT_WIDEN 0.0f #define CHANNELMIX_DEFAULT_HILBERT_TAPS 0 +#define CHANNELMIX_DEF_MATRIX(var, mix, m) float (*(var))[(mix)->src_chan] = (float (*)[(mix)->src_chan])(mix)->m + struct channelmix { uint32_t src_chan; uint32_t dst_chan; @@ -62,8 +64,8 @@ struct channelmix { #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; - float **matrix; + float *matrix_orig; + float *matrix; float freq; /* sample frequency */ float lfe_cutoff; /* in Hz, 0 is disabled */ diff --git a/spa/plugins/audioconvert/test-channelmix.c b/spa/plugins/audioconvert/test-channelmix.c index 6d251656e..45ad52df0 100644 --- a/spa/plugins/audioconvert/test-channelmix.c +++ b/spa/plugins/audioconvert/test-channelmix.c @@ -27,11 +27,12 @@ SPA_LOG_IMPL(logger); static void dump_matrix(struct channelmix *mix, double *coeff) { + CHANNELMIX_DEF_MATRIX(matrix, mix, matrix); uint32_t i, j; for (i = 0; i < mix->dst_chan; i++) { for (j = 0; j < mix->src_chan; j++) { - float v = mix->matrix[i][j]; + float v = matrix[i][j]; spa_log_debug(mix->log, "%d %d: %f <-> %f", i, j, v, *coeff); spa_assert_se(CLOSE_ENOUGH(v, (float)*coeff)); coeff++; @@ -352,16 +353,18 @@ static void test_n_m_impl(void) /* identity matrix */ run_n_m_impl(&mix, (const void**)src, N_SAMPLES); + CHANNELMIX_DEF_MATRIX(matrix_orig, &mix, matrix_orig); + /* some zero destination */ - mix.matrix_orig[2][2] = 0.0f; - mix.matrix_orig[7][7] = 0.0f; + matrix_orig[2][2] = 0.0f; + matrix_orig[7][7] = 0.0f; channelmix_set_volume(&mix, 1.0f, false, 0, NULL); run_n_m_impl(&mix, (const void**)src, N_SAMPLES); /* random matrix */ for (i = 0; i < mix.dst_chan; i++) { for (j = 0; j < mix.src_chan; j++) { - mix.matrix_orig[i][j] = (float)(drand48() - 0.5f); + matrix_orig[i][j] = (float)(drand48() - 0.5f); } } channelmix_set_volume(&mix, 1.0f, false, 0, NULL);