mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2026-05-17 21:41:45 -04:00
channelmix: Convert matrices to float arrays
Convert matrix_orig and matrix to float arrays and use variable size 2d arrays to access the elements of the matrices. This removes the need for storing pointers to matrix rows.
This commit is contained in:
parent
7cfcb46fbf
commit
a7994882b9
6 changed files with 161 additions and 134 deletions
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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++)
|
||||
|
|
|
|||
|
|
@ -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) &&
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue