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