Skip to content

Commit 32e4902

Browse files
committed
EQ FIR: Updates to generic C filter core
Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
1 parent 639b4a8 commit 32e4902

3 files changed

Lines changed: 128 additions & 46 deletions

File tree

src/audio/fir.c

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -33,29 +33,24 @@
3333
#include <stdint.h>
3434
#include <stddef.h>
3535
#include <errno.h>
36+
#include <sof/audio/component.h>
37+
#include <sof/audio/format.h>
38+
#include <uapi/eq.h>
39+
#include "fir_config.h"
3640

37-
#ifdef MODULE_TEST
38-
#include <stdio.h>
39-
#endif
41+
#if FIR_GENERIC
4042

41-
#include <sof/audio/format.h>
4243
#include "fir.h"
4344

44-
#ifdef MODULE_TEST
45-
#include <stdio.h>
46-
#endif
47-
4845
/*
4946
* EQ FIR algorithm code
5047
*/
5148

5249
void fir_reset(struct fir_state_32x16 *fir)
5350
{
54-
fir->mute = 1;
5551
fir->rwi = 0;
5652
fir->length = 0;
5753
fir->delay_size = 0;
58-
fir->in_shift = 0;
5954
fir->out_shift = 0;
6055
fir->coef = NULL;
6156
/* There may need to know the beginning of dynamic allocation after
@@ -65,19 +60,20 @@ void fir_reset(struct fir_state_32x16 *fir)
6560

6661
int fir_init_coef(struct fir_state_32x16 *fir, int16_t config[])
6762
{
68-
struct fir_coef_32x16 *setup;
63+
struct sof_eq_fir_coef_data *setup;
6964

70-
setup = (struct fir_coef_32x16 *) config;
71-
fir->mute = 0;
65+
setup = (struct sof_eq_fir_coef_data *)config;
7266
fir->rwi = 0;
73-
fir->length = (int) setup->length;
74-
fir->in_shift = (int) setup->in_shift;
75-
fir->out_shift = (int) setup->out_shift;
76-
fir->coef = &setup->coef;
67+
fir->length = (int)setup->length;
68+
fir->out_shift = (int)setup->out_shift;
69+
fir->coef = &setup->coef[0];
7770
fir->delay = NULL;
7871
fir->delay_size = 0;
7972

80-
if ((fir->length > MAX_FIR_LENGTH) || (fir->length < 1))
73+
/* Check for sane FIR length. The length is constrained to be a
74+
* multiple of 4 for optimized code.
75+
*/
76+
if (fir->length > SOF_EQ_FIR_MAX_LENGTH || fir->length < 1)
8177
return -EINVAL;
8278

8379
return fir->length;
@@ -89,3 +85,28 @@ void fir_init_delay(struct fir_state_32x16 *fir, int32_t **data)
8985
fir->delay_size = fir->length;
9086
*data += fir->delay_size; /* Point to next delay line start */
9187
}
88+
89+
void eq_fir_s32(struct fir_state_32x16 fir[], struct comp_buffer *source,
90+
struct comp_buffer *sink, int frames, int nch)
91+
{
92+
struct fir_state_32x16 *filter;
93+
int32_t *src = (int32_t *)source->r_ptr;
94+
int32_t *snk = (int32_t *)sink->w_ptr;
95+
int32_t *x;
96+
int32_t *y;
97+
int ch;
98+
int i;
99+
100+
for (ch = 0; ch < nch; ch++) {
101+
filter = &fir[ch];
102+
x = src++;
103+
y = snk++;
104+
for (i = 0; i < frames; i++) {
105+
*y = fir_32x16(filter, *x);
106+
x += nch;
107+
y += nch;
108+
}
109+
}
110+
}
111+
112+
#endif

src/audio/fir.h

Lines changed: 13 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -30,25 +30,19 @@
3030
* Keyon Jie <yang.jie@linux.intel.com>
3131
*/
3232

33-
#include <sof/audio/format.h>
33+
#ifndef FIR_H
34+
#define FIR_H
3435

35-
#define MAX_FIR_LENGTH 192
36+
#include "fir_config.h"
3637

37-
#define NHEADER_FIR_COEF_32x16 3
38+
#if FIR_GENERIC
3839

39-
struct fir_coef_32x16 {
40-
int16_t length; /* Number of FIR taps */
41-
int16_t in_shift; /* Amount of right shifts at input */
42-
int16_t out_shift; /* Amount of right shifts at output */
43-
int16_t coef; /* FIR coefficients */
44-
};
40+
#include <sof/audio/format.h>
4541

4642
struct fir_state_32x16 {
47-
int mute; /* Set to 1 to mute EQ output, 0 otherwise */
4843
int rwi; /* Circular read and write index */
4944
int length; /* Number of FIR taps */
5045
int delay_size; /* Actual delay lentgh, must be >= length */
51-
int in_shift; /* Amount of right shifts at input */
5246
int out_shift; /* Amount of right shifts at output */
5347
int16_t *coef; /* Pointer to FIR coefficients */
5448
int32_t *delay; /* Pointer to FIR delay line */
@@ -60,17 +54,8 @@ int fir_init_coef(struct fir_state_32x16 *fir, int16_t config[]);
6054

6155
void fir_init_delay(struct fir_state_32x16 *fir, int32_t **data);
6256

63-
/* The next trivial functions are inlined */
64-
65-
static inline void fir_mute(struct fir_state_32x16 *fir)
66-
{
67-
fir->mute = 1;
68-
}
69-
70-
static inline void fir_unmute(struct fir_state_32x16 *fir)
71-
{
72-
fir->mute = 0;
73-
}
57+
void eq_fir_s32(struct fir_state_32x16 fir[], struct comp_buffer *source,
58+
struct comp_buffer *sink, int frames, int nch);
7459

7560
/* The next functions are inlined to optmize execution speed */
7661

@@ -81,7 +66,7 @@ static inline void fir_part_32x16(int64_t *y, int taps, const int16_t c[],
8166

8267
/* Data is Q8.24, coef is Q1.15, product is Q9.39 */
8368
for (n = 0; n < taps; n++) {
84-
*y += (int64_t) c[*ic] * d[*id];
69+
*y += (int64_t)c[*ic] * d[*id];
8570
(*ic)++;
8671
(*id)--;
8772
}
@@ -96,7 +81,7 @@ static inline int32_t fir_32x16(struct fir_state_32x16 *fir, int32_t x)
9681
int tmp_ri;
9782

9883
/* Write sample to delay */
99-
fir->delay[fir->rwi] = x >> fir->in_shift;
84+
fir->delay[fir->rwi] = x;
10085

10186
/* Start FIR calculation. Calculate first number of taps possible to
10287
* calculate before circular wrap need.
@@ -125,8 +110,8 @@ static inline int32_t fir_32x16(struct fir_state_32x16 *fir, int32_t x)
125110
/* Q9.39 -> Q9.24, saturate to Q8.24 */
126111
y = sat_int32(y >> (15 + fir->out_shift));
127112

128-
if (fir->mute)
129-
return 0;
130-
else
131-
return (int32_t)y;
113+
return (int32_t)y;
132114
}
115+
116+
#endif
117+
#endif

src/audio/fir_config.h

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* Copyright (c) 2017, Intel Corporation
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are met:
7+
* * Redistributions of source code must retain the above copyright
8+
* notice, this list of conditions and the following disclaimer.
9+
* * Redistributions in binary form must reproduce the above copyright
10+
* notice, this list of conditions and the following disclaimer in the
11+
* documentation and/or other materials provided with the distribution.
12+
* * Neither the name of the Intel Corporation nor the
13+
* names of its contributors may be used to endorse or promote products
14+
* derived from this software without specific prior written permission.
15+
*
16+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26+
* POSSIBILITY OF SUCH DAMAGE.
27+
*
28+
* Author: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
29+
* Liam Girdwood <liam.r.girdwood@linux.intel.com>
30+
* Keyon Jie <yang.jie@linux.intel.com>
31+
*/
32+
33+
#ifndef FIR_CONFIG_H
34+
35+
/* Get platforms configuration */
36+
#include <config.h>
37+
38+
/* If next defines are set to 1 the EQ is configured automatically. Setting
39+
* to zero temporarily is useful is for testing needs.
40+
* Setting EQ_FIR_AUTOARCH to 0 allows to manually set the code variant.
41+
*/
42+
#define FIR_AUTOARCH 1
43+
44+
/* Force manually some code variant when EQ_FIR_AUTODSP is set to zero. These
45+
* are useful in code debugging.
46+
*/
47+
#if FIR_AUTOARCH == 0
48+
#define FIR_GENERIC 0
49+
#define FIR_HIFIEP 0
50+
#define FIR_HIFI3 1
51+
#endif
52+
53+
/* Select optimized code variant when xt-xcc compiler is used */
54+
#if FIR_AUTOARCH == 1
55+
#if defined __XCC__
56+
#include <xtensa/config/core-isa.h>
57+
#define FIR_GENERIC 0
58+
#if XCHAL_HAVE_HIFI2EP == 1
59+
#define FIR_HIFIEP 1
60+
#define FIR_HIFI3 0
61+
#endif
62+
#if XCHAL_HAVE_HIFI3 == 1
63+
#define FIR_HIFI3 1
64+
#define FIR_HIFIEP 0
65+
#endif
66+
#else
67+
/* GCC */
68+
#define FIR_GENERIC 1
69+
#define FIR_HIFIEP 0
70+
#define FIR_HIFI3 0
71+
#endif
72+
#endif
73+
74+
#define FIR_CONFIG_H
75+
76+
#endif

0 commit comments

Comments
 (0)