GCC Code Coverage Report


Directory: avs_core/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 87.0% 147 / 0 / 169
Functions: 90.0% 18 / 0 / 20
Branches: 85.7% 48 / 0 / 56

convert/convert_audio_c.cpp
Line Branch Exec Source
1 // Avisynth+
2 // https://avs-plus.net
3 //
4 // This file is part of Avisynth+ which is released under GPL2+ with exception.
5
6 // Convert Audio helper functions (Pure C)
7 // Copyright (c) 2020 Xinyue Lu, (c) 2021 pinterf
8
9 #include <avs/types.h>
10
11 /* Supported fast route conversions:
12 *
13 * | From: | U 8 | S16 | S24 | S32 | FLT |
14 * | To: | | | | | |
15 * | U 8 | - | CS | CS | CS | CSA |
16 * | S16 | CS | - | CS | CSA | CSA |
17 * | S24 | CS | CS | - | CS | |
18 * | S32 | CS | CSA | CS | - | CSA |
19 * | FLT | CSA | CSA | | CSA | - |
20 *
21 * * C = C, S = SSE2+, A = AVX2
22 */
23
24 /*
25 8 bit: unsigned (middle point 128)
26 16,24,32 bit: signed
27 32 bit float: -1.0 .. 1.0
28
29 Assymetric range considerations.
30
31 Android: It is implementation dependent whether the positive maximum of 1.0 is included in the interval
32 when converting to integer representation
33
34 Method 1 (e.g. Android): smallest number is full scale, 1.0 is clamped to 1.0 minus one LSB
35 -0x8000 - 0x7FFF is valid, nominally +1.0 (top of range) is not part of the range [-1.0..1.0)
36 Method 2: largest number is full scale
37 -0x7FFF - 0x7FFF, while -8000 exceeds lower limit. [-1.0..1.0] + smallest value is theoretically invalid
38
39 */
40
41 // until 3.6.1: S16 = (S32 + 0x8000) >> 16 (plain round-before shift)
42 // Actual: S16 = S32 >> 16
43 6 void convert32To16(void *inbuf, void *outbuf, int count) {
44 6 auto in16 = reinterpret_cast<int16_t *>(inbuf);
45 6 auto out = reinterpret_cast<int16_t *>(outbuf);
46
47
2/2
✓ Branch 4 → 3 taken 72 times.
✓ Branch 4 → 5 taken 6 times.
78 for (int i = 0; i < count; i++)
48 72 out[i] = in16[i * 2 + 1];
49 6 }
50
51 // until 3.6.1: S32 = (S16 << 16) + (unsigned short)(S16 + 32768)
52 // 0x7fff -> 0x7fffffff, 0x8000 -> 0x80000000
53 // Actual: S32 = S16 << 16
54 6 void convert16To32(void *inbuf, void *outbuf, int count) {
55 6 auto in = reinterpret_cast<int16_t *>(inbuf);
56 6 auto out16 = reinterpret_cast<int16_t *>(outbuf);
57
58
2/2
✓ Branch 4 → 3 taken 72 times.
✓ Branch 4 → 5 taken 6 times.
78 for (int i = 0; i < count; i++) {
59 72 out16[i * 2] = 0;
60 72 out16[i * 2 + 1] = in[i];
61 }
62 6 }
63
64 6 void convert32To8(void* inbuf, void* outbuf, int count) {
65 6 auto in8 = reinterpret_cast<int8_t*>(inbuf);
66 6 auto out = reinterpret_cast<uint8_t*>(outbuf);
67
68
2/2
✓ Branch 4 → 3 taken 72 times.
✓ Branch 4 → 5 taken 6 times.
78 for (int i = 0; i < count; i++)
69 72 out[i] = in8[i * 4 + 3] + 128;
70 6 }
71
72 6 void convert8To32(void *inbuf, void *outbuf, int count) {
73 6 auto in = reinterpret_cast<uint8_t *>(inbuf);
74 6 auto out8 = reinterpret_cast<int8_t *>(outbuf);
75
76
2/2
✓ Branch 4 → 3 taken 72 times.
✓ Branch 4 → 5 taken 6 times.
78 for (int i = 0; i < count; i++) {
77 72 out8[i * 4] = 0;
78 72 out8[i * 4 + 1] = 0;
79 72 out8[i * 4 + 2] = 0;
80 72 out8[i * 4 + 3] = in[i] - 128;
81 }
82 6 }
83
84 6 void convert16To8(void *inbuf, void *outbuf, int count) {
85 6 auto in8 = reinterpret_cast<int8_t *>(inbuf);
86 6 auto out = reinterpret_cast<uint8_t *>(outbuf);
87
88
2/2
✓ Branch 4 → 3 taken 72 times.
✓ Branch 4 → 5 taken 6 times.
78 for (int i = 0; i < count; i++)
89 72 out[i] = in8[i * 2 + 1] + 128;
90 6 }
91
92 // until 3.6.1: S16 = (S8 << 8) + (unsigned short)(S8 + 128)
93 // This make 0x7f(255-128) -> 0x7fff & 0x80(0-128) -> 0x8000
94 // Actual: S16 = (U8-128) << 8
95 6 void convert8To16(void *inbuf, void *outbuf, int count) {
96 6 auto in = reinterpret_cast<uint8_t *>(inbuf);
97 6 auto out8 = reinterpret_cast<int8_t *>(outbuf);
98
99
2/2
✓ Branch 4 → 3 taken 72 times.
✓ Branch 4 → 5 taken 6 times.
78 for (int i = 0; i < count; i++) {
100 72 out8[i * 2] = 0;
101 72 out8[i * 2 + 1] = in[i] - 128;
102 }
103 6 }
104
105 21 void convert32To24(void *inbuf, void *outbuf, int count) {
106 21 auto in8 = reinterpret_cast<int8_t *>(inbuf);
107 21 auto out8 = reinterpret_cast<int8_t *>(outbuf);
108
109
2/2
✓ Branch 4 → 3 taken 228 times.
✓ Branch 4 → 5 taken 21 times.
249 for (int i = 0; i < count; i++) {
110 228 out8[i * 3 + 0] = in8[i * 4 + 1];
111 228 out8[i * 3 + 1] = in8[i * 4 + 2];
112 228 out8[i * 3 + 2] = in8[i * 4 + 3];
113 }
114 21 }
115
116 21 void convert24To32(void *inbuf, void *outbuf, int count) {
117 21 auto in8 = reinterpret_cast<int8_t *>(inbuf);
118 21 auto out8 = reinterpret_cast<int8_t *>(outbuf);
119
120
2/2
✓ Branch 4 → 3 taken 228 times.
✓ Branch 4 → 5 taken 21 times.
249 for (int i = 0; i < count; i++) {
121 228 out8[i * 4] = 0;
122 228 out8[i * 4 + 1] = in8[i * 3 + 0];
123 228 out8[i * 4 + 2] = in8[i * 3 + 1];
124 228 out8[i * 4 + 3] = in8[i * 3 + 2];
125 }
126 21 }
127
128 3 void convert24To16(void *inbuf, void *outbuf, int count) {
129 3 auto in8 = reinterpret_cast<int8_t *>(inbuf);
130 3 auto out8 = reinterpret_cast<int8_t *>(outbuf);
131
132
2/2
✓ Branch 4 → 3 taken 48 times.
✓ Branch 4 → 5 taken 3 times.
51 for (int i = 0; i < count; i++) {
133 48 out8[i * 2 + 0] = in8[i * 3 + 1];
134 48 out8[i * 2 + 1] = in8[i * 3 + 2];
135 }
136 3 }
137
138 3 void convert16To24(void *inbuf, void *outbuf, int count) {
139 3 auto in8 = reinterpret_cast<int8_t *>(inbuf);
140 3 auto out8 = reinterpret_cast<int8_t *>(outbuf);
141
142
2/2
✓ Branch 4 → 3 taken 48 times.
✓ Branch 4 → 5 taken 3 times.
51 for (int i = 0; i < count; i++) {
143 48 out8[i * 3] = 0;
144 48 out8[i * 3 + 1] = in8[i * 2 + 0];
145 48 out8[i * 3 + 2] = in8[i * 2 + 1];
146 }
147 3 }
148
149 3 void convert24To8(void *inbuf, void *outbuf, int count) {
150 3 auto in8 = reinterpret_cast<int8_t *>(inbuf);
151 3 auto out = reinterpret_cast<uint8_t *>(outbuf);
152
153
2/2
✓ Branch 4 → 3 taken 48 times.
✓ Branch 4 → 5 taken 3 times.
51 for (int i = 0; i < count; i++)
154 48 out[i] = in8[i * 3 + 2] + 128;
155 3 }
156
157 3 void convert8To24(void *inbuf, void *outbuf, int count) {
158 3 auto in = reinterpret_cast<uint8_t *>(inbuf);
159 3 auto out8 = reinterpret_cast<int8_t *>(outbuf);
160
161
2/2
✓ Branch 4 → 3 taken 48 times.
✓ Branch 4 → 5 taken 3 times.
51 for (int i = 0; i < count; i++) {
162 48 out8[i * 3] = 0;
163 48 out8[i * 3 + 1] = 0;
164 48 out8[i * 3 + 2] = in[i] - 128;
165 }
166 3 }
167
168 9 void convert8ToFLT(void* inbuf, void* outbuf, int count) {
169 9 auto in = reinterpret_cast<uint8_t*>(inbuf);
170 9 auto out = reinterpret_cast<SFLOAT*>(outbuf);
171 9 constexpr float divisor = 1.0f / 128.f; // 1 << 7
172
173
2/2
✓ Branch 4 → 3 taken 84 times.
✓ Branch 4 → 5 taken 9 times.
93 for (int i = 0; i < count; i++)
174 84 out[i] = (in[i] - 128) * divisor;
175 9 }
176
177 10 void convertFLTTo8(void* inbuf, void* outbuf, int count) {
178 10 auto in = reinterpret_cast<SFLOAT*>(inbuf);
179 10 auto out = reinterpret_cast<uint8_t*>(outbuf);
180 10 constexpr float multiplier = 128.f;
181 10 constexpr float max8 = 127.f;
182 10 constexpr float min8 = -128.f;
183
184
2/2
✓ Branch 9 → 3 taken 101 times.
✓ Branch 9 → 10 taken 10 times.
111 for (int i = 0; i < count; i++) {
185 101 float val = in[i] * multiplier;
186 uint8_t result;
187
2/2
✓ Branch 3 → 4 taken 10 times.
✓ Branch 3 → 5 taken 91 times.
101 if (val >= max8) result = 255;
188
2/2
✓ Branch 5 → 6 taken 19 times.
✓ Branch 5 → 7 taken 72 times.
91 else if (val <= min8) result = 0;
189 72 else result = static_cast<int8_t>(val) + 128;
190 101 out[i] = result;
191 }
192 10 }
193
194 9 void convert16ToFLT(void* inbuf, void* outbuf, int count) {
195 9 auto in = reinterpret_cast<int16_t*>(inbuf);
196 9 auto out = reinterpret_cast<SFLOAT*>(outbuf);
197 9 constexpr float divisor = 1.0f / 32768.f; // 1 << 15
198
199
2/2
✓ Branch 4 → 3 taken 84 times.
✓ Branch 4 → 5 taken 9 times.
93 for (int i = 0; i < count; i++)
200 84 out[i] = in[i] * divisor;
201 9 }
202
203 10 void convertFLTTo16(void* inbuf, void* outbuf, int count) {
204 10 auto in = reinterpret_cast<SFLOAT*>(inbuf);
205 10 auto out = reinterpret_cast<int16_t*>(outbuf);
206 10 constexpr float multiplier = 32768.f;
207 10 constexpr float max16 = 32767.f;
208 10 constexpr float min16 = -32768.f;
209
210
2/2
✓ Branch 9 → 3 taken 101 times.
✓ Branch 9 → 10 taken 10 times.
111 for (int i = 0; i < count; i++) {
211 101 float val = in[i] * multiplier;
212 int16_t result;
213
2/2
✓ Branch 3 → 4 taken 10 times.
✓ Branch 3 → 5 taken 91 times.
101 if (val >= max16) result = 32767;
214
2/2
✓ Branch 5 → 6 taken 19 times.
✓ Branch 5 → 7 taken 72 times.
91 else if (val <= min16) result = (int16_t)-32768;
215 72 else result = static_cast<int16_t>(val);
216 101 out[i] = result;
217 }
218 10 }
219
220 // not yet used directly, 24 bit has 32 bit 2nd stage
221 void convert24ToFLT(void* inbuf, void* outbuf, int count) {
222 auto in = reinterpret_cast<uint8_t*>(inbuf);
223 auto out = reinterpret_cast<SFLOAT*>(outbuf);
224 constexpr float divisor = 1.0f / 8388608.f; // 1 << 23
225
226 for (int i = 0; i < count; i++)
227 out[i] = (in[i * 3] | (in[i * 3 + 1] << 8) | (in[i * 3 + 2] << 16)) * divisor;
228 }
229
230 // not yet used directly, 24 bit has 32 bit 2nd stage
231 void convertFLTTo24(void* inbuf, void* outbuf, int count) {
232 auto in = reinterpret_cast<SFLOAT*>(inbuf);
233 auto out = reinterpret_cast<uint8_t*>(outbuf);
234 constexpr float multiplier = 8388608.f;
235 constexpr float max24 = 8388607.f;
236 constexpr float min24 = -8388608.f;
237
238 for (int i = 0; i < count; i++) {
239 float val = in[i] * multiplier;
240 int32_t result;
241 if (val >= max24) result = 0x7FFFFF; // 8388607
242 else if (val <= min24) result = 0x800000; // -8388608
243 else result = static_cast<int32_t>(val);
244 out[i * 3 + 0] = result & 0xFF;
245 out[i * 3 + 1] = (result >> 8) & 0xFF;
246 out[i * 3 + 2] = (result >> 16) & 0xFF;
247 }
248 }
249
250 // note for 32 bit conversions: 32 bit integer cannot be represented in float
251 // 2147483647.0f is 2147483648.0f in reality
252
253 21 void convert32ToFLT(void *inbuf, void *outbuf, int count) {
254 21 auto in = reinterpret_cast<int32_t *>(inbuf);
255 21 auto out = reinterpret_cast<SFLOAT *>(outbuf);
256 21 constexpr float divisor = 1.0f/2147483648.0f;
257
258
2/2
✓ Branch 4 → 3 taken 204 times.
✓ Branch 4 → 5 taken 21 times.
225 for (int i = 0; i < count; i++)
259 204 out[i] = in[i] * divisor;
260 21 }
261
262 22 void convertFLTTo32(void *inbuf, void *outbuf, int count) {
263 22 auto in = reinterpret_cast<SFLOAT *>(inbuf);
264 22 auto out = reinterpret_cast<int32_t *>(outbuf);
265 22 constexpr float multiplier = 2147483648.0f;
266 22 constexpr float max32 = 2147483647.0f;
267 22 constexpr float min32 = -2147483648.0f;
268
269
2/2
✓ Branch 9 → 3 taken 221 times.
✓ Branch 9 → 10 taken 22 times.
243 for (int i = 0; i < count; i++) {
270 221 float val = in[i] * multiplier;
271 int32_t result;
272
2/2
✓ Branch 3 → 4 taken 17 times.
✓ Branch 3 → 5 taken 204 times.
221 if (val >= max32) result = 0x7FFFFFFF; // 2147483647
273
2/2
✓ Branch 5 → 6 taken 43 times.
✓ Branch 5 → 7 taken 161 times.
204 else if (val <= min32) result = 0x80000000; // -2147483648
274 161 else result = static_cast<int32_t>(val);
275 221 out[i] = result;
276 }
277 22 }
278