1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* SPDX-FileCopyrightText: OpenMPT Project Developers and Contributors */
3 
4 
5 #pragma once
6 
7 #include "openmpt/all/BuildSettings.hpp"
8 
9 #include "mpt/base/floatingpoint.hpp"
10 #include "mpt/base/macros.hpp"
11 #include "mpt/base/memory.hpp"
12 #include "openmpt/base/Endian.hpp"
13 #include "openmpt/base/Types.hpp"
14 
15 #include <algorithm>
16 
17 #include <cmath>
18 #include <cstddef>
19 
20 
21 OPENMPT_NAMESPACE_BEGIN
22 
23 
24 // Byte offsets, from lowest significant to highest significant byte (for various functor template parameters)
25 #define littleEndian64 0, 1, 2, 3, 4, 5, 6, 7
26 #define littleEndian32 0, 1, 2, 3
27 #define littleEndian24 0, 1, 2
28 #define littleEndian16 0, 1
29 
30 #define bigEndian64 7, 6, 5, 4, 3, 2, 1, 0
31 #define bigEndian32 3, 2, 1, 0
32 #define bigEndian24 2, 1, 0
33 #define bigEndian16 1, 0
34 
35 
36 namespace SC
37 {  // SC = _S_ample_C_onversion
38 
39 
40 // Every sample decoding functor has to typedef its input_t and output_t
41 // and has to provide a static constexpr input_inc member
42 // which describes by how many input_t elements inBuf has to be incremented between invocations.
43 // input_inc is normally 1 except when decoding e.g. bigger sample values
44 // from multiple std::byte values.
45 
46 
47 struct DecodeInt8
48 {
49 	using input_t = std::byte;
50 	using output_t = int8;
51 	static constexpr std::size_t input_inc = 1;
operator ()SC::DecodeInt852 	MPT_FORCEINLINE output_t operator()(const input_t *inBuf)
53 	{
54 		return mpt::byte_cast<int8>(*inBuf);
55 	}
56 };
57 
58 struct DecodeUint8
59 {
60 	using input_t = std::byte;
61 	using output_t = int8;
62 	static constexpr std::size_t input_inc = 1;
operator ()SC::DecodeUint863 	MPT_FORCEINLINE output_t operator()(const input_t *inBuf)
64 	{
65 		return static_cast<int8>(static_cast<int>(mpt::byte_cast<uint8>(*inBuf)) - 128);
66 	}
67 };
68 
69 struct DecodeInt8Delta
70 {
71 	using input_t = std::byte;
72 	using output_t = int8;
73 	static constexpr std::size_t input_inc = 1;
74 	uint8 delta;
DecodeInt8DeltaSC::DecodeInt8Delta75 	DecodeInt8Delta()
76 		: delta(0) {}
operator ()SC::DecodeInt8Delta77 	MPT_FORCEINLINE output_t operator()(const input_t *inBuf)
78 	{
79 		delta += mpt::byte_cast<uint8>(*inBuf);
80 		return static_cast<int8>(delta);
81 	}
82 };
83 
84 struct DecodeInt16uLaw
85 {
86 	using input_t = std::byte;
87 	using output_t = int16;
88 	static constexpr std::size_t input_inc = 1;
89 	// clang-format off
90 	static constexpr std::array<int16, 256> uLawTable =
91 	{
92 		-32124,-31100,-30076,-29052,-28028,-27004,-25980,-24956,
93 		-23932,-22908,-21884,-20860,-19836,-18812,-17788,-16764,
94 		-15996,-15484,-14972,-14460,-13948,-13436,-12924,-12412,
95 		-11900,-11388,-10876,-10364, -9852, -9340, -8828, -8316,
96 		 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
97 		 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
98 		 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
99 		 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
100 		 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
101 		 -1372, -1308, -1244, -1180, -1116, -1052,  -988,  -924,
102 		  -876,  -844,  -812,  -780,  -748,  -716,  -684,  -652,
103 		  -620,  -588,  -556,  -524,  -492,  -460,  -428,  -396,
104 		  -372,  -356,  -340,  -324,  -308,  -292,  -276,  -260,
105 		  -244,  -228,  -212,  -196,  -180,  -164,  -148,  -132,
106 		  -120,  -112,  -104,   -96,   -88,   -80,   -72,   -64,
107 		   -56,   -48,   -40,   -32,   -24,   -16,    -8,    -1,
108 		 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
109 		 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
110 		 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
111 		 11900, 11388, 10876, 10364,  9852,  9340,  8828,  8316,
112 		  7932,  7676,  7420,  7164,  6908,  6652,  6396,  6140,
113 		  5884,  5628,  5372,  5116,  4860,  4604,  4348,  4092,
114 		  3900,  3772,  3644,  3516,  3388,  3260,  3132,  3004,
115 		  2876,  2748,  2620,  2492,  2364,  2236,  2108,  1980,
116 		  1884,  1820,  1756,  1692,  1628,  1564,  1500,  1436,
117 		  1372,  1308,  1244,  1180,  1116,  1052,   988,   924,
118 		   876,   844,   812,   780,   748,   716,   684,   652,
119 		   620,   588,   556,   524,   492,   460,   428,   396,
120 		   372,   356,   340,   324,   308,   292,   276,   260,
121 		   244,   228,   212,   196,   180,   164,   148,   132,
122 		   120,   112,   104,    96,    88,    80,    72,    64,
123 		    56,    48,    40,    32,    24,    16,     8,     0
124 	};
125 	// clang-format on
operator ()SC::DecodeInt16uLaw126 	MPT_FORCEINLINE output_t operator()(const input_t *inBuf)
127 	{
128 		return uLawTable[mpt::byte_cast<uint8>(*inBuf)];
129 	}
130 };
131 
132 struct DecodeInt16ALaw
133 {
134 	using input_t = std::byte;
135 	using output_t = int16;
136 	static constexpr std::size_t input_inc = 1;
137 	// clang-format off
138 	static constexpr std::array<int16, 256> ALawTable =
139 	{
140 		 -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736,
141 		 -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784,
142 		 -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368,
143 		 -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392,
144 		-22016,-20992,-24064,-23040,-17920,-16896,-19968,-18944,
145 		-30208,-29184,-32256,-31232,-26112,-25088,-28160,-27136,
146 		-11008,-10496,-12032,-11520, -8960, -8448, -9984, -9472,
147 		-15104,-14592,-16128,-15616,-13056,-12544,-14080,-13568,
148 		  -344,  -328,  -376,  -360,  -280,  -264,  -312,  -296,
149 		  -472,  -456,  -504,  -488,  -408,  -392,  -440,  -424,
150 		   -88,   -72,  -120,  -104,   -24,   -8,    -56,   -40,
151 		  -216,  -200,  -248,  -232,  -152,  -136,  -184,  -168,
152 		 -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184,
153 		 -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696,
154 		  -688,  -656,  -752,  -720,  -560,  -528,  -624,  -592,
155 		  -944,  -912,  -1008, -976,  -816,  -784,  -880,  -848,
156 		  5504,  5248,  6016,  5760,  4480,  4224,  4992,  4736,
157 		  7552,  7296,  8064,  7808,  6528,  6272,  7040,  6784,
158 		  2752,  2624,  3008,  2880,  2240,  2112,  2496,  2368,
159 		  3776,  3648,  4032,  3904,  3264,  3136,  3520,  3392,
160 		 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944,
161 		 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136,
162 		 11008, 10496, 12032, 11520,  8960,  8448,  9984,  9472,
163 		 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568,
164 		   344,   328,   376,   360,   280,   264,   312,   296,
165 		   472,   456,   504,   488,   408,   392,   440,   424,
166 		    88,    72,   120,   104,    24,     8,    56,    40,
167 		   216,   200,   248,   232,   152,   136,   184,   168,
168 		  1376,  1312,  1504,  1440,  1120,  1056,  1248,  1184,
169 		  1888,  1824,  2016,  1952,  1632,  1568,  1760,  1696,
170 		   688,   656,   752,   720,   560,   528,   624,   592,
171 		   944,   912,  1008,   976,   816,   784,   880,   848
172 	};
173 	// clang-format on
operator ()SC::DecodeInt16ALaw174 	MPT_FORCEINLINE output_t operator()(const input_t *inBuf)
175 	{
176 		return ALawTable[mpt::byte_cast<uint8>(*inBuf)];
177 	}
178 };
179 
180 template <uint16 offset, std::size_t loByteIndex, std::size_t hiByteIndex>
181 struct DecodeInt16
182 {
183 	using input_t = std::byte;
184 	using output_t = int16;
185 	static constexpr std::size_t input_inc = 2;
operator ()SC::DecodeInt16186 	MPT_FORCEINLINE output_t operator()(const input_t *inBuf)
187 	{
188 		return (mpt::byte_cast<uint8>(inBuf[loByteIndex]) | (mpt::byte_cast<uint8>(inBuf[hiByteIndex]) << 8)) - offset;
189 	}
190 };
191 
192 template <std::size_t loByteIndex, std::size_t hiByteIndex>
193 struct DecodeInt16Delta
194 {
195 	using input_t = std::byte;
196 	using output_t = int16;
197 	static constexpr std::size_t input_inc = 2;
198 	uint16 delta;
DecodeInt16DeltaSC::DecodeInt16Delta199 	DecodeInt16Delta()
200 		: delta(0) {}
operator ()SC::DecodeInt16Delta201 	MPT_FORCEINLINE output_t operator()(const input_t *inBuf)
202 	{
203 		delta += mpt::byte_cast<uint8>(inBuf[loByteIndex]) | (mpt::byte_cast<uint8>(inBuf[hiByteIndex]) << 8);
204 		return static_cast<int16>(delta);
205 	}
206 };
207 
208 struct DecodeInt16Delta8
209 {
210 	using input_t = std::byte;
211 	using output_t = int16;
212 	static constexpr std::size_t input_inc = 2;
213 	uint16 delta;
DecodeInt16Delta8SC::DecodeInt16Delta8214 	DecodeInt16Delta8()
215 		: delta(0) {}
operator ()SC::DecodeInt16Delta8216 	MPT_FORCEINLINE output_t operator()(const input_t *inBuf)
217 	{
218 		delta += mpt::byte_cast<uint8>(inBuf[0]);
219 		int16 result = delta & 0xFF;
220 		delta += mpt::byte_cast<uint8>(inBuf[1]);
221 		result |= (delta << 8);
222 		return result;
223 	}
224 };
225 
226 template <uint32 offset, std::size_t loByteIndex, std::size_t midByteIndex, std::size_t hiByteIndex>
227 struct DecodeInt24
228 {
229 	using input_t = std::byte;
230 	using output_t = int32;
231 	static constexpr std::size_t input_inc = 3;
operator ()SC::DecodeInt24232 	MPT_FORCEINLINE output_t operator()(const input_t *inBuf)
233 	{
234 		return ((mpt::byte_cast<uint8>(inBuf[loByteIndex]) << 8) | (mpt::byte_cast<uint8>(inBuf[midByteIndex]) << 16) | (mpt::byte_cast<uint8>(inBuf[hiByteIndex]) << 24)) - offset;
235 	}
236 };
237 
238 template <uint32 offset, std::size_t loLoByteIndex, std::size_t loHiByteIndex, std::size_t hiLoByteIndex, std::size_t hiHiByteIndex>
239 struct DecodeInt32
240 {
241 	using input_t = std::byte;
242 	using output_t = int32;
243 	static constexpr std::size_t input_inc = 4;
operator ()SC::DecodeInt32244 	MPT_FORCEINLINE output_t operator()(const input_t *inBuf)
245 	{
246 		return (mpt::byte_cast<uint8>(inBuf[loLoByteIndex]) | (mpt::byte_cast<uint8>(inBuf[loHiByteIndex]) << 8) | (mpt::byte_cast<uint8>(inBuf[hiLoByteIndex]) << 16) | (mpt::byte_cast<uint8>(inBuf[hiHiByteIndex]) << 24)) - offset;
247 	}
248 };
249 
250 template <uint64 offset, std::size_t b0, std::size_t b1, std::size_t b2, std::size_t b3, std::size_t b4, std::size_t b5, std::size_t b6, std::size_t b7>
251 struct DecodeInt64
252 {
253 	using input_t = std::byte;
254 	using output_t = int64;
255 	static constexpr std::size_t input_inc = 8;
operator ()SC::DecodeInt64256 	MPT_FORCEINLINE output_t operator()(const input_t *inBuf)
257 	{
258 		return (uint64(0)
259 				| (static_cast<uint64>(mpt::byte_cast<uint8>(inBuf[b0])) << 0)
260 				| (static_cast<uint64>(mpt::byte_cast<uint8>(inBuf[b1])) << 8)
261 				| (static_cast<uint64>(mpt::byte_cast<uint8>(inBuf[b2])) << 16)
262 				| (static_cast<uint64>(mpt::byte_cast<uint8>(inBuf[b3])) << 24)
263 				| (static_cast<uint64>(mpt::byte_cast<uint8>(inBuf[b4])) << 32)
264 				| (static_cast<uint64>(mpt::byte_cast<uint8>(inBuf[b5])) << 40)
265 				| (static_cast<uint64>(mpt::byte_cast<uint8>(inBuf[b6])) << 48)
266 				| (static_cast<uint64>(mpt::byte_cast<uint8>(inBuf[b7])) << 56))
267 			- offset;
268 	}
269 };
270 
271 template <std::size_t loLoByteIndex, std::size_t loHiByteIndex, std::size_t hiLoByteIndex, std::size_t hiHiByteIndex>
272 struct DecodeFloat32
273 {
274 	using input_t = std::byte;
275 	using output_t = float32;
276 	static constexpr std::size_t input_inc = 4;
operator ()SC::DecodeFloat32277 	MPT_FORCEINLINE output_t operator()(const input_t *inBuf)
278 	{
279 		float32 val = IEEE754binary32LE(inBuf[loLoByteIndex], inBuf[loHiByteIndex], inBuf[hiLoByteIndex], inBuf[hiHiByteIndex]);
280 		val = mpt::sanitize_nan(val);
281 		if(std::isinf(val))
282 		{
283 			if(val >= 0.0f)
284 			{
285 				val = 1.0f;
286 			} else
287 			{
288 				val = -1.0f;
289 			}
290 		}
291 		return val;
292 	}
293 };
294 
295 template <std::size_t loLoByteIndex, std::size_t loHiByteIndex, std::size_t hiLoByteIndex, std::size_t hiHiByteIndex>
296 struct DecodeScaledFloat32
297 {
298 	using input_t = std::byte;
299 	using output_t = float32;
300 	static constexpr std::size_t input_inc = 4;
301 	float factor;
operator ()SC::DecodeScaledFloat32302 	MPT_FORCEINLINE output_t operator()(const input_t *inBuf)
303 	{
304 		float32 val = IEEE754binary32LE(inBuf[loLoByteIndex], inBuf[loHiByteIndex], inBuf[hiLoByteIndex], inBuf[hiHiByteIndex]);
305 		val = mpt::sanitize_nan(val);
306 		if(std::isinf(val))
307 		{
308 			if(val >= 0.0f)
309 			{
310 				val = 1.0f;
311 			} else
312 			{
313 				val = -1.0f;
314 			}
315 		}
316 		return factor * val;
317 	}
DecodeScaledFloat32SC::DecodeScaledFloat32318 	MPT_FORCEINLINE DecodeScaledFloat32(float scaleFactor)
319 		: factor(scaleFactor)
320 	{
321 		return;
322 	}
323 };
324 
325 template <std::size_t b0, std::size_t b1, std::size_t b2, std::size_t b3, std::size_t b4, std::size_t b5, std::size_t b6, std::size_t b7>
326 struct DecodeFloat64
327 {
328 	using input_t = std::byte;
329 	using output_t = float64;
330 	static constexpr std::size_t input_inc = 8;
operator ()SC::DecodeFloat64331 	MPT_FORCEINLINE output_t operator()(const input_t *inBuf)
332 	{
333 		float64 val = IEEE754binary64LE(inBuf[b0], inBuf[b1], inBuf[b2], inBuf[b3], inBuf[b4], inBuf[b5], inBuf[b6], inBuf[b7]);
334 		val = mpt::sanitize_nan(val);
335 		if(std::isinf(val))
336 		{
337 			if(val >= 0.0)
338 			{
339 				val = 1.0;
340 			} else
341 			{
342 				val = -1.0;
343 			}
344 		}
345 		return val;
346 	}
347 };
348 
349 template <typename Tsample>
350 struct DecodeIdentity
351 {
352 	using input_t = Tsample;
353 	using output_t = Tsample;
354 	static constexpr std::size_t input_inc = 1;
operator ()SC::DecodeIdentity355 	MPT_FORCEINLINE output_t operator()(const input_t *inBuf)
356 	{
357 		return *inBuf;
358 	}
359 };
360 
361 
362 // Reads sample data with Func and passes it directly to Func2.
363 // Func1::output_t and Func2::input_t must be identical
364 template <typename Func2, typename Func1>
365 struct ConversionChain
366 {
367 	using input_t = typename Func1::input_t;
368 	using output_t = typename Func2::output_t;
369 	static constexpr std::size_t input_inc = Func1::input_inc;
370 	Func1 func1;
371 	Func2 func2;
operator ()SC::ConversionChain372 	MPT_FORCEINLINE output_t operator()(const input_t *inBuf)
373 	{
374 		return func2(func1(inBuf));
375 	}
ConversionChainSC::ConversionChain376 	MPT_FORCEINLINE ConversionChain(Func2 f2 = Func2(), Func1 f1 = Func1())
377 		: func1(f1)
378 		, func2(f2)
379 	{
380 		return;
381 	}
382 };
383 
384 
385 }  // namespace SC
386 
387 
388 OPENMPT_NAMESPACE_END
389