QOATypes.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /*
  2. * Copyright (c) 2023, kleines Filmröllchen <filmroellchen@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Array.h>
  8. #include <AK/Forward.h>
  9. #include <AK/Math.h>
  10. #include <AK/Types.h>
  11. #include <math.h>
  12. namespace Audio::QOA {
  13. // 'qoaf'
  14. static constexpr u32 const magic = 0x716f6166;
  15. static constexpr size_t const header_size = sizeof(u64);
  16. struct FrameHeader {
  17. u8 num_channels;
  18. u32 sample_rate; // 24 bits
  19. u16 sample_count;
  20. // TODO: might be removed and/or replaced
  21. u16 frame_size;
  22. static ErrorOr<FrameHeader> read_from_stream(Stream& stream);
  23. };
  24. static constexpr size_t const frame_header_size = sizeof(u64);
  25. // Least mean squares (LMS) predictor FIR filter size.
  26. static constexpr size_t const lms_history = 4;
  27. static constexpr size_t const lms_state_size = 2 * lms_history * sizeof(u16);
  28. // Only used for internal purposes; intermediate LMS states can be beyond 16 bits.
  29. struct LMSState {
  30. i32 history[lms_history] { 0, 0, 0, 0 };
  31. i32 weights[lms_history] { 0, 0, 0, 0 };
  32. LMSState() = default;
  33. LMSState(u64 history_packed, u64 weights_packed);
  34. i32 predict() const;
  35. void update(i32 sample, i32 residual);
  36. };
  37. using PackedSlice = u64;
  38. // A QOA slice in a more directly readable format, unpacked from the stored 64-bit format.
  39. struct UnpackedSlice {
  40. size_t scale_factor_index; // 4 bits packed
  41. Array<u8, 20> residuals; // 3 bits packed
  42. };
  43. // Samples within a 64-bit slice.
  44. static constexpr size_t const slice_samples = 20;
  45. static constexpr size_t const max_slices_per_frame = 256;
  46. static constexpr size_t const max_frame_samples = slice_samples * max_slices_per_frame;
  47. // Defined as clamping limits by the spec.
  48. static constexpr i32 const sample_minimum = -32768;
  49. static constexpr i32 const sample_maximum = 32767;
  50. // Quantization and scale factor tables computed from formulas given in qoa.h
  51. constexpr Array<int, 17> generate_scale_factor_table()
  52. {
  53. Array<int, 17> scalefactor_table;
  54. for (size_t s = 0; s < 17; ++s)
  55. scalefactor_table[s] = static_cast<int>(AK::round<double>(AK::pow<double>(static_cast<double>(s + 1), 2.75)));
  56. return scalefactor_table;
  57. }
  58. // FIXME: Get rid of the literal table once Clang understands our constexpr pow() and round() implementations.
  59. #if defined(AK_COMPILER_CLANG)
  60. static constexpr Array<int, 17> scale_factor_table = {
  61. 1, 7, 21, 45, 84, 138, 211, 304, 421, 562, 731, 928, 1157, 1419, 1715, 2048
  62. };
  63. #else
  64. static constexpr Array<int, 17> scale_factor_table = generate_scale_factor_table();
  65. #endif
  66. constexpr Array<int, 17> generate_reciprocal_table()
  67. {
  68. Array<int, 17> reciprocal_table;
  69. for (size_t s = 0; s < 17; ++s) {
  70. reciprocal_table[s] = ((1 << 16) + scale_factor_table[s] - 1) / scale_factor_table[s];
  71. }
  72. return reciprocal_table;
  73. }
  74. constexpr Array<Array<int, 8>, 16> generate_dequantization_table()
  75. {
  76. Array<Array<int, 8>, 16> dequantization_table;
  77. constexpr Array<double, 8> float_dequantization_table = { 0.75, -0.75, 2.5, -2.5, 4.5, -4.5, 7, -7 };
  78. for (size_t scale = 0; scale < 16; ++scale) {
  79. for (size_t quantization = 0; quantization < 8; ++quantization)
  80. dequantization_table[scale][quantization] = static_cast<int>(AK::round<double>(
  81. static_cast<double>(scale_factor_table[scale]) * float_dequantization_table[quantization]));
  82. }
  83. return dequantization_table;
  84. }
  85. #if defined(AK_COMPILER_CLANG)
  86. static constexpr Array<int, 17> reciprocal_table = {
  87. 65536, 9363, 3121, 1457, 781, 475, 311, 216, 156, 117, 90, 71, 57, 47, 39, 32
  88. };
  89. static constexpr Array<Array<int, 8>, 16> dequantization_table = {
  90. Array<int, 8> { 1, -1, 3, -3, 5, -5, 7, -7 },
  91. { 5, -5, 18, -18, 32, -32, 49, -49 },
  92. { 16, -16, 53, -53, 95, -95, 147, -147 },
  93. { 34, -34, 113, -113, 203, -203, 315, -315 },
  94. { 63, -63, 210, -210, 378, -378, 588, -588 },
  95. { 104, -104, 345, -345, 621, -621, 966, -966 },
  96. { 158, -158, 528, -528, 950, -950, 1477, -1477 },
  97. { 228, -228, 760, -760, 1368, -1368, 2128, -2128 },
  98. { 316, -316, 1053, -1053, 1895, -1895, 2947, -2947 },
  99. { 422, -422, 1405, -1405, 2529, -2529, 3934, -3934 },
  100. { 548, -548, 1828, -1828, 3290, -3290, 5117, -5117 },
  101. { 696, -696, 2320, -2320, 4176, -4176, 6496, -6496 },
  102. { 868, -868, 2893, -2893, 5207, -5207, 8099, -8099 },
  103. { 1064, -1064, 3548, -3548, 6386, -6386, 9933, -9933 },
  104. { 1286, -1286, 4288, -4288, 7718, -7718, 12005, -12005 },
  105. { 1536, -1536, 5120, -5120, 9216, -9216, 14336, -14336 },
  106. };
  107. #else
  108. static constexpr Array<int, 17> reciprocal_table = generate_reciprocal_table();
  109. static constexpr Array<Array<int, 8>, 16> dequantization_table = generate_dequantization_table();
  110. #endif
  111. static constexpr Array<int, 17> quantization_table = {
  112. 7, 7, 7, 5, 5, 3, 3, 1, // -8 ..-1
  113. 0, // 0
  114. 0, 2, 2, 4, 4, 6, 6, 6 // 1 .. 8
  115. };
  116. }