OSDN Git Service

[BUILD][CMAKE] Add falback values.Merge toolchain for native gcc into a file.
[csp-qt/common_source_project-fm7.git] / source / src / qt / osd_sound_mod_utils.h
1 #pragma once
2 #include "./osd_sound_mod_consts.h"
3
4 #include <limits>
5 namespace SOUND_MODULE {
6 /* SOUND_MODULE */
7         
8         static inline const __BYTEORDER get_system_byteorder()
9         {
10                 #ifdef __LITTLE_ENDIAN__
11                 return __BYTEORDER::Little;
12                 #else
13                 return __BYTEORDER::Big;
14                 #endif
15         }
16         inline bool check_attribute(sound_attribute a)
17         {
18                 if((a.word_size == 0) || (a.word_size > 16)) return false;
19                 if((a.channels == 0) || (a.channels > 8)) return false;
20                 return true;
21         }
22         
23         inline bool compare_attribute(sound_attribute src, sound_attribute dst)
24         {
25                 bool _b = true;
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);
30                 return _b;
31         }
32
33         
34         template <typename T>
35         size_t swap_endian(T* src, T* dst, size_t words)
36         {
37                 if(words == 0) return 0;
38                 const size_t wordsize = sizeof(T);
39                 
40                 typedef union _t_pair_t {
41                         T               data;
42                         uint8_t u8[sizeof(T)];
43                 };
44                 T* p = src;
45                 T* q = dst;
46                 
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;
51                 
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];
56                         }
57
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];
63                                 }
64                         }
65                         
66                 __DECL_VECTORIZED_LOOP
67                         for(size_t j = 0; j < 8; j++) {
68                                 q[j] = dstbuf[j].data;
69                         }
70                         q += 8;
71                         p += 8;
72                 }
73                 _t_pair_t __tmp;
74                 _t_pair_t __dst;
75                 for(size_t i = 0; i < minor_words; i++) {
76                         __tmp.data = p[i];
77                         for(size_t k = 0; k < sizeof(T); k++) {
78                                 __dst.u8[k] = __tmp.u8[sizeof(T) - k - 1]; 
79                         }
80                         q[i] = __dst.data;
81                 }
82                 return words;
83         }
84         template <>
85         size_t swap_endian(uint8_t* src, uint8_t* dst, size_t words)
86         {
87                 if(words == 0) return 0;
88                 if((uintptr_t)src == (uintptr_t)dst) return words;
89                 memcpy(dst, src, words);
90                 return words;
91         }       
92         template <>
93         size_t swap_endian(int8_t* src, int8_t* dst, size_t words)
94         {
95                 if(words == 0) return 0;
96                 if((uintptr_t)src == (uintptr_t)dst) return words;
97                 memcpy(dst, src, words);
98                 return words;
99         }
100         
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)
104         {
105                 if(dst == nullptr) return 0;
106                 if(src == nullptr) return 0;
107                 if(words == 0) return 0;
108
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;
113                 
114                 enum {
115                         src_false = 0,
116                         src_true  = 1,
117                         dst_false = 0,
118                         dst_true  = 2
119                 };
120
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);
124                 
125                 S* p = src;
126                 D* q = dst;
127                 __DECL_ALIGNED(16) S srcbuf[8];
128                 __DECL_ALIGNED(16) D dstbuf[8];
129                 
130                 switch(type_is_int) {
131                 case (src_false | dst_false):
132                         // Both float or double
133                         {
134                                 for(size_t i = 0; i < major_nwords; i++) {
135                                 __DECL_VECTORIZED_LOOP
136                                         for(size_t j = 0; j < 8; j++) {
137                                                 srcbuf[j] = p[j];
138                                         }
139                                 __DECL_VECTORIZED_LOOP
140                                         for(size_t j = 0; j < 8; j++) {
141                                                 dstbuf[j] = (D)(srcbuf[j]);
142                                         }
143                                 __DECL_VECTORIZED_LOOP
144                                         for(size_t j = 0; j < 8; j++) {
145                                                 q[j] = dstbuf[j];
146                                         }
147                                         p += 8;
148                                         q += 8;
149                                 }
150                                 for(size_t j = 0; j < minor_words; j++) {
151                                         q[j] = (D)(p[j]);
152                                 }
153                         }
154                         break;
155                 case (src_true | dst_false):
156                         // src is signed or unsigned int, dst is float or double
157                         {
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];
161                                 
162                                 if(std::numeric_limits<S>::is_signed()) {
163                                         // Signed
164                                         for(size_t i = 0; i < major_nwords; i++) {
165                                         __DECL_VECTORIZED_LOOP
166                                                 for(size_t j = 0; j < 8; j++) {
167                                                         srcbuf[j] = p[j];
168                                                 }
169                                         __DECL_VECTORIZED_LOOP
170                                                 for(size_t j = 0; j < 8; j++) {
171                                                         srcbuf_2[j] = (D)(srcbuf[j]);
172                                                 }
173                                         __DECL_VECTORIZED_LOOP
174                                                 for(size_t j = 0; j < 8; j++) {
175                                                         dstbuf[j] = srcbuf_2[j] / src_max[j];
176                                                 }
177                                         __DECL_VECTORIZED_LOOP
178                                                 for(size_t j = 0; j < 8; j++) {
179                                                         q[j] = dstbuf[j];
180                                                 }
181                                                 p += 8;
182                                                 q += 8;
183                                         }
184                                         for(size_t j = 0; j < minor_words; j++) {
185                                                 D _tmp = (D)(p[j]);
186                                                 _tmp = _tmp / tmp_src_max;
187                                                 q[j] = _tmp;
188                                         }
189                                 } else {
190                                         // Unsigned
191                                         for(size_t i = 0; i < major_nwords; i++) {
192                                         __DECL_VECTORIZED_LOOP
193                                                 for(size_t j = 0; j < 8; j++) {
194                                                         srcbuf[j] = p[j];
195                                                 }
196                                         __DECL_VECTORIZED_LOOP
197                                                 for(size_t j = 0; j < 8; j++) {
198                                                         srcbuf_2[j] = (D)(srcbuf[j]);
199                                                 }
200                                         __DECL_VECTORIZED_LOOP
201                                                 for(size_t j = 0; j < 8; j++) {
202                                                         dstbuf[j] = (srcbuf_2[j] / src_max[j]) - 0.5;
203                                                 }
204                                         __DECL_VECTORIZED_LOOP
205                                                 for(size_t j = 0; j < 8; j++) {
206                                                         q[j] = dstbuf[j];
207                                                 }
208                                                 p += 8;
209                                                 q += 8;
210                                         }
211                                         for(size_t j = 0; j < minor_words; j++) {
212                                                 D _tmp = (D)(p[j]);
213                                                 _tmp = (_tmp / tmp_src_max) - 0.5;
214                                                 q[j] = _tmp;
215                                         }
216                                 }
217                         }
218                         break;
219                 case (src_false | dst_true):
220                         //  src is float or double, dst is signed or unsigned int
221                         {
222                                 const S tmp_dst_max = (S)(dst_limit.max()) + 1.0;
223                                 __DECL_ALIGNED(16) const S dst_max[8] = {tmp_dst_max};
224                 
225                                 if(std::numeric_limits<S>::is_signed()) {
226                                         // Signed
227                                         for(size_t i = 0; i < major_nwords; i++) {
228                                         __DECL_VECTORIZED_LOOP
229                                                 for(size_t j = 0; j < 8; j++) {
230                                                         srcbuf[j] = p[j];
231                                                 }
232                                         __DECL_VECTORIZED_LOOP
233                                                 for(size_t j = 0; j < 8; j++) {
234                                                         srcbuf[j] = srcbuf[j] * dst_max[j];
235                                                 }
236                                         __DECL_VECTORIZED_LOOP
237                                                 for(size_t j = 0; j < 8; j++) {
238                                                         dstbuf[j] = (D)(srcbuf[j]);
239                                                 }
240                                         __DECL_VECTORIZED_LOOP
241                                                 for(size_t j = 0; j < 8; j++) {
242                                                         q[j] = dstbuf[j];
243                                                 }
244                                                 p += 8;
245                                                 q += 8;
246                                         }
247                                         for(size_t j = 0; j < minor_words; j++) {
248                                                 S _tmp = p[j];
249                                                 _tmp = _tmp * tmp_dst_max;
250                                                 q[j] = (D)_tmp;
251                                         }
252                                 } else {
253                                         // Unsigned
254                                         for(size_t i = 0; i < major_nwords; i++) {
255                                         __DECL_VECTORIZED_LOOP
256                                                 for(size_t j = 0; j < 8; j++) {
257                                                         srcbuf[j] = p[j];
258                                                 }
259                                         __DECL_VECTORIZED_LOOP
260                                                 for(size_t j = 0; j < 8; j++) {
261                                                         srcbuf[j] = (srcbuf[j] + 0.5)  * dst_max[j];
262                                                 }
263                                         __DECL_VECTORIZED_LOOP
264                                                 for(size_t j = 0; j < 8; j++) {
265                                                         dstbuf[j] = (D)(srcbuf[j]);
266                                                 }
267                                         __DECL_VECTORIZED_LOOP
268                                                 for(size_t j = 0; j < 8; j++) {
269                                                         q[j] = dstbuf[j];
270                                                 }
271                                                 p += 8;
272                                                 q += 8;
273                                         }
274                                         for(size_t j = 0; j < minor_words; j++) {
275                                                 S _tmp = p[j];
276                                                 _tmp = (_tmp + 0.5) * tmp_dst_max;
277                                                 q[j] = (D)_tmp;
278                                         }
279                                 }
280                         }
281                         break;
282                 default:
283                         //  both src and dst are signed or unsigned int
284                         {
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);
288                                 
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;
292                                 
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;
296
297                                 D tmp_offset;
298                                 switch(type_is_signed) {
299                                 case (src_true | dst_false): // signed -> unsigned
300                                         tmp_offset = (D)tmp_src_max + 1;
301                                         break;
302                                 case (src_false | dst_true): // unsigned -> signed
303                                         tmp_offset = -((D)tmp_src_max + 1);
304                                         break;
305                                 default:
306                                         // unsigned -> unsigned
307                                         // signed -> signed
308                                         tmp_offset = 0;
309                                         break;
310                                 }
311                                 if(bit_width_diff <= 0) {
312                                         tmp_offset = 0;
313                                 }
314                                 if((tmp_offset == 0) && (bit_width_diff == 0)) {
315                                         // Same signess && Same bitwidth
316                                         memdpy(dst, src, words * sizeof(D));
317                                         return words;
318                                 }
319                                 __DECL_ALIGNED(16) const D bitfill[8] = {tmp_bitfill};
320                                 __DECL_ALIGNED(16) const D _offset[8] = {tmp_offset};
321                                 
322                                 for(size_t i = 0; i < major_nwords; i++) {
323                                 __DECL_VECTORIZED_LOOP
324                                         for(size_t j = 0; j < 8; j++) {
325                                                 srcbuf[j] = p[j];
326                                         }
327                                 __DECL_VECTORIZED_LOOP
328                                         for(size_t j = 0; j < 8; j++) {
329                                                 dstbuf[j] = (D)(srcbuf[j]);
330                                         }
331                                 __DECL_VECTORIZED_LOOP
332                                         for(size_t j = 0; j < 8; j++) {
333                                                 dstbuf[j] += _offset[j];
334                                         }
335                                 __DECL_VECTORIZED_LOOP
336                                         for(size_t j = 0; j < 8; j++) {
337                                                 dstbuf[j] <<= bit_width_diff;
338                                         }
339                                 __DECL_VECTORIZED_LOOP
340                                         for(size_t j = 0; j < 8; j++) {
341                                                 dstbuf[j] |= bitfill[j];
342                                         }
343                                 __DECL_VECTORIZED_LOOP
344                                         for(size_t j = 0; j < 8; j++) {
345                                                 q[j] = dstbuf[j];
346                                         }
347                                         p += 8;
348                                         q += 8;
349                                 }
350                                 for(size_t j = 0; j < minor_words; j++) {
351                                         D tmp = (D)(p[j]);
352                                         tmp += tmp_offset;
353                                         tmp <<= bit_width_diff;
354                                         tmp |= tmp_bitfill;
355                                         q[j] = tmp;
356                                 }
357                         }
358                         break;
359                 }
360                 return words;
361         }
362         
363 /* SOUND_MODULE */
364 }