Skip to content

Commit 122b08b

Browse files
committed
Math: Separate icomplex16 and icomplex32 structs from FFT
This patch helps with more generic use of complex numbers not directly related to the FFTs domain. It prepares to add polar complex numbers format that is commonly used in frequency domain signal processing. Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
1 parent be9c9f0 commit 122b08b

15 files changed

Lines changed: 129 additions & 79 deletions

File tree

src/audio/mfcc/mfcc_generic.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#include <sof/audio/component.h>
1111
#include <sof/audio/audio_stream.h>
1212
#include <sof/math/auditory.h>
13+
#include <sof/math/icomplex16.h>
14+
#include <sof/math/icomplex32.h>
1315
#include <sof/math/matrix.h>
1416
#include <sof/math/sqrt.h>
1517
#include <sof/math/trig.h>

src/audio/mfcc/mfcc_hifi4.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
#include <sof/audio/component.h>
1212
#include <sof/audio/audio_stream.h>
1313
#include <sof/math/auditory.h>
14+
#include <sof/math/icomplex16.h>
15+
#include <sof/math/icomplex32.h>
1416
#include <sof/math/matrix.h>
1517
#include <sof/math/sqrt.h>
1618
#include <sof/math/trig.h>

src/audio/mfcc/mfcc_setup.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
#include <sof/audio/component.h>
99
#include <sof/audio/audio_stream.h>
1010
#include <sof/math/auditory.h>
11+
#include <sof/math/icomplex16.h>
12+
#include <sof/math/icomplex32.h>
1113
#include <sof/math/trig.h>
1214
#include <sof/math/window.h>
1315
#include <sof/trace/trace.h>

src/include/sof/math/fft.h

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include <sof/audio/module_adapter/module/generic.h>
1313
#include <sof/audio/format.h>
14+
#include <sof/math/icomplex32.h>
1415
#include <sof/common.h>
1516
#include <stdbool.h>
1617
#include <stdint.h>
@@ -30,20 +31,6 @@
3031
#define FFT_SIZE_MAX 1024
3132
#define FFT_MULTI_COUNT_MAX 3
3233

33-
struct icomplex32 {
34-
int32_t real;
35-
int32_t imag;
36-
};
37-
38-
/* Note: the add of packed attribute to icmplex16 would significantly increase
39-
* processing time of fft_execute_16() so it is not done. The optimized versions of
40-
* FFT for HiFi will need a different packed data structure vs. generic C.
41-
*/
42-
struct icomplex16 {
43-
int16_t real;
44-
int16_t imag;
45-
};
46-
4734
struct fft_plan {
4835
uint32_t size; /* fft size */
4936
uint32_t len; /* fft length in exponent of 2 */

src/include/sof/math/icomplex16.h

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// SPDX-License-Identifier: BSD-3-Clause
2+
//
3+
// Copyright(c) 2020-2026 Intel Corporation.
4+
//
5+
// Author: Amery Song <chao.song@intel.com>
6+
// Keyon Jie <yang.jie@linux.intel.com>
7+
8+
#include <sof/audio/format.h>
9+
#include <sof/common.h>
10+
#include <stdint.h>
11+
12+
#ifndef __SOF_ICOMPLEX16_H__
13+
#define __SOF_ICOMPLEX16_H__
14+
15+
/* Note: the add of packed attribute to icmplex16 would significantly increase
16+
* processing time of fft_execute_16() so it is not done. The optimized versions of
17+
* FFT for HiFi will need a different packed data structure vs. generic C.
18+
*
19+
* TODO: Use with care with other than 16-bit FFT internals. Access with intrinsics
20+
* will requires packed and aligned data. Currently there is no such usage in SOF.
21+
*/
22+
23+
/**
24+
* struct icomplex16 - Storage for a normal complex number.
25+
* @param real The real part in Q1.15 fractional format.
26+
* @param imag The imaginary part in Q1.15 fractional format.
27+
*/
28+
struct icomplex16 {
29+
int16_t real;
30+
int16_t imag;
31+
};
32+
33+
/*
34+
* Helpers for 16 bit FFT calculation
35+
*/
36+
static inline void icomplex16_add(const struct icomplex16 *in1, const struct icomplex16 *in2,
37+
struct icomplex16 *out)
38+
{
39+
out->real = in1->real + in2->real;
40+
out->imag = in1->imag + in2->imag;
41+
}
42+
43+
static inline void icomplex16_sub(const struct icomplex16 *in1, const struct icomplex16 *in2,
44+
struct icomplex16 *out)
45+
{
46+
out->real = in1->real - in2->real;
47+
out->imag = in1->imag - in2->imag;
48+
}
49+
50+
static inline void icomplex16_mul(const struct icomplex16 *in1, const struct icomplex16 *in2,
51+
struct icomplex16 *out)
52+
{
53+
int32_t real = (int32_t)in1->real * in2->real - (int32_t)in1->imag * in2->imag;
54+
int32_t imag = (int32_t)in1->real * in2->imag + (int32_t)in1->imag * in2->real;
55+
56+
out->real = Q_SHIFT_RND(real, 30, 15);
57+
out->imag = Q_SHIFT_RND(imag, 30, 15);
58+
}
59+
60+
/* complex conjugate */
61+
static inline void icomplex16_conj(struct icomplex16 *comp)
62+
{
63+
comp->imag = sat_int16(-((int32_t)comp->imag));
64+
}
65+
66+
/* shift a complex n bits, n > 0: left shift, n < 0: right shift */
67+
static inline void icomplex16_shift(const struct icomplex16 *input, int16_t n,
68+
struct icomplex16 *output)
69+
{
70+
int n1, n2;
71+
72+
if (n >= 0) {
73+
/* need saturation handling */
74+
output->real = sat_int16((int32_t)input->real << n);
75+
output->imag = sat_int16((int32_t)input->imag << n);
76+
} else {
77+
n1 = -n;
78+
n2 = 1 << (n1 - 1);
79+
output->real = sat_int16(((int32_t)input->real + n2) >> n1);
80+
output->imag = sat_int16(((int32_t)input->imag + n2) >> n1);
81+
}
82+
}
83+
84+
#endif /* __SOF_ICOMPLEX16_H__ */
Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,29 @@
11
// SPDX-License-Identifier: BSD-3-Clause
22
//
3-
// Copyright(c) 2020-2025 Intel Corporation. All rights reserved.
3+
// Copyright(c) 2020-2026 Intel Corporation.
44
//
55
// Author: Amery Song <chao.song@intel.com>
66
// Keyon Jie <yang.jie@linux.intel.com>
77

88
#include <sof/audio/format.h>
9-
#include <sof/math/fft.h>
9+
#include <sof/math/exp_fcn.h>
10+
#include <sof/math/log.h>
11+
#include <sof/math/trig.h>
1012
#include <sof/common.h>
13+
#include <stdint.h>
14+
15+
#ifndef __SOF_ICOMPLEX32_H__
16+
#define __SOF_ICOMPLEX32_H__
17+
18+
/**
19+
* struct icomplex32 - Storage for a normal complex number.
20+
* @param real The real part in Q1.31 fractional format.
21+
* @param imag The imaginary part in Q1.31 fractional format.
22+
*/
23+
struct icomplex32 {
24+
int32_t real;
25+
int32_t imag;
26+
};
1127

1228
/*
1329
* These helpers are optimized for FFT calculation only.
@@ -62,3 +78,5 @@ static inline void icomplex32_shift(const struct icomplex32 *input, int32_t n,
6278
output->imag = input->imag >> -n;
6379
}
6480
}
81+
82+
#endif /* __SOF_ICOMPLEX32_H__ */

src/math/auditory/mel_filterbank_16.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
#include <sof/audio/format.h>
88
#include <sof/math/auditory.h>
9-
#include <sof/math/fft.h>
9+
#include <sof/math/icomplex16.h>
1010
#include <sof/math/log.h>
1111
#include <sof/math/numbers.h>
1212
#include <stdint.h>

src/math/auditory/mel_filterbank_32.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
#include <sof/audio/format.h>
88
#include <sof/math/auditory.h>
9-
#include <sof/math/fft.h>
9+
#include <sof/math/icomplex32.h>
1010
#include <sof/math/log.h>
1111
#include <sof/math/numbers.h>
1212
#include <stdint.h>

src/math/fft/fft_16.c

Lines changed: 4 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,19 @@
11
// SPDX-License-Identifier: BSD-3-Clause
22
//
3-
// Copyright(c) 2020 Intel Corporation. All rights reserved.
3+
// Copyright(c) 2020-2026 Intel Corporation.
44
//
55
// Author: Amery Song <chao.song@intel.com>
66
// Keyon Jie <yang.jie@linux.intel.com>
77

88
#include <sof/audio/format.h>
9-
#include <sof/common.h>
109
#include <sof/math/fft.h>
10+
#include <sof/math/icomplex16.h>
11+
#include <sof/common.h>
12+
#include <stdint.h>
1113

1214
#ifdef FFT_GENERIC
1315
#include <sof/audio/coefficients/fft/twiddle_16.h>
1416

15-
/*
16-
* Helpers for 16 bit FFT calculation
17-
*/
18-
static inline void icomplex16_add(const struct icomplex16 *in1, const struct icomplex16 *in2,
19-
struct icomplex16 *out)
20-
{
21-
out->real = in1->real + in2->real;
22-
out->imag = in1->imag + in2->imag;
23-
}
24-
25-
static inline void icomplex16_sub(const struct icomplex16 *in1, const struct icomplex16 *in2,
26-
struct icomplex16 *out)
27-
{
28-
out->real = in1->real - in2->real;
29-
out->imag = in1->imag - in2->imag;
30-
}
31-
32-
static inline void icomplex16_mul(const struct icomplex16 *in1, const struct icomplex16 *in2,
33-
struct icomplex16 *out)
34-
{
35-
int32_t real = (int32_t)in1->real * in2->real - (int32_t)in1->imag * in2->imag;
36-
int32_t imag = (int32_t)in1->real * in2->imag + (int32_t)in1->imag * in2->real;
37-
38-
out->real = Q_SHIFT_RND(real, 30, 15);
39-
out->imag = Q_SHIFT_RND(imag, 30, 15);
40-
}
41-
42-
/* complex conjugate */
43-
static inline void icomplex16_conj(struct icomplex16 *comp)
44-
{
45-
comp->imag = sat_int16(-((int32_t)comp->imag));
46-
}
47-
48-
/* shift a complex n bits, n > 0: left shift, n < 0: right shift */
49-
static inline void icomplex16_shift(const struct icomplex16 *input, int16_t n,
50-
struct icomplex16 *output)
51-
{
52-
int n1, n2;
53-
54-
if (n >= 0) {
55-
/* need saturation handling */
56-
output->real = sat_int16((int32_t)input->real << n);
57-
output->imag = sat_int16((int32_t)input->imag << n);
58-
} else {
59-
n1 = -n;
60-
n2 = 1 << (n1 - 1);
61-
output->real = sat_int16(((int32_t)input->real + n2) >> n1);
62-
output->imag = sat_int16(((int32_t)input->imag + n2) >> n1);
63-
}
64-
}
65-
6617
/**
6718
* \brief Execute the 16-bits Fast Fourier Transform (FFT) or Inverse FFT (IFFT)
6819
* For the configured fft_pan.

src/math/fft/fft_16_hifi3.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include <sof/audio/format.h>
88
#include <sof/common.h>
99
#include <sof/math/fft.h>
10+
#include <sof/math/icomplex16.h>
11+
1012

1113
#ifdef FFT_HIFI3
1214
#include <sof/audio/coefficients/fft/twiddle_16.h>

0 commit comments

Comments
 (0)