Skip to content

Commit 5412a28

Browse files
committed
Math: Inline function sofm_lut_sin_fixed_16b() for performance
This patch inlines the function sofm_lut_sin_fixed_16b() and moves it to header file lut_trig.h. The lookup table is kept in lut_trig.c and made global. The DRC component use a lot the sine function (the fast lookup tables version). The function seems to not get improvement from HiFi intrinsics rewrite but making it inline improves DRC performance in MTL platform by 0.54 MCPS, from 12.62 MCPS to 12.08 MCPS. In Multiband-DRC the saving multiplies by number of bands, e.g. 1.58 MCPS saving with three bands. Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
1 parent 503ae3e commit 5412a28

File tree

2 files changed

+49
-47
lines changed

2 files changed

+49
-47
lines changed

src/include/sof/math/lut_trig.h

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,53 @@
1010

1111
#include <stdint.h>
1212

13-
int16_t sofm_lut_sin_fixed_16b(int32_t w); /* Input is Q4.28, output is Q1.15 */
13+
#define SOFM_LUT_SINE_C_Q20 341782638 /* 2 * SINE_NQUART / pi in Q12.20 */
14+
#define SOFM_LUT_SINE_NQUART 512 /* Must be 2^N */
15+
#define SOFM_LUT_SINE_SIZE (SOFM_LUT_SINE_NQUART + 1)
16+
17+
extern const uint16_t sofm_lut_sine_table_s16[];
18+
19+
/* Sine lookup table read */
20+
static inline int32_t sofm_sine_lookup_16b(int idx)
21+
{
22+
uint16_t s;
23+
int i1;
24+
25+
i1 = idx & (2 * SOFM_LUT_SINE_NQUART - 1);
26+
if (i1 > SOFM_LUT_SINE_NQUART)
27+
i1 = 2 * SOFM_LUT_SINE_NQUART - i1;
28+
29+
s = sofm_lut_sine_table_s16[i1];
30+
if (idx > 2 * SOFM_LUT_SINE_NQUART)
31+
return -((int32_t)s);
32+
33+
return (int32_t)s;
34+
}
35+
36+
/**
37+
* Compute fixed point sine with table lookup and interpolation
38+
* @param w Input angle in radians Q4.28
39+
* @return Sine value Q1.15
40+
*/
41+
static inline int16_t sofm_lut_sin_fixed_16b(int32_t w)
42+
{
43+
int64_t idx;
44+
int32_t sine;
45+
int32_t frac;
46+
int32_t delta;
47+
int32_t s0;
48+
int32_t s1;
49+
int64_t idx_tmp;
50+
51+
/* Q4.28 x Q12.20 -> Q16.48 --> Q16.31*/
52+
idx_tmp = ((int64_t)w * SOFM_LUT_SINE_C_Q20) >> 17;
53+
idx = (idx_tmp >> 31); /* Shift to Q0 */
54+
frac = (int32_t)(idx_tmp - (idx << 31)); /* Get fraction Q1.31*/
55+
s0 = sofm_sine_lookup_16b(idx); /* Q1.16 */
56+
s1 = sofm_sine_lookup_16b(idx + 1); /* Q1.16 */
57+
delta = s1 - s0; /* Q1.16 */
58+
sine = s0 + q_mults_32x32(frac, delta, Q_SHIFT_BITS_64(31, 16, 16)); /* Q1.16 */
59+
return sat_int16((sine + 1) >> 1); /* Round to Q1.15 */
60+
}
1461

1562
#endif /* __SOF_MATH_LUT_TRIG_H__ */

src/math/lut_trig.c

Lines changed: 1 addition & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,16 @@
55
// Author: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
66

77
#include <sof/audio/format.h>
8-
#include <sof/math/lut_trig.h>
98
#include <rtos/symbol.h>
109
#include <stdint.h>
1110

12-
#define SOFM_LUT_SINE_C_Q20 341782638 /* 2 * SINE_NQUART / pi in Q12.20 */
13-
#define SOFM_LUT_SINE_NQUART 512 /* Must be 2^N */
14-
#define SOFM_LUT_SINE_SIZE (SOFM_LUT_SINE_NQUART + 1)
15-
1611
/* Sine values 0 to pi/2, calculated with Octave
1712
* w = linspace(0, pi/2, 513);
1813
* s = 2^16;
1914
* x = min(round(s * sin(w)), s - 1);
2015
*/
2116

22-
static const uint16_t sofm_lut_sine_table_s16[SOFM_LUT_SINE_SIZE] = {
17+
const uint16_t sofm_lut_sine_table_s16[] = {
2318
0, 201, 402, 603, 804, 1005, 1206, 1407, 1608, 1809, 2010,
2419
2211, 2412, 2613, 2814, 3015, 3216, 3417, 3617, 3818, 4019, 4219,
2520
4420, 4621, 4821, 5022, 5222, 5422, 5623, 5823, 6023, 6224, 6424,
@@ -68,43 +63,3 @@ static const uint16_t sofm_lut_sine_table_s16[SOFM_LUT_SINE_SIZE] = {
6863
65447, 65457, 65467, 65476, 65484, 65492, 65499, 65505, 65511, 65516, 65521,
6964
65525, 65528, 65531, 65533, 65535, 65535, 65535
7065
};
71-
72-
/* Sine lookup table read */
73-
static inline int32_t sofm_sine_lookup_16b(int idx)
74-
{
75-
uint16_t s;
76-
int i1;
77-
78-
i1 = idx & (2 * SOFM_LUT_SINE_NQUART - 1);
79-
if (i1 > SOFM_LUT_SINE_NQUART)
80-
i1 = 2 * SOFM_LUT_SINE_NQUART - i1;
81-
82-
s = sofm_lut_sine_table_s16[i1];
83-
if (idx > 2 * SOFM_LUT_SINE_NQUART)
84-
return -((int32_t)s);
85-
86-
return (int32_t)s;
87-
}
88-
89-
/* Compute fixed point sine with table lookup and interpolation */
90-
int16_t sofm_lut_sin_fixed_16b(int32_t w)
91-
{
92-
int64_t idx;
93-
int32_t sine;
94-
int32_t frac;
95-
int32_t delta;
96-
int32_t s0;
97-
int32_t s1;
98-
int64_t idx_tmp;
99-
100-
/* Q4.28 x Q12.20 -> Q16.48 --> Q16.31*/
101-
idx_tmp = ((int64_t)w * SOFM_LUT_SINE_C_Q20) >> 17;
102-
idx = (idx_tmp >> 31); /* Shift to Q0 */
103-
frac = (int32_t)(idx_tmp - (idx << 31)); /* Get fraction Q1.31*/
104-
s0 = sofm_sine_lookup_16b(idx); /* Q1.16 */
105-
s1 = sofm_sine_lookup_16b(idx + 1); /* Q1.16 */
106-
delta = s1 - s0; /* Q1.16 */
107-
sine = s0 + q_mults_32x32(frac, delta, Q_SHIFT_BITS_64(31, 16, 16)); /* Q1.16 */
108-
return sat_int16((sine + 1) >> 1); /* Round to Q1.15 */
109-
}
110-
EXPORT_SYMBOL(sofm_lut_sin_fixed_16b);

0 commit comments

Comments
 (0)