Skip to content

Commit 9963357

Browse files
authored
Merge pull request #434 from singalsu/eq_fir_cleanup_init_cache_proposal
EQ FIR: Updates for component initialization and cache functions
2 parents 44c6402 + 7a0d5f6 commit 9963357

9 files changed

Lines changed: 197 additions & 226 deletions

File tree

src/audio/eq_fir.c

Lines changed: 128 additions & 138 deletions
Large diffs are not rendered by default.

src/audio/fir.c

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -50,40 +50,35 @@ void fir_reset(struct fir_state_32x16 *fir)
5050
{
5151
fir->rwi = 0;
5252
fir->length = 0;
53-
fir->delay_size = 0;
5453
fir->out_shift = 0;
5554
fir->coef = NULL;
5655
/* There may need to know the beginning of dynamic allocation after
5756
* reset so omitting setting also fir->delay to NULL.
5857
*/
5958
}
6059

61-
int fir_init_coef(struct fir_state_32x16 *fir, int16_t config[])
60+
size_t fir_init_coef(struct fir_state_32x16 *fir,
61+
struct sof_eq_fir_coef_data *config)
6262
{
63-
struct sof_eq_fir_coef_data *setup;
64-
65-
setup = (struct sof_eq_fir_coef_data *)config;
6663
fir->rwi = 0;
67-
fir->length = (int)setup->length;
68-
fir->out_shift = (int)setup->out_shift;
69-
fir->coef = &setup->coef[0];
64+
fir->length = (int)config->length;
65+
fir->out_shift = (int)config->out_shift;
66+
fir->coef = &config->coef[0];
7067
fir->delay = NULL;
71-
fir->delay_size = 0;
7268

7369
/* Check for sane FIR length. The length is constrained to be a
7470
* multiple of 4 for optimized code.
7571
*/
7672
if (fir->length > SOF_EQ_FIR_MAX_LENGTH || fir->length < 1)
7773
return -EINVAL;
7874

79-
return fir->length;
75+
return fir->length * sizeof(int32_t);
8076
}
8177

8278
void fir_init_delay(struct fir_state_32x16 *fir, int32_t **data)
8379
{
8480
fir->delay = *data;
85-
fir->delay_size = fir->length;
86-
*data += fir->delay_size; /* Point to next delay line start */
81+
*data += fir->length; /* Point to next delay line start */
8782
}
8883

8984
void eq_fir_s32(struct fir_state_32x16 fir[], struct comp_buffer *source,

src/audio/fir.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,15 @@
4242
struct fir_state_32x16 {
4343
int rwi; /* Circular read and write index */
4444
int length; /* Number of FIR taps */
45-
int delay_size; /* Actual delay lentgh, must be >= length */
4645
int out_shift; /* Amount of right shifts at output */
4746
int16_t *coef; /* Pointer to FIR coefficients */
4847
int32_t *delay; /* Pointer to FIR delay line */
4948
};
5049

5150
void fir_reset(struct fir_state_32x16 *fir);
5251

53-
int fir_init_coef(struct fir_state_32x16 *fir, int16_t config[]);
52+
size_t fir_init_coef(struct fir_state_32x16 *fir,
53+
struct sof_eq_fir_coef_data *config);
5454

5555
void fir_init_delay(struct fir_state_32x16 *fir, int32_t **data);
5656

@@ -80,6 +80,10 @@ static inline int32_t fir_32x16(struct fir_state_32x16 *fir, int32_t x)
8080
int i = 0; /* Start from 1st tap */
8181
int tmp_ri;
8282

83+
/* Bypass is set with length set to zero. */
84+
if (!fir->length)
85+
return x;
86+
8387
/* Write sample to delay */
8488
fir->delay[fir->rwi] = x;
8589

@@ -89,7 +93,7 @@ static inline int32_t fir_32x16(struct fir_state_32x16 *fir, int32_t x)
8993
n1 = fir->rwi + 1;
9094
/* Point to newest sample and advance read index */
9195
tmp_ri = (fir->rwi)++;
92-
if (fir->rwi == fir->delay_size)
96+
if (fir->rwi == fir->length)
9397
fir->rwi = 0;
9498

9599
if (n1 > fir->length) {
@@ -104,7 +108,7 @@ static inline int32_t fir_32x16(struct fir_state_32x16 *fir, int32_t x)
104108
fir_part_32x16(&y, n1, fir->coef, &i, fir->delay, &tmp_ri);
105109

106110
/* Part 2, unwrap fir_ri, continue rest of filter */
107-
tmp_ri = fir->delay_size - 1;
111+
tmp_ri = fir->length - 1;
108112
fir_part_32x16(&y, n2, fir->coef, &i, fir->delay, &tmp_ri);
109113
}
110114
/* Q9.39 -> Q9.24, saturate to Q8.24 */

src/audio/fir_config.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,11 @@
5858
#if XCHAL_HAVE_HIFI2EP == 1
5959
#define FIR_HIFIEP 1
6060
#define FIR_HIFI3 0
61-
#endif
62-
#if XCHAL_HAVE_HIFI3 == 1
61+
#elif XCHAL_HAVE_HIFI3 == 1
6362
#define FIR_HIFI3 1
6463
#define FIR_HIFIEP 0
64+
#else
65+
#error "No HIFIEP or HIFI3 found. Cannot build FIR module."
6566
#endif
6667
#else
6768
/* GCC */

src/audio/fir_hifi2ep.c

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -48,34 +48,28 @@
4848

4949
void fir_reset(struct fir_state_32x16 *fir)
5050
{
51-
fir->mute = 1;
51+
fir->taps = 0;
5252
fir->length = 0;
5353
fir->out_shift = 0;
54-
fir->rwp = NULL;
55-
fir->delay = NULL;
56-
fir->delay_end = NULL;
5754
fir->coef = NULL;
5855
/* There may need to know the beginning of dynamic allocation after
5956
* reset so omitting setting also fir->delay to NULL.
6057
*/
6158
}
6259

63-
int fir_init_coef(struct fir_state_32x16 *fir, int16_t config[])
60+
size_t fir_init_coef(struct fir_state_32x16 *fir,
61+
struct sof_eq_fir_coef_data *config)
6462
{
65-
struct sof_eq_fir_coef_data *setup;
66-
6763
/* The length is taps plus two since the filter computes two
6864
* samples per call. Length plus one would be minimum but the add
6965
* must be even. The even length is needed for 64 bit loads from delay
7066
* lines with 32 bit samples.
7167
*/
72-
setup = (struct sof_eq_fir_coef_data *)config;
73-
fir->mute = 0;
7468
fir->rwp = NULL;
75-
fir->taps = (int)setup->length;
69+
fir->taps = (int)config->length;
7670
fir->length = fir->taps + 2;
77-
fir->out_shift = (int)setup->out_shift;
78-
fir->coef = (ae_p16x2s *)&setup->coef[0];
71+
fir->out_shift = (int)config->out_shift;
72+
fir->coef = (ae_p16x2s *)&config->coef[0];
7973
fir->delay = NULL;
8074
fir->delay_end = NULL;
8175

@@ -86,7 +80,7 @@ int fir_init_coef(struct fir_state_32x16 *fir, int16_t config[])
8680
if (fir->taps & 3)
8781
return -EINVAL;
8882

89-
return fir->length;
83+
return fir->length * sizeof(int32_t);
9084
}
9185

9286
void fir_init_delay(struct fir_state_32x16 *fir, int32_t **data)
@@ -100,13 +94,8 @@ void fir_init_delay(struct fir_state_32x16 *fir, int32_t **data)
10094
void fir_get_lrshifts(struct fir_state_32x16 *fir, int *lshift,
10195
int *rshift)
10296
{
103-
if (fir->mute) {
104-
*lshift = 0;
105-
*rshift = 31;
106-
} else {
107-
*lshift = (fir->out_shift < 0) ? -fir->out_shift : 0;
108-
*rshift = (fir->out_shift > 0) ? fir->out_shift : 0;
109-
}
97+
*lshift = (fir->out_shift < 0) ? -fir->out_shift : 0;
98+
*rshift = (fir->out_shift > 0) ? fir->out_shift : 0;
11099
}
111100

112101
/* For even frame lengths use FIR filter that processes two sequential

src/audio/fir_hifi2ep.h

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ struct fir_state_32x16 {
4444
ae_p24f *delay; /* Pointer to FIR delay line */
4545
ae_p24f *delay_end; /* Pointer to FIR delay line end */
4646
ae_p16x2s *coef; /* Pointer to FIR coefficients */
47-
int mute; /* Set to 1 to mute EQ output, 0 otherwise */
4847
int taps; /* Number of FIR taps */
4948
int length; /* Number of FIR taps plus input length (even) */
5049
int in_shift; /* Amount of right shifts at input */
@@ -53,7 +52,8 @@ struct fir_state_32x16 {
5352

5453
void fir_reset(struct fir_state_32x16 *fir);
5554

56-
int fir_init_coef(struct fir_state_32x16 *fir, int16_t config[]);
55+
size_t fir_init_coef(struct fir_state_32x16 *fir,
56+
struct sof_eq_fir_coef_data *config);
5757

5858
void fir_init_delay(struct fir_state_32x16 *fir, int32_t **data);
5959

@@ -65,18 +65,6 @@ void eq_fir_2x_s32_hifiep(struct fir_state_32x16 fir[],
6565
void eq_fir_s32_hifiep(struct fir_state_32x16 fir[], struct comp_buffer *source,
6666
struct comp_buffer *sink, int frames, int nch);
6767

68-
/* The next trivial functions are inlined */
69-
70-
static inline void fir_mute(struct fir_state_32x16 *fir)
71-
{
72-
fir->mute = 1;
73-
}
74-
75-
static inline void fir_unmute(struct fir_state_32x16 *fir)
76-
{
77-
fir->mute = 0;
78-
}
79-
8068
/* Setup circular buffer for FIR input data delay */
8169
static inline void fir_hifiep_setup_circular(struct fir_state_32x16 *fir)
8270
{
@@ -114,6 +102,12 @@ static inline void fir_32x16_hifiep(struct fir_state_32x16 *fir, int32_t *x,
114102
const int taps_div_4 = fir->taps >> 2;
115103
const int inc = sizeof(int32_t);
116104

105+
/* Bypass samples if taps count is zero. */
106+
if (!taps_div_4) {
107+
*y = *x;
108+
return;
109+
}
110+
117111
/* Write sample to delay */
118112
a = AE_LQ32F_I((ae_q32s *)x, 0);
119113
AE_SQ32F_C(a, (ae_q32s *)fir->rwp, -sizeof(int32_t));
@@ -184,6 +178,13 @@ static inline void fir_32x16_2x_hifiep(struct fir_state_32x16 *fir, int32_t *x0,
184178
const int taps_div_4 = fir->taps >> 2;
185179
const int inc = 2 * sizeof(int32_t);
186180

181+
/* Bypass samples if taps count is zero. */
182+
if (!taps_div_4) {
183+
*y0 = *x0;
184+
*y1 = *x1;
185+
return;
186+
}
187+
187188
/* Write samples to delay */
188189
a = AE_LQ32F_I((ae_q32s *)x0, 0);
189190
AE_SQ32F_C(a, (ae_q32s *)fir->rwp, -sizeof(int32_t));

src/audio/fir_hifi3.c

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -48,34 +48,28 @@
4848

4949
void fir_reset(struct fir_state_32x16 *fir)
5050
{
51-
fir->mute = 1;
51+
fir->taps = 0;
5252
fir->length = 0;
5353
fir->out_shift = 0;
54-
fir->rwp = NULL;
55-
fir->delay = NULL;
56-
fir->delay_end = NULL;
5754
fir->coef = NULL;
5855
/* There may need to know the beginning of dynamic allocation after
5956
* reset so omitting setting also fir->delay to NULL.
6057
*/
6158
}
6259

63-
int fir_init_coef(struct fir_state_32x16 *fir, int16_t config[])
60+
size_t fir_init_coef(struct fir_state_32x16 *fir,
61+
struct sof_eq_fir_coef_data *config)
6462
{
65-
struct sof_eq_fir_coef_data *setup;
66-
6763
/* The length is taps plus two since the filter computes two
6864
* samples per call. Length plus one would be minimum but the add
6965
* must be even. The even length is needed for 64 bit loads from delay
7066
* lines with 32 bit samples.
7167
*/
72-
setup = (struct sof_eq_fir_coef_data *)config;
73-
fir->mute = 0;
7468
fir->rwp = NULL;
75-
fir->taps = (int)setup->length;
69+
fir->taps = (int)config->length;
7670
fir->length = fir->taps + 2;
77-
fir->out_shift = (int)setup->out_shift;
78-
fir->coef = (ae_f16x4 *)&setup->coef[0];
71+
fir->out_shift = (int)config->out_shift;
72+
fir->coef = (ae_f16x4 *)&config->coef[0];
7973
fir->delay = NULL;
8074
fir->delay_end = NULL;
8175

@@ -86,7 +80,7 @@ int fir_init_coef(struct fir_state_32x16 *fir, int16_t config[])
8680
if (fir->taps & 3)
8781
return -EINVAL;
8882

89-
return fir->length;
83+
return fir->length * sizeof(int32_t);
9084
}
9185

9286
void fir_init_delay(struct fir_state_32x16 *fir, int32_t **data)
@@ -100,13 +94,8 @@ void fir_init_delay(struct fir_state_32x16 *fir, int32_t **data)
10094
void fir_get_lrshifts(struct fir_state_32x16 *fir, int *lshift,
10195
int *rshift)
10296
{
103-
if (fir->mute) {
104-
*lshift = 0;
105-
*rshift = 31;
106-
} else {
107-
*lshift = (fir->out_shift < 0) ? -fir->out_shift : 0;
108-
*rshift = (fir->out_shift > 0) ? fir->out_shift : 0;
109-
}
97+
*lshift = (fir->out_shift < 0) ? -fir->out_shift : 0;
98+
*rshift = (fir->out_shift > 0) ? fir->out_shift : 0;
11099
}
111100

112101
/* For even frame lengths use FIR filter that processes two sequential
@@ -131,8 +120,7 @@ void eq_fir_2x_s32_hifi3(struct fir_state_32x16 fir[],
131120
int inc = nch << 1;
132121

133122
for (ch = 0; ch < nch; ch++) {
134-
/* Get FIR instance and get shifts to e.g. apply mute
135-
* without overhead.
123+
/* Get FIR instance and get shifts.
136124
*/
137125
f = &fir[ch];
138126
fir_get_lrshifts(f, &lshift, &rshift);

src/audio/fir_hifi3.h

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ struct fir_state_32x16 {
4444
ae_int32 *delay; /* Pointer to FIR delay line */
4545
ae_int32 *delay_end; /* Pointer to FIR delay line end */
4646
ae_f16x4 *coef; /* Pointer to FIR coefficients */
47-
int mute; /* Set to 1 to mute EQ output, 0 otherwise */
4847
int taps; /* Number of FIR taps */
4948
int length; /* Number of FIR taps plus input length (even) */
5049
int in_shift; /* Amount of right shifts at input */
@@ -53,7 +52,8 @@ struct fir_state_32x16 {
5352

5453
void fir_reset(struct fir_state_32x16 *fir);
5554

56-
int fir_init_coef(struct fir_state_32x16 *fir, int16_t config[]);
55+
size_t fir_init_coef(struct fir_state_32x16 *fir,
56+
struct sof_eq_fir_coef_data *config);
5757

5858
void fir_init_delay(struct fir_state_32x16 *fir, int32_t **data);
5959

@@ -64,18 +64,6 @@ void eq_fir_2x_s32_hifi3(struct fir_state_32x16 fir[],
6464
void eq_fir_s32_hifi3(struct fir_state_32x16 fir[], struct comp_buffer *source,
6565
struct comp_buffer *sink, int frames, int nch);
6666

67-
/* The next trivial functions are inlined */
68-
69-
static inline void fir_mute(struct fir_state_32x16 *fir)
70-
{
71-
fir->mute = 1;
72-
}
73-
74-
static inline void fir_unmute(struct fir_state_32x16 *fir)
75-
{
76-
fir->mute = 0;
77-
}
78-
7967
/* Setup circular buffer for FIR input data delay */
8068
static inline void fir_hifi3_setup_circular(struct fir_state_32x16 *fir)
8169
{
@@ -114,6 +102,12 @@ static inline void fir_32x16_hifi3(struct fir_state_32x16 *fir, int32_t *x,
114102
const int taps_div_4 = fir->taps >> 2;
115103
const int inc = sizeof(int32_t);
116104

105+
/* Bypass samples if taps count is zero. */
106+
if (!taps_div_4) {
107+
*y = *x;
108+
return;
109+
}
110+
117111
/* Write sample to delay */
118112
AE_S32_L_XC((ae_int32)*x, fir->rwp, -sizeof(int32_t));
119113

@@ -188,6 +182,13 @@ static inline void fir_32x16_2x_hifi3(struct fir_state_32x16 *fir, int32_t *x0,
188182
const int taps_div_4 = fir->taps >> 2;
189183
const int inc = 2 * sizeof(int32_t);
190184

185+
/* Bypass samples if taps count is zero. */
186+
if (!taps_div_4) {
187+
*y0 = *x0;
188+
*y1 = *x1;
189+
return;
190+
}
191+
191192
/* Write samples to delay */
192193
AE_S32_L_XC((ae_int32)*x0, fir->rwp, -sizeof(int32_t));
193194
dp = (ae_f32x2 *)fir->rwp;

src/include/uapi/eq.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444

4545
#define SOF_EQ_FIR_MAX_LENGTH 192 /* Max length for individual filter */
4646

47+
#define SOF_EQ_FIR_MAX_RESPONSES 8 /* A blob can define max 8 FIR EQs */
48+
4749
/*
4850
* eq_fir_configuration data structure contains this information
4951
* uint32_t size

0 commit comments

Comments
 (0)