1 /* SPDX-License-Identifier: BSD-3-Clause
2 *
3 * Copyright(c) 2016 Intel Corporation. All rights reserved.
4 *
5 * Author: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
6 * Liam Girdwood <liam.r.girdwood@linux.intel.com>
7 * Keyon Jie <yang.jie@linux.intel.com>
8 */
9
10 #ifndef __SOF_AUDIO_FORMAT_H__
11 #define __SOF_AUDIO_FORMAT_H__
12
13 #if defined __XCC__
14 #include <xtensa/config/core-isa.h>
15 #if XCHAL_HAVE_HIFI3 == 1
16 #define __AUDIO_FORMAT_GENERIC__ 0
17 #define __AUDIO_FORMAT_HIFI3__ 1
18 #else
19 /* Generic build for e.g. hifi2 */
20 #define __AUDIO_FORMAT_GENERIC__ 1
21 #define __AUDIO_FORMAT_HIFI3__ 0
22 #endif /* !XCHAL_HAVE_HIFI3 */
23 #else
24 /* GCC */
25 #define __AUDIO_FORMAT_GENERIC__ 1
26 #define __AUDIO_FORMAT_HIFI3__ 0
27 #endif /* !__XCC__ */
28
29 #include <ipc/stream.h>
30 #include <stdint.h>
31
32 /* Maximum and minimum values for 24 bit */
33 #define INT24_MAXVALUE 8388607
34 #define INT24_MINVALUE -8388608
35
36 /* Collection of common fractional numbers */
37 #define ONE_Q2_30 1073741824 /* Q2.30 1.0 */
38 #define ONE_Q1_31 2147483647 /* Q1.31 ~1.0 */
39 #define MINUS_3DB_Q1_31 1520301996 /* 10^(-3/20) */
40 #define MINUS_6DB_Q1_31 1076291389 /* 10^(-6/20) */
41 #define MINUS_10DB_Q1_31 679093957 /* 10^(-10/20) */
42 #define MINUS_20DB_Q1_31 214748365 /* 10^(-20/20) */
43 #define MINUS_30DB_Q1_31 67909396 /* 10^(-30/20) */
44 #define MINUS_40DB_Q1_31 21474836 /* 10^(-40/20) */
45 #define MINUS_50DB_Q1_31 6790940 /* 10^(-50/20) */
46 #define MINUS_60DB_Q1_31 2147484 /* 10^(-60/20) */
47 #define MINUS_70DB_Q1_31 679094 /* 10^(-70/20) */
48 #define MINUS_80DB_Q1_31 214748 /* 10^(-80/20) */
49 #define MINUS_90DB_Q1_31 67909 /* 10^(-90/20) */
50
51 /* Compute the number of shifts
52 * This will result in a compiler overflow error if shift bits are out of
53 * range as INT64_MAX/MIN is greater than 32 bit Q shift parameter
54 */
55 #define Q_SHIFT_BITS_64(qx, qy, qz) \
56 ((qx + qy - qz) <= 63 ? (((qx + qy - qz) >= 0) ? \
57 (qx + qy - qz) : INT64_MIN) : INT64_MAX)
58
59 #define Q_SHIFT_BITS_32(qx, qy, qz) \
60 ((qx + qy - qz) <= 31 ? (((qx + qy - qz) >= 0) ? \
61 (qx + qy - qz) : INT32_MIN) : INT32_MAX)
62
63 /* Convert a float number to fractional Qnx.ny format. Note that there is no
64 * check for nx+ny number of bits to fit the word length of int. The parameter
65 * qy must be 31 or less.
66 */
67 #define Q_CONVERT_FLOAT(f, qy) \
68 ((int32_t)(((const double)f) * ((int64_t)1 << (const int)qy) + 0.5))
69
70 /* Convert fractional Qnx.ny number x to float */
71 #define Q_CONVERT_QTOF(x, ny) ((float)(x) / ((int64_t)1 << (ny)))
72
73 /* A more clever macro for Q-shifts */
74 #define Q_SHIFT(x, src_q, dst_q) ((x) >> ((src_q) - (dst_q)))
75 #define Q_SHIFT_RND(x, src_q, dst_q) \
76 ((((x) >> ((src_q) - (dst_q) - 1)) + 1) >> 1)
77
78 /* Alternative version since compiler does not allow (x >> -1) */
79 #define Q_SHIFT_LEFT(x, src_q, dst_q) ((x) << ((dst_q) - (src_q)))
80
81 /* Fractional multiplication with shift
82 * Note that the parameters px and py must be cast to (int32_t) if other type.
83 */
84 #define Q_MULTS_16X16(px, py, qx, qy, qp) \
85 ((px) * (py) >> (((qx) + (qy) - (qp))))
86
87 /* Fractional multiplication with shift and round
88 * Note that the parameters px and py must be cast to (int32_t) if other type.
89 */
90 #define Q_MULTSR_16X16(px, py, qx, qy, qp) \
91 ((((px) * (py) >> ((qx) + (qy) - (qp) - 1)) + 1) >> 1)
92
93 /* Fractional multiplication with shift
94 * Note that the parameters px and py must be cast to (int64_t) if other type.
95 */
96 #define Q_MULTS_32X32(px, py, qx, qy, qp) \
97 ((px) * (py) >> (((qx) + (qy) - (qp))))
98
99 /* Fractional multiplication with shift and round
100 * Note that the parameters px and py must be cast to (int64_t) if other type.
101 */
102 #define Q_MULTSR_32X32(px, py, qx, qy, qp) \
103 ((((px) * (py) >> ((qx) + (qy) - (qp) - 1)) + 1) >> 1)
104
105 /* Saturation */
106 #define SATP_INT32(x) (((x) > INT32_MAX) ? INT32_MAX : (x))
107 #define SATM_INT32(x) (((x) < INT32_MIN) ? INT32_MIN : (x))
108
109 /* Inline functions */
110
111 #if __AUDIO_FORMAT_GENERIC__
112 #include "format_generic.h"
113 #endif
114 #if __AUDIO_FORMAT_HIFI3__
115 #include "format_hifi3.h"
116 #endif
117
q_mults_32x32(int32_t x,int32_t y,const int shift_bits)118 static inline int64_t q_mults_32x32(int32_t x, int32_t y, const int shift_bits)
119 {
120 return ((int64_t)x * y) >> shift_bits;
121 }
122
q_multsr_32x32(int32_t x,int32_t y,const int shift_bits)123 static inline int64_t q_multsr_32x32(int32_t x, int32_t y, const int shift_bits)
124 {
125 return ((((int64_t)x * y) >> (shift_bits - 1)) + 1) >> 1;
126 }
127
q_mults_16x16(int16_t x,int32_t y,const int shift_bits)128 static inline int32_t q_mults_16x16(int16_t x, int32_t y, const int shift_bits)
129 {
130 return ((int32_t)x * y) >> shift_bits;
131 }
132
q_multsr_16x16(int16_t x,int32_t y,const int shift_bits)133 static inline int16_t q_multsr_16x16(int16_t x, int32_t y, const int shift_bits)
134 {
135 return ((((int32_t)x * y) >> (shift_bits - 1)) + 1) >> 1;
136 }
137
138 /* Fractional multiplication with shift and saturation */
q_multsr_sat_32x32(int32_t x,int32_t y,const int shift_bits)139 static inline int32_t q_multsr_sat_32x32(int32_t x, int32_t y,
140 const int shift_bits)
141 {
142 return sat_int32(((((int64_t)x * y) >> (shift_bits - 1)) + 1) >> 1);
143 }
144
q_multsr_sat_32x32_24(int32_t x,int32_t y,const int shift_bits)145 static inline int32_t q_multsr_sat_32x32_24(int32_t x, int32_t y,
146 const int shift_bits)
147 {
148 return sat_int24(((((int64_t)x * y) >> (shift_bits - 1)) + 1) >> 1);
149 }
150
q_multsr_sat_32x32_16(int32_t x,int32_t y,const int shift_bits)151 static inline int32_t q_multsr_sat_32x32_16(int32_t x, int32_t y,
152 const int shift_bits)
153 {
154 return sat_int16(((((int64_t)x * y) >> (shift_bits - 1)) + 1) >> 1);
155 }
156
q_multsr_sat_16x16(int16_t x,int32_t y,const int shift_bits)157 static inline int16_t q_multsr_sat_16x16(int16_t x, int32_t y,
158 const int shift_bits)
159 {
160 return sat_int16(((((int32_t)x * y) >> (shift_bits - 1)) + 1) >> 1);
161 }
162
sign_extend_s24(int32_t x)163 static inline int32_t sign_extend_s24(int32_t x)
164 {
165 return (x << 8) >> 8;
166 }
167
get_sample_bytes(enum sof_ipc_frame fmt)168 static inline uint32_t get_sample_bytes(enum sof_ipc_frame fmt)
169 {
170 switch (fmt) {
171 case SOF_IPC_FRAME_S16_LE:
172 return 2;
173 case SOF_IPC_FRAME_S24_3LE:
174 return 3;
175 default:
176 return 4;
177 }
178 }
179
get_frame_bytes(enum sof_ipc_frame fmt,uint32_t channels)180 static inline uint32_t get_frame_bytes(enum sof_ipc_frame fmt,
181 uint32_t channels)
182 {
183 return get_sample_bytes(fmt) * channels;
184 }
185
186 #endif /* __SOF_AUDIO_FORMAT_H__ */
187