2 #include "./osd_sound_mod_consts.h"
5 namespace SOUND_MODULE {
8 static inline const __BYTEORDER get_system_byteorder()
10 #ifdef __LITTLE_ENDIAN__
11 return __BYTEORDER::Little;
13 return __BYTEORDER::Big;
16 inline bool check_attribute(sound_attribute a)
18 if((a.word_size == 0) || (a.word_size > 16)) return false;
19 if((a.channels == 0) || (a.channels > 8)) return false;
23 inline bool compare_attribute(sound_attribute src, sound_attribute dst)
26 _b &= (src.format == dst.format);
27 _b &= (src.endian == dst.endian);
28 _b &= (src.word_size == dst.word_size);
29 _b &= (src.channels == dst.channels);
35 size_t swap_endian(T* src, T* dst, size_t words)
37 if(words == 0) return 0;
38 const size_t wordsize = sizeof(T);
40 typedef union _t_pair_t {
42 uint8_t u8[sizeof(T)];
47 __DECL_ALIGNED(16) _t_pair_t tmpbuf[8];
48 __DECL_ALIGNED(16) _t_pair_t dstbuf[8];
49 const size_t major_words = words / 8;
50 const size_t minor_words = words % 8;
52 for(size_t i = 0; i < major_words; i++) {
53 __DECL_VECTORIZED_LOOP
54 for(size_t j = 0; j < 8; j++) {
55 tmpbuf[j].data = p[j];
58 __DECL_VECTORIZED_LOOP
59 for(size_t j = 0; j < 8; j++) {
60 __DECL_VECTORIZED_LOOP
61 for(size_t k = 0; k < sizeof(T); k++) {
62 dstbuf[j].u8[k] = tmpbuf[j].u8[sizeof(T) - k - 1];
66 __DECL_VECTORIZED_LOOP
67 for(size_t j = 0; j < 8; j++) {
68 q[j] = dstbuf[j].data;
75 for(size_t i = 0; i < minor_words; i++) {
77 for(size_t k = 0; k < sizeof(T); k++) {
78 __dst.u8[k] = __tmp.u8[sizeof(T) - k - 1];
85 size_t swap_endian(uint8_t* src, uint8_t* dst, size_t words)
87 if(words == 0) return 0;
88 if((uintptr_t)src == (uintptr_t)dst) return words;
89 memcpy(dst, src, words);
93 size_t swap_endian(int8_t* src, int8_t* dst, size_t words)
95 if(words == 0) return 0;
96 if((uintptr_t)src == (uintptr_t)dst) return words;
97 memcpy(dst, src, words);
101 /* convert format for both of integer variants */
102 template <typename S, typename D>
103 size_t convert_format(D* dst, S* src, size_t words)
105 if(dst == nullptr) return 0;
106 if(src == nullptr) return 0;
107 if(words == 0) return 0;
109 std::numeric_limits<S> src_limit;
110 std::numeric_limits<D> dst_limit;
111 size_t major_nwords = words / 8;
112 size_t minor_words = words % 8;
121 uint8_t type_is_int =
122 (std::numeric_limits<S>::is_exact() ? src_true : src_false) |
123 (std::numeric_limits<D>::is_exact() ? dst_true : dst_false);
127 __DECL_ALIGNED(16) S srcbuf[8];
128 __DECL_ALIGNED(16) D dstbuf[8];
130 switch(type_is_int) {
131 case (src_false | dst_false):
132 // Both float or double
134 for(size_t i = 0; i < major_nwords; i++) {
135 __DECL_VECTORIZED_LOOP
136 for(size_t j = 0; j < 8; j++) {
139 __DECL_VECTORIZED_LOOP
140 for(size_t j = 0; j < 8; j++) {
141 dstbuf[j] = (D)(srcbuf[j]);
143 __DECL_VECTORIZED_LOOP
144 for(size_t j = 0; j < 8; j++) {
150 for(size_t j = 0; j < minor_words; j++) {
155 case (src_true | dst_false):
156 // src is signed or unsigned int, dst is float or double
158 const D tmp_src_max = (D)(src_limit.max());
159 __DECL_ALIGNED(16) const D src_max[8] = {tmp_src_max};
160 __DECL_ALIGNED(16) D srcbuf_2[8];
162 if(std::numeric_limits<S>::is_signed()) {
164 for(size_t i = 0; i < major_nwords; i++) {
165 __DECL_VECTORIZED_LOOP
166 for(size_t j = 0; j < 8; j++) {
169 __DECL_VECTORIZED_LOOP
170 for(size_t j = 0; j < 8; j++) {
171 srcbuf_2[j] = (D)(srcbuf[j]);
173 __DECL_VECTORIZED_LOOP
174 for(size_t j = 0; j < 8; j++) {
175 dstbuf[j] = srcbuf_2[j] / src_max[j];
177 __DECL_VECTORIZED_LOOP
178 for(size_t j = 0; j < 8; j++) {
184 for(size_t j = 0; j < minor_words; j++) {
186 _tmp = _tmp / tmp_src_max;
191 for(size_t i = 0; i < major_nwords; i++) {
192 __DECL_VECTORIZED_LOOP
193 for(size_t j = 0; j < 8; j++) {
196 __DECL_VECTORIZED_LOOP
197 for(size_t j = 0; j < 8; j++) {
198 srcbuf_2[j] = (D)(srcbuf[j]);
200 __DECL_VECTORIZED_LOOP
201 for(size_t j = 0; j < 8; j++) {
202 dstbuf[j] = (srcbuf_2[j] / src_max[j]) - 0.5;
204 __DECL_VECTORIZED_LOOP
205 for(size_t j = 0; j < 8; j++) {
211 for(size_t j = 0; j < minor_words; j++) {
213 _tmp = (_tmp / tmp_src_max) - 0.5;
219 case (src_false | dst_true):
220 // src is float or double, dst is signed or unsigned int
222 const S tmp_dst_max = (S)(dst_limit.max()) + 1.0;
223 __DECL_ALIGNED(16) const S dst_max[8] = {tmp_dst_max};
225 if(std::numeric_limits<S>::is_signed()) {
227 for(size_t i = 0; i < major_nwords; i++) {
228 __DECL_VECTORIZED_LOOP
229 for(size_t j = 0; j < 8; j++) {
232 __DECL_VECTORIZED_LOOP
233 for(size_t j = 0; j < 8; j++) {
234 srcbuf[j] = srcbuf[j] * dst_max[j];
236 __DECL_VECTORIZED_LOOP
237 for(size_t j = 0; j < 8; j++) {
238 dstbuf[j] = (D)(srcbuf[j]);
240 __DECL_VECTORIZED_LOOP
241 for(size_t j = 0; j < 8; j++) {
247 for(size_t j = 0; j < minor_words; j++) {
249 _tmp = _tmp * tmp_dst_max;
254 for(size_t i = 0; i < major_nwords; i++) {
255 __DECL_VECTORIZED_LOOP
256 for(size_t j = 0; j < 8; j++) {
259 __DECL_VECTORIZED_LOOP
260 for(size_t j = 0; j < 8; j++) {
261 srcbuf[j] = (srcbuf[j] + 0.5) * dst_max[j];
263 __DECL_VECTORIZED_LOOP
264 for(size_t j = 0; j < 8; j++) {
265 dstbuf[j] = (D)(srcbuf[j]);
267 __DECL_VECTORIZED_LOOP
268 for(size_t j = 0; j < 8; j++) {
274 for(size_t j = 0; j < minor_words; j++) {
276 _tmp = (_tmp + 0.5) * tmp_dst_max;
283 // both src and dst are signed or unsigned int
285 uint8_t type_is_signed =
286 (std::numeric_limits<S>::is_signed() ? src_true : src_false) |
287 (std::numeric_limits<D>::is_signed() ? dst_true : dst_false);
289 const ssize_t src_bit_width = sizeof(S) << 3;
290 const ssize_t dst_bit_width = sizeof(D) << 3;
291 const ssize_t bit_width_diff = dst_bit_width - src_bit_width;
293 const S tmp_src_max = src_limit.max();
294 const D tmp_dst_max = dst_limit.max();
295 const D tmp_bitfill = (bit_width_diff > 0) ? ((((D)1) << src_bit_width) - 1) & tmp_dst_max : 0;
298 switch(type_is_signed) {
299 case (src_true | dst_false): // signed -> unsigned
300 tmp_offset = (D)tmp_src_max + 1;
302 case (src_false | dst_true): // unsigned -> signed
303 tmp_offset = -((D)tmp_src_max + 1);
306 // unsigned -> unsigned
311 if(bit_width_diff <= 0) {
314 if((tmp_offset == 0) && (bit_width_diff == 0)) {
315 // Same signess && Same bitwidth
316 memdpy(dst, src, words * sizeof(D));
319 __DECL_ALIGNED(16) const D bitfill[8] = {tmp_bitfill};
320 __DECL_ALIGNED(16) const D _offset[8] = {tmp_offset};
322 for(size_t i = 0; i < major_nwords; i++) {
323 __DECL_VECTORIZED_LOOP
324 for(size_t j = 0; j < 8; j++) {
327 __DECL_VECTORIZED_LOOP
328 for(size_t j = 0; j < 8; j++) {
329 dstbuf[j] = (D)(srcbuf[j]);
331 __DECL_VECTORIZED_LOOP
332 for(size_t j = 0; j < 8; j++) {
333 dstbuf[j] += _offset[j];
335 __DECL_VECTORIZED_LOOP
336 for(size_t j = 0; j < 8; j++) {
337 dstbuf[j] <<= bit_width_diff;
339 __DECL_VECTORIZED_LOOP
340 for(size_t j = 0; j < 8; j++) {
341 dstbuf[j] |= bitfill[j];
343 __DECL_VECTORIZED_LOOP
344 for(size_t j = 0; j < 8; j++) {
350 for(size_t j = 0; j < minor_words; j++) {
353 tmp <<= bit_width_diff;