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