1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright(c) 2017 Intel Corporation. All rights reserved.
4  *
5  * Author: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
6  */
7 
8 #ifndef __USER_EQ_H__
9 #define __USER_EQ_H__
10 
11 #include <stdint.h>
12 
13 /* FIR EQ type */
14 
15 #define SOF_EQ_FIR_IDX_SWITCH	0
16 
17 #define SOF_EQ_FIR_MAX_SIZE 4096 /* Max size allowed for coef data in bytes */
18 
19 #define SOF_EQ_FIR_MAX_RESPONSES 8 /* A blob can define max 8 FIR EQs */
20 
21 /*
22  * eq_fir_configuration data structure contains this information
23  *     uint32_t size
24  *	   This is the number of bytes need to store the received EQ
25  *	   configuration.
26  *     uint16_t channels_in_config
27  *         This describes the number of channels in this EQ config data. It
28  *         can be different from PLATFORM_MAX_CHANNELS.
29  *     uint16_t number_of_responses
30  *         0=no responses, 1=one response defined, 2=two responses defined, etc.
31  *     int16_t data[]
32  *         assign_response[channels_in_config]
33  *             0 = use first response, 1 = use 2nd response, etc.
34  *             E.g. {0, 0, 0, 0, 1, 1, 1, 1} would apply to channels 0-3 the
35  *	       same first defined response and for to channels 4-7 the second.
36  *         coef_data[]
37  *             Repeated data
38  *             { filter_length, output_shift, h[] }
39  *	       for every EQ response defined where vector h has filter_length
40  *             number of coefficients. Coefficients in h[] are in Q1.15 format.
41  *             E.g. 16384 (Q1.15) = 0.5. The shifts are number of right shifts.
42  *
43  * NOTE: The channels_in_config must be even to have coef_data aligned to
44  * 32 bit word in RAM. Therefore a mono EQ assign must be duplicated to 2ch
45  * even if it would never used. Similarly a 5ch EQ assign must be increased
46  * to 6ch. EQ init will return an error if this is not met.
47  *
48  * NOTE: The filter_length must be multiple of four. Therefore the filter must
49  * be padded from the end with zeros have this condition met.
50  */
51 
52 struct sof_eq_fir_config {
53 	uint32_t size;
54 	uint16_t channels_in_config;
55 	uint16_t number_of_responses;
56 
57 	/* reserved */
58 	uint32_t reserved[4];
59 
60 	int16_t data[];
61 } __attribute__((packed));
62 
63 /* IIR EQ type */
64 
65 #define SOF_EQ_IIR_IDX_SWITCH   0
66 
67 #define SOF_EQ_IIR_MAX_SIZE 1024 /* Max size allowed for coef data in bytes */
68 
69 #define SOF_EQ_IIR_MAX_RESPONSES 8 /* A blob can define max 8 IIR EQs */
70 
71 /* eq_iir_configuration
72  *     uint32_t channels_in_config
73  *         This describes the number of channels in this EQ config data. It
74  *         can be different from PLATFORM_MAX_CHANNELS.
75  *     uint32_t number_of_responses_defined
76  *         0=no responses, 1=one response defined, 2=two responses defined, etc.
77  *     int32_t data[]
78  *         Data consist of two parts. First is the response assign vector that
79  *	   has length of channels_in_config. The latter part is coefficient
80  *         data.
81  *         uint32_t assign_response[channels_in_config]
82  *             -1 = not defined, 0 = use first response, 1 = use 2nd, etc.
83  *             E.g. {0, 0, 0, 0, -1, -1, -1, -1} would apply to channels 0-3 the
84  *             same first defined response and leave channels 4-7 unequalized.
85  *         coefficient_data[]
86  *             <1st EQ>
87  *             uint32_t num_biquads
88  *             uint32_t num_biquads_in_series
89  *             <1st biquad>
90  *             int32_t coef_a2       Q2.30 format
91  *             int32_t coef_a1       Q2.30 format
92  *             int32_t coef_b2       Q2.30 format
93  *             int32_t coef_b1       Q2.30 format
94  *             int32_t coef_b0       Q2.30 format
95  *             int32_t output_shift  number of shifts right, shift left is negative
96  *             int32_t output_gain   Q2.14 format
97  *             <2nd biquad>
98  *             ...
99  *             <2nd EQ>
100  *
101  *         Note: A flat response biquad can be made with a section set to
102  *         b0 = 1.0, gain = 1.0, and other parameters set to 0
103  *         {0, 0, 0, 0, 1073741824, 0, 16484}
104  */
105 
106 struct sof_eq_iir_config {
107 	uint32_t size;
108 	uint32_t channels_in_config;
109 	uint32_t number_of_responses;
110 
111 	/* reserved */
112 	uint32_t reserved[4];
113 
114 	int32_t data[]; /* eq_assign[channels], eq 0, eq 1, ... */
115 } __attribute__((packed));
116 
117 struct sof_eq_iir_header_df2t {
118 	uint32_t num_sections;
119 	uint32_t num_sections_in_series;
120 
121 	/* reserved */
122 	uint32_t reserved[4];
123 
124 	int32_t biquads[]; /* Repeated biquad coefficients */
125 } __attribute__((packed));
126 
127 struct sof_eq_iir_biquad_df2t {
128 	int32_t a2; /* Q2.30 */
129 	int32_t a1; /* Q2.30 */
130 	int32_t b2; /* Q2.30 */
131 	int32_t b1; /* Q2.30 */
132 	int32_t b0; /* Q2.30 */
133 	int32_t output_shift; /* Number of right shifts */
134 	int32_t output_gain;  /* Q2.14 */
135 } __attribute__((packed));
136 
137 /* A full 22th order equalizer with 11 biquads cover octave bands 1-11 in
138  * in the 0 - 20 kHz bandwidth.
139  */
140 #define SOF_EQ_IIR_DF2T_BIQUADS_MAX 11
141 
142 /* The number of int32_t words in sof_eq_iir_header_df2t:
143  *	num_sections, num_sections_in_series, reserved[4]
144  */
145 #define SOF_EQ_IIR_NHEADER_DF2T \
146 	(sizeof(struct sof_eq_iir_header_df2t) / sizeof(int32_t))
147 
148 /* The number of int32_t words in sof_eq_iir_biquad_df2t:
149  *	a2, a1, b2, b1, b0, output_shift, output_gain
150  */
151 #define SOF_EQ_IIR_NBIQUAD_DF2T \
152 	(sizeof(struct sof_eq_iir_biquad_df2t) / sizeof(int32_t))
153 
154 #endif /* __USER_EQ_H__ */
155