DSPark 1.6.1
Header-only audio DSP framework in pure C++20 — zero dependencies
Loading...
Searching...
No Matches
Mp3File.h
Go to the documentation of this file.
1// DSPark - Professional Audio DSP Framework
2// Copyright (c) 2026 Cristian Moresi - MIT License
3
4#pragma once
5
39#include "AudioFile.h"
40
41#include <algorithm>
42#include <array>
43#include <cmath>
44#include <cstdint>
45#include <cstring>
46#include <fstream>
47#include <vector>
48#include <filesystem>
49
50namespace dspark {
51
52// ============================================================================
53// Mp3File
54// ============================================================================
55
56class Mp3File : public AudioFile
57{
58public:
59 ~Mp3File() override { close(); }
60
61 // -- AudioFile interface ---------------------------------------------------
62
63 [[nodiscard]] bool openRead(const std::filesystem::path& path) override
64 {
65 close();
66
67 std::ifstream in(path, std::ios::binary | std::ios::ate);
68 if (!in.is_open()) return false;
69
70 auto fileSize = static_cast<size_t>(in.tellg());
71 if (fileSize < 10) return false;
72
73 constexpr size_t kMaxMp3FileSize = 256 * 1024 * 1024; // 256 MB bounds check
74 if (fileSize > kMaxMp3FileSize) return false;
75 in.seekg(0, std::ios::beg);
76
77 fileData_.resize(fileSize);
78 in.read(reinterpret_cast<char*>(fileData_.data()), static_cast<std::streamsize>(fileSize));
79 if (static_cast<size_t>(in.gcount()) != fileSize)
80 {
81 fileData_.clear();
82 return false;
83 }
84 in.close();
85
86 filePos_ = 0;
87 skipID3v2();
88
89 if (!scanFrames())
90 {
91 fileData_.clear();
92 return false;
93 }
94
95 if (!decodeAll())
96 {
97 fileData_.clear();
98 decodedSamplesFlat_.clear();
99 return false;
100 }
101
102 fileData_.clear(); // Free raw memory after full planar extraction
103 isOpen_ = true;
104 return true;
105 }
106
107 [[nodiscard]] bool openWrite(const std::filesystem::path& path, const AudioFileInfo& info) override
108 {
109 close();
110 outFile_.open(path, std::ios::binary | std::ios::trunc);
111 if (!outFile_.is_open()) return false;
112
113 info_ = info;
114 if (info_.numChannels < 1) info_.numChannels = 1;
115 if (info_.numChannels > 2) info_.numChannels = 2;
116
117 encBitrate_ = info_.bitsPerSample;
118 if (encBitrate_ < 32) encBitrate_ = 128;
119
120 static constexpr int validBr[] = {32,40,48,56,64,80,96,112,128,160,192,224,256,320};
121 int best = 128, bestDist = 999;
122 for (int br : validBr) {
123 int d = std::abs(br - encBitrate_);
124 if (d < bestDist) { bestDist = d; best = br; }
125 }
126 encBitrate_ = best;
127
128 double sr = info_.sampleRate;
129 if (sr <= 36050) info_.sampleRate = 32000;
130 else if (sr <= 46050) info_.sampleRate = 44100;
131 else info_.sampleRate = 48000;
132
133 for (int ch = 0; ch < kChannelsMax; ++ch) encState_[ch] = {};
134 encFrameBuf_.clear();
135 encInputPos_ = 0;
136 isWriting_ = true;
137 isOpen_ = true;
138 return true;
139 }
140
141 [[nodiscard]] AudioFileInfo getInfo() const override { return info_; }
142
143 [[nodiscard]] bool readSamples(AudioBufferView<float> dest) override
144 {
145 return readSamples(dest, 0, info_.numSamples);
146 }
147
148 [[nodiscard]] bool readSamples(AudioBufferView<float> dest,
149 int64_t startFrame, int64_t numFrames) override
150 {
151 if (!isOpen_) return false;
152 if (startFrame < 0 || numFrames <= 0) return false;
153 if (startFrame + numFrames > info_.numSamples) return false;
154
155 const int nCh = std::min(dest.getNumChannels(), static_cast<int>(info_.numChannels));
156 const int64_t toCopy = std::min(numFrames, static_cast<int64_t>(dest.getNumSamples()));
157 const size_t bytesToCopy = static_cast<size_t>(toCopy) * sizeof(float);
158
159 for (int ch = 0; ch < nCh; ++ch)
160 {
161 float* dst = dest.getChannel(ch);
162 const float* src = decodedSamplesFlat_.data() + static_cast<size_t>(ch * info_.numSamples + startFrame);
163 std::memcpy(dst, src, bytesToCopy);
164 }
165
166 return true;
167 }
168
169 [[nodiscard]] bool writeSamples(AudioBufferView<const float> src) override
170 {
171 if (!isWriting_ || !outFile_.is_open()) return false;
172
173 const int nCh = std::min(src.getNumChannels(), static_cast<int>(info_.numChannels));
174 const int nS = src.getNumSamples();
175
176 for (int i = 0; i < nS; ++i)
177 {
178 for (int ch = 0; ch < static_cast<int>(info_.numChannels); ++ch)
179 {
180 float val = (ch < nCh) ? src.getChannel(ch)[i] : 0.0f;
181 encInput_[ch][encInputPos_] = static_cast<double>(val);
182 }
183 ++encInputPos_;
184
185 if (encInputPos_ >= kSamplesPerFrame)
186 {
187 encEncodeFrame();
188 encInputPos_ = 0;
189 }
190 }
191 return true;
192 }
193
194 void close() override
195 {
196 if (isWriting_ && outFile_.is_open())
197 {
198 if (encInputPos_ > 0)
199 {
200 for (int ch = 0; ch < static_cast<int>(info_.numChannels); ++ch)
201 for (int i = encInputPos_; i < kSamplesPerFrame; ++i)
202 encInput_[ch][i] = 0.0;
203 encEncodeFrame();
204 }
205 outFile_.close();
206 }
207 isWriting_ = false;
208
209 fileData_.clear();
210 decodedSamplesFlat_.clear();
211 frameOffsets_.clear();
212 info_ = {};
213 isOpen_ = false;
214 filePos_ = 0;
215 }
216
217 [[nodiscard]] bool isOpen() const noexcept override { return isOpen_; }
218
219private:
220 // ========================================================================
221 // Constants
222 // ========================================================================
223
224 static constexpr int kGranules = 2;
225 static constexpr int kChannelsMax = 2;
226 static constexpr int kSamplesPerGranule = 576;
227 static constexpr int kSamplesPerFrame = 1152; // MPEG-1 Layer III
228 static constexpr int kSubbands = 32;
229 static constexpr int kSynthSlots = 16;
230 static constexpr int kMaxReservoir = 8192; // Bit reservoir maximum bytes
231
232 // ========================================================================
233 // Frame header & Side Info Structs
234 // ========================================================================
235
236 struct FrameHeader
237 {
238 int version = 0;
239 int layer = 0;
240 bool crcProtect = false;
241 int bitrateIdx = 0;
242 int srateIdx = 0;
243 bool padding = false;
244 int channelMode = 0;
245 int modeExt = 0;
246 bool copyright = false;
247 bool original = false;
248 int emphasis = 0;
249 int bitrate = 0;
250 int sampleRate = 0;
251 int channels = 0;
252 int frameSize = 0;
253 int sideInfoSize = 0;
254 };
255
256 struct GranuleChannel
257 {
258 int part2_3_length = 0;
259 int big_values = 0;
260 int global_gain = 0;
261 int scalefac_compress = 0;
262 bool window_switching = false;
263 int block_type = 0;
264 int mixed_block = 0;
265 int table_select[3] = {};
266 int subblock_gain[3] = {};
267 int region0_count = 0;
268 int region1_count = 0;
269 int preflag = 0;
270 int scalefac_scale = 0;
271 int count1table_select = 0;
272 };
273
274 struct SideInfo
275 {
276 int main_data_begin = 0;
277 int scfsi[2] = {};
278 GranuleChannel gr[2][2] = {};
279 };
280
281 // ========================================================================
282 // Bitstream reader
283 // ========================================================================
284
285 class BitReader
286 {
287 public:
288 BitReader() = default;
289
290 void init(const uint8_t* data, size_t sizeBytes)
291 {
292 data_ = data;
293 size_ = sizeBytes * 8;
294 pos_ = 0;
295 }
296
297 uint32_t readBits(int n)
298 {
299 if (n == 0) return 0;
300 uint32_t val = 0;
301 for (int i = 0; i < n; ++i)
302 {
303 val <<= 1;
304 if (pos_ < size_)
305 {
306 size_t byteIdx = pos_ >> 3;
307 int bitIdx = 7 - static_cast<int>(pos_ & 7);
308 val |= (data_[byteIdx] >> bitIdx) & 1u;
309 }
310 ++pos_;
311 }
312 return val;
313 }
314
315 int readBit()
316 {
317 if (pos_ >= size_) { ++pos_; return 0; }
318 size_t byteIdx = pos_ >> 3;
319 int bitIdx = 7 - static_cast<int>(pos_ & 7);
320 int val = (data_[byteIdx] >> bitIdx) & 1;
321 ++pos_;
322 return val;
323 }
324
325 [[nodiscard]] size_t getPos() const { return pos_; }
326 void setPos(size_t p) { pos_ = p; }
327 [[nodiscard]] size_t remaining() const { return (pos_ < size_) ? (size_ - pos_) : 0; }
328
329 private:
330 const uint8_t* data_ = nullptr;
331 size_t size_ = 0;
332 size_t pos_ = 0;
333 };
334
335 // ========================================================================
336 // Bitrate and sample rate tables (MPEG-1)
337 // ========================================================================
338
339 static constexpr int kBitrateTable[16] = {
340 0, 32, 40, 48, 56, 64, 80, 96,
341 112, 128, 160, 192, 224, 256, 320, 0
342 };
343
344 static constexpr int kSampleRateTable[4] = {
345 44100, 48000, 32000, 0
346 };
347
348 // ========================================================================
349 // Scalefactor band tables (MPEG-1 Layer III)
350 // ========================================================================
351
352 struct BandTable
353 {
354 int longBands[23] = {};
355 int shortBands[14] = {};
356 int longCount = 0;
357 int shortCount = 0;
358 };
359
360 static BandTable getBandTable(int sampleRate)
361 {
362 BandTable t {};
363 if (sampleRate == 44100)
364 {
365 static constexpr int lb[] = {0,4,8,12,16,20,24,30,36,44,52,62,74,90,110,134,162,196,238,288,342,418,576};
366 static constexpr int sb[] = {0,4,8,12,16,22,30,40,52,66,84,106,136,192};
367 std::memcpy(t.longBands, lb, sizeof(lb));
368 std::memcpy(t.shortBands, sb, sizeof(sb));
369 t.longCount = 22;
370 t.shortCount = 13;
371 }
372 else if (sampleRate == 48000)
373 {
374 static constexpr int lb[] = {0,4,8,12,16,20,24,30,36,42,50,60,72,88,106,128,156,190,230,276,330,384,576};
375 static constexpr int sb[] = {0,4,8,12,16,22,28,38,50,64,80,100,126,192};
376 std::memcpy(t.longBands, lb, sizeof(lb));
377 std::memcpy(t.shortBands, sb, sizeof(sb));
378 t.longCount = 22;
379 t.shortCount = 13;
380 }
381 else
382 {
383 static constexpr int lb[] = {0,4,8,12,16,20,24,30,36,44,54,66,82,102,126,156,194,240,296,364,448,550,576};
384 static constexpr int sb[] = {0,4,8,12,16,22,30,42,58,78,104,138,180,192};
385 std::memcpy(t.longBands, lb, sizeof(lb));
386 std::memcpy(t.shortBands, sb, sizeof(sb));
387 t.longCount = 22;
388 t.shortCount = 13;
389 }
390 return t;
391 }
392
393 static constexpr int kSlen1[16] = {0,0,0,0,3,1,1,1,2,2,2,3,3,3,4,4};
394 static constexpr int kSlen2[16] = {0,1,2,3,0,1,2,3,1,2,3,1,2,3,2,3};
395 static constexpr int kPretab[22] = {0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,2,2,3,3,3,2,0};
396
397 // ========================================================================
398 // Huffman tables (ISO 11172-3)
399 // ========================================================================
400
401 static constexpr int kHuffLinbits[32] = {
402 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
403 1,2,3,4,6,8,10,13,4,5,6,7,8,9,11,13
404 };
405
406 struct HuffCode { uint8_t len; uint16_t code; uint8_t x, y; };
407
408 static constexpr HuffCode kHuff01[] = {
409 {1, 0b1, 0, 0}, {3, 0b001, 0, 1}, {2, 0b01, 1, 0}, {3, 0b000, 1, 1},
410 };
411
412 static constexpr HuffCode kHuff02[] = {
413 {1, 0b1, 0, 0}, {3, 0b010, 0, 1}, {6, 0b000001, 0, 2}, {3, 0b011, 1, 0}, {3, 0b001, 1, 1},
414 {5, 0b00001, 1, 2}, {5, 0b00011, 2, 0}, {5, 0b00010, 2, 1}, {6, 0b000000, 2, 2},
415 };
416
417 static constexpr HuffCode kHuff03[] = {
418 {2, 0b11, 0, 0}, {2, 0b10, 0, 1}, {6, 0b000001, 0, 2}, {3, 0b001, 1, 0}, {2, 0b01, 1, 1},
419 {5, 0b00001, 1, 2}, {5, 0b00011, 2, 0}, {5, 0b00010, 2, 1}, {6, 0b000000, 2, 2},
420 };
421
422 static constexpr HuffCode kHuff05[] = {
423 {1, 0b1, 0, 0}, {3, 0b010, 0, 1}, {6, 0b000110, 0, 2}, {7, 0b0000101, 0, 3}, {3, 0b011, 1, 0},
424 {3, 0b001, 1, 1}, {6, 0b000100, 1, 2}, {7, 0b0000100, 1, 3}, {6, 0b000111, 2, 0}, {6, 0b000101, 2, 1},
425 {7, 0b0000111, 2, 2}, {8, 0b00000001, 2, 3}, {7, 0b0000110, 3, 0}, {6, 0b000001, 3, 1},
426 {7, 0b0000001, 3, 2}, {8, 0b00000000, 3, 3},
427 };
428
429 static constexpr HuffCode kHuff06[] = {
430 {3, 0b111, 0, 0}, {3, 0b011, 0, 1}, {5, 0b00101, 0, 2}, {7, 0b0000001, 0, 3}, {3, 0b110, 1, 0},
431 {2, 0b10, 1, 1}, {4, 0b0011, 1, 2}, {5, 0b00010, 1, 3}, {4, 0b0101, 2, 0}, {4, 0b0100, 2, 1},
432 {5, 0b00100, 2, 2}, {6, 0b000001, 2, 3}, {6, 0b000011, 3, 0}, {5, 0b00011, 3, 1}, {6, 0b000010, 3, 2},
433 {7, 0b0000000, 3, 3},
434 };
435
436 static constexpr HuffCode kHuff07[] = {
437 {1, 0b1, 0, 0}, {3, 0b010, 0, 1}, {6, 0b001010, 0, 2}, {8, 0b00010011, 0, 3}, {8, 0b00010000, 0, 4},
438 {9, 0b000001010, 0, 5}, {3, 0b011, 1, 0}, {4, 0b0011, 1, 1}, {6, 0b000111, 1, 2}, {7, 0b0001010, 1, 3},
439 {7, 0b0000101, 1, 4}, {8, 0b00000011, 1, 5}, {6, 0b001011, 2, 0}, {5, 0b00100, 2, 1}, {7, 0b0001101, 2, 2},
440 {8, 0b00010001, 2, 3}, {8, 0b00001000, 2, 4}, {9, 0b000000100, 2, 5}, {7, 0b0001100, 3, 0},
441 {7, 0b0001011, 3, 1}, {8, 0b00010010, 3, 2}, {9, 0b000001111, 3, 3}, {9, 0b000001011, 3, 4},
442 {9, 0b000000010, 3, 5}, {7, 0b0000111, 4, 0}, {7, 0b0000110, 4, 1}, {8, 0b00001001, 4, 2},
443 {9, 0b000001110, 4, 3}, {9, 0b000000011, 4, 4}, {10, 0b0000000001, 4, 5}, {8, 0b00000110, 5, 0},
444 {8, 0b00000100, 5, 1}, {9, 0b000000101, 5, 2}, {10, 0b0000000011, 5, 3}, {10, 0b0000000010, 5, 4},
445 {10, 0b0000000000, 5, 5},
446 };
447
448 static constexpr HuffCode kHuff08[] = {
449 {2, 0b11, 0, 0}, {3, 0b100, 0, 1}, {6, 0b000110, 0, 2}, {8, 0b00010010, 0, 3}, {8, 0b00001100, 0, 4},
450 {9, 0b000000101, 0, 5}, {3, 0b101, 1, 0}, {2, 0b01, 1, 1}, {4, 0b0010, 1, 2}, {8, 0b00010000, 1, 3},
451 {8, 0b00001001, 1, 4}, {8, 0b00000011, 1, 5}, {6, 0b000111, 2, 0}, {4, 0b0011, 2, 1}, {6, 0b000101, 2, 2},
452 {8, 0b00001110, 2, 3}, {8, 0b00000111, 2, 4}, {9, 0b000000011, 2, 5}, {8, 0b00010011, 3, 0},
453 {8, 0b00010001, 3, 1}, {8, 0b00001111, 3, 2}, {9, 0b000001101, 3, 3}, {9, 0b000001010, 3, 4},
454 {10, 0b0000000100, 3, 5}, {8, 0b00001101, 4, 0}, {7, 0b0000101, 4, 1}, {8, 0b00001000, 4, 2},
455 {9, 0b000001011, 4, 3}, {10, 0b0000000101, 4, 4}, {10, 0b0000000001, 4, 5}, {9, 0b000001100, 5, 0},
456 {8, 0b00000100, 5, 1}, {9, 0b000000100, 5, 2}, {9, 0b000000001, 5, 3}, {11, 0b00000000001, 5, 4},
457 {11, 0b00000000000, 5, 5},
458 };
459
460 static constexpr HuffCode kHuff09[] = {
461 {3, 0b111, 0, 0}, {3, 0b101, 0, 1}, {5, 0b01001, 0, 2}, {6, 0b001110, 0, 3}, {8, 0b00001111, 0, 4},
462 {9, 0b000000111, 0, 5}, {3, 0b110, 1, 0}, {3, 0b100, 1, 1}, {4, 0b0101, 1, 2}, {5, 0b00101, 1, 3},
463 {6, 0b000110, 1, 4}, {8, 0b00000111, 1, 5}, {4, 0b0111, 2, 0}, {4, 0b0110, 2, 1}, {5, 0b01000, 2, 2},
464 {6, 0b001000, 2, 3}, {7, 0b0001000, 2, 4}, {8, 0b00000101, 2, 5}, {6, 0b001111, 3, 0}, {5, 0b00110, 3, 1},
465 {6, 0b001001, 3, 2}, {7, 0b0001010, 3, 3}, {7, 0b0000101, 3, 4}, {8, 0b00000001, 3, 5},
466 {7, 0b0001011, 4, 0}, {6, 0b000111, 4, 1}, {7, 0b0001001, 4, 2}, {7, 0b0000110, 4, 3},
467 {8, 0b00000100, 4, 4}, {9, 0b000000001, 4, 5}, {8, 0b00001110, 5, 0}, {7, 0b0000100, 5, 1},
468 {8, 0b00000110, 5, 2}, {8, 0b00000010, 5, 3}, {9, 0b000000110, 5, 4}, {9, 0b000000000, 5, 5},
469 };
470
471 static constexpr HuffCode kHuff10[] = {
472 {1, 0b1, 0, 0}, {3, 0b010, 0, 1}, {6, 0b001010, 0, 2}, {8, 0b00010111, 0, 3}, {9, 0b000100011, 0, 4},
473 {9, 0b000011110, 0, 5}, {9, 0b000001100, 0, 6}, {10, 0b0000010001, 0, 7}, {3, 0b011, 1, 0},
474 {4, 0b0011, 1, 1}, {6, 0b001000, 1, 2}, {7, 0b0001100, 1, 3}, {8, 0b00010010, 1, 4},
475 {9, 0b000010101, 1, 5}, {8, 0b00001100, 1, 6}, {8, 0b00000111, 1, 7}, {6, 0b001011, 2, 0},
476 {6, 0b001001, 2, 1}, {7, 0b0001111, 2, 2}, {8, 0b00010101, 2, 3}, {9, 0b000100000, 2, 4},
477 {10, 0b0000101000, 2, 5}, {9, 0b000010011, 2, 6}, {9, 0b000000110, 2, 7}, {7, 0b0001110, 3, 0},
478 {7, 0b0001101, 3, 1}, {8, 0b00010110, 3, 2}, {9, 0b000100010, 3, 3}, {10, 0b0000101110, 3, 4},
479 {10, 0b0000010111, 3, 5}, {9, 0b000010010, 3, 6}, {10, 0b0000000111, 3, 7}, {8, 0b00010100, 4, 0},
480 {8, 0b00010011, 4, 1}, {9, 0b000100001, 4, 2}, {10, 0b0000101111, 4, 3}, {10, 0b0000011011, 4, 4},
481 {10, 0b0000010110, 4, 5}, {10, 0b0000001001, 4, 6}, {10, 0b0000000011, 4, 7}, {9, 0b000011111, 5, 0},
482 {9, 0b000010110, 5, 1}, {10, 0b0000101001, 5, 2}, {10, 0b0000011010, 5, 3}, {11, 0b00000010101, 5, 4},
483 {11, 0b00000010100, 5, 5}, {10, 0b0000000101, 5, 6}, {11, 0b00000000011, 5, 7}, {8, 0b00001110, 6, 0},
484 {8, 0b00001101, 6, 1}, {9, 0b000001010, 6, 2}, {10, 0b0000001011, 6, 3}, {10, 0b0000010000, 6, 4},
485 {10, 0b0000000110, 6, 5}, {11, 0b00000000101, 6, 6}, {11, 0b00000000001, 6, 7}, {9, 0b000001001, 7, 0},
486 {8, 0b00001000, 7, 1}, {9, 0b000000111, 7, 2}, {10, 0b0000001000, 7, 3}, {10, 0b0000000100, 7, 4},
487 {11, 0b00000000100, 7, 5}, {11, 0b00000000010, 7, 6}, {11, 0b00000000000, 7, 7},
488 };
489
490 static constexpr HuffCode kHuff11[] = {
491 {2, 0b11, 0, 0}, {3, 0b100, 0, 1}, {5, 0b01010, 0, 2}, {7, 0b0011000, 0, 3}, {8, 0b00100010, 0, 4},
492 {9, 0b000100001, 0, 5}, {8, 0b00010101, 0, 6}, {9, 0b000001111, 0, 7}, {3, 0b101, 1, 0}, {3, 0b011, 1, 1},
493 {4, 0b0100, 1, 2}, {6, 0b001010, 1, 3}, {8, 0b00100000, 1, 4}, {8, 0b00010001, 1, 5}, {7, 0b0001011, 1, 6},
494 {8, 0b00001010, 1, 7}, {5, 0b01011, 2, 0}, {5, 0b00111, 2, 1}, {6, 0b001101, 2, 2}, {7, 0b0010010, 2, 3},
495 {8, 0b00011110, 2, 4}, {9, 0b000011111, 2, 5}, {8, 0b00010100, 2, 6}, {8, 0b00000101, 2, 7},
496 {7, 0b0011001, 3, 0}, {6, 0b001011, 3, 1}, {7, 0b0010011, 3, 2}, {9, 0b000111011, 3, 3},
497 {8, 0b00011011, 3, 4}, {10, 0b0000010010, 3, 5}, {8, 0b00001100, 3, 6}, {9, 0b000000101, 3, 7},
498 {8, 0b00100011, 4, 0}, {8, 0b00100001, 4, 1}, {8, 0b00011111, 4, 2}, {9, 0b000111010, 4, 3},
499 {9, 0b000011110, 4, 4}, {10, 0b0000010000, 4, 5}, {9, 0b000000111, 4, 6}, {10, 0b0000000101, 4, 7},
500 {8, 0b00011100, 5, 0}, {8, 0b00011010, 5, 1}, {9, 0b000100000, 5, 2}, {10, 0b0000010011, 5, 3},
501 {10, 0b0000010001, 5, 4}, {11, 0b00000001111, 5, 5}, {10, 0b0000001000, 5, 6}, {11, 0b00000001110, 5, 7},
502 {8, 0b00001110, 6, 0}, {7, 0b0001100, 6, 1}, {7, 0b0001001, 6, 2}, {8, 0b00001101, 6, 3},
503 {9, 0b000001110, 6, 4}, {10, 0b0000001001, 6, 5}, {10, 0b0000000100, 6, 6}, {10, 0b0000000001, 6, 7},
504 {8, 0b00001011, 7, 0}, {7, 0b0000100, 7, 1}, {8, 0b00000110, 7, 2}, {9, 0b000000110, 7, 3},
505 {10, 0b0000000110, 7, 4}, {10, 0b0000000011, 7, 5}, {10, 0b0000000010, 7, 6}, {10, 0b0000000000, 7, 7},
506 };
507
508 static constexpr HuffCode kHuff12[] = {
509 {4, 0b1001, 0, 0}, {3, 0b110, 0, 1}, {5, 0b10000, 0, 2}, {7, 0b0100001, 0, 3}, {8, 0b00101001, 0, 4},
510 {9, 0b000100111, 0, 5}, {9, 0b000100110, 0, 6}, {9, 0b000011010, 0, 7}, {3, 0b111, 1, 0}, {3, 0b101, 1, 1},
511 {4, 0b0110, 1, 2}, {5, 0b01001, 1, 3}, {7, 0b0010111, 1, 4}, {7, 0b0010000, 1, 5}, {8, 0b00011010, 1, 6},
512 {8, 0b00001011, 1, 7}, {5, 0b10001, 2, 0}, {4, 0b0111, 2, 1}, {5, 0b01011, 2, 2}, {6, 0b001110, 2, 3},
513 {7, 0b0010101, 2, 4}, {8, 0b00011110, 2, 5}, {7, 0b0001010, 2, 6}, {8, 0b00000111, 2, 7},
514 {6, 0b010001, 3, 0}, {5, 0b01010, 3, 1}, {6, 0b001111, 3, 2}, {6, 0b001100, 3, 3}, {7, 0b0010010, 3, 4},
515 {8, 0b00011100, 3, 5}, {8, 0b00001110, 3, 6}, {8, 0b00000101, 3, 7}, {7, 0b0100000, 4, 0},
516 {6, 0b001101, 4, 1}, {7, 0b0010110, 4, 2}, {7, 0b0010011, 4, 3}, {8, 0b00010010, 4, 4},
517 {8, 0b00010000, 4, 5}, {8, 0b00001001, 4, 6}, {9, 0b000000101, 4, 7}, {8, 0b00101000, 5, 0},
518 {7, 0b0010001, 5, 1}, {8, 0b00011111, 5, 2}, {8, 0b00011101, 5, 3}, {8, 0b00010001, 5, 4},
519 {9, 0b000001101, 5, 5}, {8, 0b00000100, 5, 6}, {9, 0b000000010, 5, 7}, {8, 0b00011011, 6, 0},
520 {7, 0b0001100, 6, 1}, {7, 0b0001011, 6, 2}, {8, 0b00001111, 6, 3}, {8, 0b00001010, 6, 4},
521 {9, 0b000000111, 6, 5}, {9, 0b000000100, 6, 6}, {10, 0b0000000001, 6, 7}, {9, 0b000011011, 7, 0},
522 {8, 0b00001100, 7, 1}, {8, 0b00001000, 7, 2}, {9, 0b000001100, 7, 3}, {9, 0b000000110, 7, 4},
523 {9, 0b000000011, 7, 5}, {9, 0b000000001, 7, 6}, {10, 0b0000000000, 7, 7},
524 };
525
526 static constexpr HuffCode kHuff13[] = {
527 {1, 0b1, 0, 0}, {4, 0b0101, 0, 1}, {6, 0b001110, 0, 2}, {7, 0b0010101, 0, 3}, {8, 0b00100010, 0, 4},
528 {9, 0b000110011, 0, 5}, {9, 0b000101110, 0, 6}, {10, 0b0001000111, 0, 7}, {9, 0b000101010, 0, 8},
529 {10, 0b0000110100, 0, 9}, {11, 0b00001000100, 0, 10}, {11, 0b00000110100, 0, 11},
530 {12, 0b000001000011, 0, 12}, {12, 0b000000101100, 0, 13}, {13, 0b0000000101011, 0, 14},
531 {13, 0b0000000010011, 0, 15}, {3, 0b011, 1, 0}, {4, 0b0100, 1, 1}, {6, 0b001100, 1, 2},
532 {7, 0b0010011, 1, 3}, {8, 0b00011111, 1, 4}, {8, 0b00011010, 1, 5}, {9, 0b000101100, 1, 6},
533 {9, 0b000100001, 1, 7}, {9, 0b000011111, 1, 8}, {9, 0b000011000, 1, 9}, {10, 0b0000100000, 1, 10},
534 {10, 0b0000011000, 1, 11}, {11, 0b00000011111, 1, 12}, {12, 0b000000100011, 1, 13},
535 {12, 0b000000010110, 1, 14}, {12, 0b000000001110, 1, 15}, {6, 0b001111, 2, 0}, {6, 0b001101, 2, 1},
536 {7, 0b0010111, 2, 2}, {8, 0b00100100, 2, 3}, {9, 0b000111011, 2, 4}, {9, 0b000110001, 2, 5},
537 {10, 0b0001001101, 2, 6}, {10, 0b0001000001, 2, 7}, {9, 0b000011101, 2, 8}, {10, 0b0000101000, 2, 9},
538 {10, 0b0000011110, 2, 10}, {11, 0b00000101000, 2, 11}, {11, 0b00000011011, 2, 12},
539 {12, 0b000000100001, 2, 13}, {13, 0b0000000101010, 2, 14}, {13, 0b0000000010000, 2, 15},
540 {7, 0b0010110, 3, 0}, {7, 0b0010100, 3, 1}, {8, 0b00100101, 3, 2}, {9, 0b000111101, 3, 3},
541 {9, 0b000111000, 3, 4}, {10, 0b0001001111, 3, 5}, {10, 0b0001001001, 3, 6}, {10, 0b0001000000, 3, 7},
542 {10, 0b0000101011, 3, 8}, {11, 0b00001001100, 3, 9}, {11, 0b00000111000, 3, 10},
543 {11, 0b00000100101, 3, 11}, {11, 0b00000011010, 3, 12}, {12, 0b000000011111, 3, 13},
544 {13, 0b0000000011001, 3, 14}, {13, 0b0000000001110, 3, 15}, {8, 0b00100011, 4, 0}, {7, 0b0010000, 4, 1},
545 {9, 0b000111100, 4, 2}, {9, 0b000111001, 4, 3}, {10, 0b0001100001, 4, 4}, {10, 0b0001001011, 4, 5},
546 {11, 0b00001110010, 4, 6}, {11, 0b00001011011, 4, 7}, {10, 0b0000110110, 4, 8}, {11, 0b00001001001, 4, 9},
547 {11, 0b00000110111, 4, 10}, {12, 0b000000101001, 4, 11}, {12, 0b000000110000, 4, 12},
548 {13, 0b0000000110101, 4, 13}, {13, 0b0000000010111, 4, 14}, {14, 0b00000000011000, 4, 15},
549 {9, 0b000111010, 5, 0}, {8, 0b00011011, 5, 1}, {9, 0b000110010, 5, 2}, {10, 0b0001100000, 5, 3},
550 {10, 0b0001001100, 5, 4}, {10, 0b0001000110, 5, 5}, {11, 0b00001011101, 5, 6}, {11, 0b00001010100, 5, 7},
551 {11, 0b00001001101, 5, 8}, {11, 0b00000111010, 5, 9}, {12, 0b000001001111, 5, 10},
552 {11, 0b00000011101, 5, 11}, {13, 0b0000001001010, 5, 12}, {13, 0b0000000110001, 5, 13},
553 {14, 0b00000000101001, 5, 14}, {14, 0b00000000010001, 5, 15}, {9, 0b000101111, 6, 0},
554 {9, 0b000101101, 6, 1}, {10, 0b0001001110, 6, 2}, {10, 0b0001001010, 6, 3}, {11, 0b00001110011, 6, 4},
555 {11, 0b00001011110, 6, 5}, {11, 0b00001011010, 6, 6}, {11, 0b00001001111, 6, 7}, {11, 0b00001000101, 6, 8},
556 {12, 0b000001010011, 6, 9}, {12, 0b000001000111, 6, 10}, {12, 0b000000110010, 6, 11},
557 {13, 0b0000000111011, 6, 12}, {13, 0b0000000100110, 6, 13}, {14, 0b00000000100100, 6, 14},
558 {14, 0b00000000001111, 6, 15}, {10, 0b0001001000, 7, 0}, {9, 0b000100010, 7, 1}, {10, 0b0000111000, 7, 2},
559 {11, 0b00001011111, 7, 3}, {11, 0b00001011100, 7, 4}, {11, 0b00001010101, 7, 5},
560 {12, 0b000001011011, 7, 6}, {12, 0b000001011010, 7, 7}, {12, 0b000001010110, 7, 8},
561 {12, 0b000001001001, 7, 9}, {13, 0b0000001001101, 7, 10}, {13, 0b0000001000001, 7, 11},
562 {13, 0b0000000110011, 7, 12}, {14, 0b00000000101100, 7, 13}, {16, 0b0000000000101011, 7, 14},
563 {16, 0b0000000000101010, 7, 15}, {9, 0b000101011, 8, 0}, {8, 0b00010100, 8, 1}, {9, 0b000011110, 8, 2},
564 {10, 0b0000101100, 8, 3}, {10, 0b0000110111, 8, 4}, {11, 0b00001001110, 8, 5}, {11, 0b00001001000, 8, 6},
565 {12, 0b000001010111, 8, 7}, {12, 0b000001001110, 8, 8}, {12, 0b000000111101, 8, 9},
566 {12, 0b000000101110, 8, 10}, {13, 0b0000000110110, 8, 11}, {13, 0b0000000100101, 8, 12},
567 {14, 0b00000000011110, 8, 13}, {15, 0b000000000010100, 8, 14}, {15, 0b000000000010000, 8, 15},
568 {10, 0b0000110101, 9, 0}, {9, 0b000011001, 9, 1}, {10, 0b0000101001, 9, 2}, {10, 0b0000100101, 9, 3},
569 {11, 0b00000101100, 9, 4}, {11, 0b00000111011, 9, 5}, {11, 0b00000110110, 9, 6},
570 {13, 0b0000001010001, 9, 7}, {12, 0b000001000010, 9, 8}, {13, 0b0000001001100, 9, 9},
571 {13, 0b0000000111001, 9, 10}, {14, 0b00000000110110, 9, 11}, {14, 0b00000000100101, 9, 12},
572 {14, 0b00000000010010, 9, 13}, {16, 0b0000000000100111, 9, 14}, {15, 0b000000000001011, 9, 15},
573 {10, 0b0000100011, 10, 0}, {10, 0b0000100001, 10, 1}, {10, 0b0000011111, 10, 2},
574 {11, 0b00000111001, 10, 3}, {11, 0b00000101010, 10, 4}, {12, 0b000001010010, 10, 5},
575 {12, 0b000001001000, 10, 6}, {13, 0b0000001010000, 10, 7}, {12, 0b000000101111, 10, 8},
576 {13, 0b0000000111010, 10, 9}, {14, 0b00000000110111, 10, 10}, {13, 0b0000000010101, 10, 11},
577 {14, 0b00000000010110, 10, 12}, {15, 0b000000000011010, 10, 13}, {16, 0b0000000000100110, 10, 14},
578 {17, 0b00000000000010110, 10, 15}, {11, 0b00000110101, 11, 0}, {10, 0b0000011001, 11, 1},
579 {10, 0b0000010111, 11, 2}, {11, 0b00000100110, 11, 3}, {12, 0b000001000110, 11, 4},
580 {12, 0b000000111100, 11, 5}, {12, 0b000000110011, 11, 6}, {12, 0b000000100100, 11, 7},
581 {13, 0b0000000110111, 11, 8}, {13, 0b0000000011010, 11, 9}, {13, 0b0000000100010, 11, 10},
582 {14, 0b00000000010111, 11, 11}, {15, 0b000000000011011, 11, 12}, {15, 0b000000000001110, 11, 13},
583 {15, 0b000000000001001, 11, 14}, {16, 0b0000000000000111, 11, 15}, {11, 0b00000100010, 12, 0},
584 {11, 0b00000100000, 12, 1}, {11, 0b00000011100, 12, 2}, {12, 0b000000100111, 12, 3},
585 {12, 0b000000110001, 12, 4}, {13, 0b0000001001011, 12, 5}, {12, 0b000000011110, 12, 6},
586 {13, 0b0000000110100, 12, 7}, {14, 0b00000000110000, 12, 8}, {14, 0b00000000101000, 12, 9},
587 {15, 0b000000000110100, 12, 10}, {15, 0b000000000011100, 12, 11}, {15, 0b000000000010010, 12, 12},
588 {16, 0b0000000000010001, 12, 13}, {16, 0b0000000000001001, 12, 14}, {16, 0b0000000000000101, 12, 15},
589 {12, 0b000000101101, 13, 0}, {11, 0b00000010101, 13, 1}, {12, 0b000000100010, 13, 2},
590 {13, 0b0000001000000, 13, 3}, {13, 0b0000000111000, 13, 4}, {13, 0b0000000110010, 13, 5},
591 {14, 0b00000000110001, 13, 6}, {14, 0b00000000101101, 13, 7}, {14, 0b00000000011111, 13, 8},
592 {14, 0b00000000010011, 13, 9}, {14, 0b00000000001100, 13, 10}, {15, 0b000000000001111, 13, 11},
593 {16, 0b0000000000001010, 13, 12}, {15, 0b000000000000111, 13, 13}, {16, 0b0000000000000110, 13, 14},
594 {16, 0b0000000000000011, 13, 15}, {13, 0b0000000110000, 14, 0}, {12, 0b000000010111, 14, 1},
595 {12, 0b000000010100, 14, 2}, {13, 0b0000000100111, 14, 3}, {13, 0b0000000100100, 14, 4},
596 {13, 0b0000000100011, 14, 5}, {15, 0b000000000110101, 14, 6}, {14, 0b00000000010101, 14, 7},
597 {14, 0b00000000010000, 14, 8}, {17, 0b00000000000010111, 14, 9}, {15, 0b000000000001101, 14, 10},
598 {15, 0b000000000001010, 14, 11}, {15, 0b000000000000110, 14, 12}, {17, 0b00000000000000001, 14, 13},
599 {16, 0b0000000000000100, 14, 14}, {16, 0b0000000000000010, 14, 15}, {12, 0b000000010000, 15, 0},
600 {12, 0b000000001111, 15, 1}, {13, 0b0000000010001, 15, 2}, {14, 0b00000000011011, 15, 3},
601 {14, 0b00000000011001, 15, 4}, {14, 0b00000000010100, 15, 5}, {15, 0b000000000011101, 15, 6},
602 {14, 0b00000000001011, 15, 7}, {15, 0b000000000010001, 15, 8}, {15, 0b000000000001100, 15, 9},
603 {16, 0b0000000000010000, 15, 10}, {16, 0b0000000000001000, 15, 11}, {19, 0b0000000000000000001, 15, 12},
604 {18, 0b000000000000000001, 15, 13}, {19, 0b0000000000000000000, 15, 14}, {16, 0b0000000000000001, 15, 15},
605 };
606
607 static constexpr HuffCode kHuff15[] = {
608 {3, 0b111, 0, 0}, {4, 0b1100, 0, 1}, {5, 0b10010, 0, 2}, {7, 0b0110101, 0, 3}, {7, 0b0101111, 0, 4},
609 {8, 0b01001100, 0, 5}, {9, 0b001111100, 0, 6}, {9, 0b001101100, 0, 7}, {9, 0b001011001, 0, 8},
610 {10, 0b0001111011, 0, 9}, {10, 0b0001101100, 0, 10}, {11, 0b00001110111, 0, 11},
611 {11, 0b00001101011, 0, 12}, {11, 0b00001010001, 0, 13}, {12, 0b000001111010, 0, 14},
612 {13, 0b0000000111111, 0, 15}, {4, 0b1101, 1, 0}, {3, 0b101, 1, 1}, {5, 0b10000, 1, 2}, {6, 0b011011, 1, 3},
613 {7, 0b0101110, 1, 4}, {7, 0b0100100, 1, 5}, {8, 0b00111101, 1, 6}, {8, 0b00110011, 1, 7},
614 {8, 0b00101010, 1, 8}, {9, 0b001000110, 1, 9}, {9, 0b000110100, 1, 10}, {10, 0b0001010011, 1, 11},
615 {10, 0b0001000001, 1, 12}, {10, 0b0000101001, 1, 13}, {11, 0b00000111011, 1, 14},
616 {11, 0b00000100100, 1, 15}, {5, 0b10011, 2, 0}, {5, 0b10001, 2, 1}, {5, 0b01111, 2, 2},
617 {6, 0b011000, 2, 3}, {7, 0b0101001, 2, 4}, {7, 0b0100010, 2, 5}, {8, 0b00111011, 2, 6},
618 {8, 0b00110000, 2, 7}, {8, 0b00101000, 2, 8}, {9, 0b001000000, 2, 9}, {9, 0b000110010, 2, 10},
619 {10, 0b0001001110, 2, 11}, {10, 0b0000111110, 2, 12}, {11, 0b00001010000, 2, 13},
620 {11, 0b00000111000, 2, 14}, {11, 0b00000100001, 2, 15}, {6, 0b011101, 3, 0}, {6, 0b011100, 3, 1},
621 {6, 0b011001, 3, 2}, {7, 0b0101011, 3, 3}, {7, 0b0100111, 3, 4}, {8, 0b00111111, 3, 5},
622 {8, 0b00110111, 3, 6}, {9, 0b001011101, 3, 7}, {9, 0b001001100, 3, 8}, {9, 0b000111011, 3, 9},
623 {10, 0b0001011101, 3, 10}, {10, 0b0001001000, 3, 11}, {10, 0b0000110110, 3, 12},
624 {11, 0b00001001011, 3, 13}, {11, 0b00000110010, 3, 14}, {11, 0b00000011101, 3, 15}, {7, 0b0110100, 4, 0},
625 {6, 0b010110, 4, 1}, {7, 0b0101010, 4, 2}, {7, 0b0101000, 4, 3}, {8, 0b01000011, 4, 4},
626 {8, 0b00111001, 4, 5}, {9, 0b001011111, 4, 6}, {9, 0b001001111, 4, 7}, {9, 0b001001000, 4, 8},
627 {9, 0b000111001, 4, 9}, {10, 0b0001011001, 4, 10}, {10, 0b0001000101, 4, 11}, {10, 0b0000110001, 4, 12},
628 {11, 0b00001000010, 4, 13}, {11, 0b00000101110, 4, 14}, {11, 0b00000011011, 4, 15}, {8, 0b01001101, 5, 0},
629 {7, 0b0100101, 5, 1}, {7, 0b0100011, 5, 2}, {8, 0b01000010, 5, 3}, {8, 0b00111010, 5, 4},
630 {8, 0b00110100, 5, 5}, {9, 0b001011011, 5, 6}, {9, 0b001001010, 5, 7}, {9, 0b000111110, 5, 8},
631 {9, 0b000110000, 5, 9}, {10, 0b0001001111, 5, 10}, {10, 0b0000111111, 5, 11}, {11, 0b00001011010, 5, 12},
632 {11, 0b00000111110, 5, 13}, {11, 0b00000101000, 5, 14}, {12, 0b000000100110, 5, 15},
633 {9, 0b001111101, 6, 0}, {7, 0b0100000, 6, 1}, {8, 0b00111100, 6, 2}, {8, 0b00111000, 6, 3},
634 {8, 0b00110010, 6, 4}, {9, 0b001011100, 6, 5}, {9, 0b001001110, 6, 6}, {9, 0b001000001, 6, 7},
635 {9, 0b000110111, 6, 8}, {10, 0b0001010111, 6, 9}, {10, 0b0001000111, 6, 10}, {10, 0b0000110011, 6, 11},
636 {11, 0b00001001001, 6, 12}, {11, 0b00000110011, 6, 13}, {12, 0b000001000110, 6, 14},
637 {12, 0b000000011110, 6, 15}, {9, 0b001101101, 7, 0}, {8, 0b00110101, 7, 1}, {8, 0b00110001, 7, 2},
638 {9, 0b001011110, 7, 3}, {9, 0b001011000, 7, 4}, {9, 0b001001011, 7, 5}, {9, 0b001000010, 7, 6},
639 {10, 0b0001111010, 7, 7}, {10, 0b0001011011, 7, 8}, {10, 0b0001001001, 7, 9}, {10, 0b0000111000, 7, 10},
640 {10, 0b0000101010, 7, 11}, {11, 0b00001000000, 7, 12}, {11, 0b00000101100, 7, 13},
641 {11, 0b00000010101, 7, 14}, {12, 0b000000011001, 7, 15}, {9, 0b001011010, 8, 0}, {8, 0b00101011, 8, 1},
642 {8, 0b00101001, 8, 2}, {9, 0b001001101, 8, 3}, {9, 0b001001001, 8, 4}, {9, 0b000111111, 8, 5},
643 {9, 0b000111000, 8, 6}, {10, 0b0001011100, 8, 7}, {10, 0b0001001101, 8, 8}, {10, 0b0001000010, 8, 9},
644 {10, 0b0000101111, 8, 10}, {11, 0b00001000011, 8, 11}, {11, 0b00000110000, 8, 12},
645 {12, 0b000000110101, 8, 13}, {12, 0b000000100100, 8, 14}, {12, 0b000000010100, 8, 15},
646 {9, 0b001000111, 9, 0}, {8, 0b00100010, 9, 1}, {9, 0b001000011, 9, 2}, {9, 0b000111100, 9, 3},
647 {9, 0b000111010, 9, 4}, {9, 0b000110001, 9, 5}, {10, 0b0001011000, 9, 6}, {10, 0b0001001100, 9, 7},
648 {10, 0b0001000011, 9, 8}, {11, 0b00001101010, 9, 9}, {11, 0b00001000111, 9, 10},
649 {11, 0b00000110110, 9, 11}, {11, 0b00000100110, 9, 12}, {12, 0b000000100111, 9, 13},
650 {12, 0b000000010111, 9, 14}, {12, 0b000000001111, 9, 15}, {10, 0b0001101101, 10, 0},
651 {9, 0b000110101, 10, 1}, {9, 0b000110011, 10, 2}, {9, 0b000101111, 10, 3}, {10, 0b0001011010, 10, 4},
652 {10, 0b0001010010, 10, 5}, {10, 0b0000111010, 10, 6}, {10, 0b0000111001, 10, 7}, {10, 0b0000110000, 10, 8},
653 {11, 0b00001001000, 10, 9}, {11, 0b00000111001, 10, 10}, {11, 0b00000101001, 10, 11},
654 {11, 0b00000010111, 10, 12}, {12, 0b000000011011, 10, 13}, {13, 0b0000000111110, 10, 14},
655 {12, 0b000000001001, 10, 15}, {10, 0b0001010110, 11, 0}, {9, 0b000101010, 11, 1}, {9, 0b000101000, 11, 2},
656 {9, 0b000100101, 11, 3}, {10, 0b0001000110, 11, 4}, {10, 0b0001000000, 11, 5}, {10, 0b0000110100, 11, 6},
657 {10, 0b0000101011, 11, 7}, {11, 0b00001000110, 11, 8}, {11, 0b00000110111, 11, 9},
658 {11, 0b00000101010, 11, 10}, {11, 0b00000011001, 11, 11}, {12, 0b000000011101, 11, 12},
659 {12, 0b000000010010, 11, 13}, {12, 0b000000001011, 11, 14}, {13, 0b0000000001011, 11, 15},
660 {11, 0b00001110110, 12, 0}, {10, 0b0001000100, 12, 1}, {9, 0b000011110, 12, 2}, {10, 0b0000110111, 12, 3},
661 {10, 0b0000110010, 12, 4}, {10, 0b0000101110, 12, 5}, {11, 0b00001001010, 12, 6},
662 {11, 0b00001000001, 12, 7}, {11, 0b00000110001, 12, 8}, {11, 0b00000100111, 12, 9},
663 {11, 0b00000011000, 12, 10}, {11, 0b00000010000, 12, 11}, {12, 0b000000010110, 12, 12},
664 {12, 0b000000001101, 12, 13}, {13, 0b0000000001110, 12, 14}, {13, 0b0000000000111, 12, 15},
665 {11, 0b00001011011, 13, 0}, {10, 0b0000101100, 13, 1}, {10, 0b0000100111, 13, 2},
666 {10, 0b0000100110, 13, 3}, {10, 0b0000100010, 13, 4}, {11, 0b00000111111, 13, 5},
667 {11, 0b00000110100, 13, 6}, {11, 0b00000101101, 13, 7}, {11, 0b00000011111, 13, 8},
668 {12, 0b000000110100, 13, 9}, {12, 0b000000011100, 13, 10}, {12, 0b000000010011, 13, 11},
669 {12, 0b000000001110, 13, 12}, {12, 0b000000001000, 13, 13}, {13, 0b0000000001001, 13, 14},
670 {13, 0b0000000000011, 13, 15}, {12, 0b000001111011, 14, 0}, {11, 0b00000111100, 14, 1},
671 {11, 0b00000111010, 14, 2}, {11, 0b00000110101, 14, 3}, {11, 0b00000101111, 14, 4},
672 {11, 0b00000101011, 14, 5}, {11, 0b00000100000, 14, 6}, {11, 0b00000010110, 14, 7},
673 {12, 0b000000100101, 14, 8}, {12, 0b000000011000, 14, 9}, {12, 0b000000010001, 14, 10},
674 {12, 0b000000001100, 14, 11}, {13, 0b0000000001111, 14, 12}, {13, 0b0000000001010, 14, 13},
675 {12, 0b000000000010, 14, 14}, {13, 0b0000000000001, 14, 15}, {12, 0b000001000111, 15, 0},
676 {11, 0b00000100101, 15, 1}, {11, 0b00000100010, 15, 2}, {11, 0b00000011110, 15, 3},
677 {11, 0b00000011100, 15, 4}, {11, 0b00000010100, 15, 5}, {11, 0b00000010001, 15, 6},
678 {12, 0b000000011010, 15, 7}, {12, 0b000000010101, 15, 8}, {12, 0b000000010000, 15, 9},
679 {12, 0b000000001010, 15, 10}, {12, 0b000000000110, 15, 11}, {13, 0b0000000001000, 15, 12},
680 {13, 0b0000000000110, 15, 13}, {13, 0b0000000000010, 15, 14}, {13, 0b0000000000000, 15, 15},
681 };
682
683 static constexpr HuffCode kHuff16[] = {
684 {1, 0b1, 0, 0}, {4, 0b0101, 0, 1}, {6, 0b001110, 0, 2}, {8, 0b00101100, 0, 3}, {9, 0b001001010, 0, 4},
685 {9, 0b000111111, 0, 5}, {10, 0b0001101110, 0, 6}, {10, 0b0001011101, 0, 7}, {11, 0b00010101100, 0, 8},
686 {11, 0b00010010101, 0, 9}, {11, 0b00010001010, 0, 10}, {12, 0b000011110010, 0, 11},
687 {12, 0b000011100001, 0, 12}, {12, 0b000011000011, 0, 13}, {13, 0b0000101111000, 0, 14},
688 {9, 0b000010001, 0, 15}, {3, 0b011, 1, 0}, {4, 0b0100, 1, 1}, {6, 0b001100, 1, 2}, {7, 0b0010100, 1, 3},
689 {8, 0b00100011, 1, 4}, {9, 0b000111110, 1, 5}, {9, 0b000110101, 1, 6}, {9, 0b000101111, 1, 7},
690 {10, 0b0001010011, 1, 8}, {10, 0b0001001011, 1, 9}, {10, 0b0001000100, 1, 10}, {11, 0b00001110111, 1, 11},
691 {12, 0b000011001001, 1, 12}, {11, 0b00001101011, 1, 13}, {12, 0b000011001111, 1, 14},
692 {8, 0b00001001, 1, 15}, {6, 0b001111, 2, 0}, {6, 0b001101, 2, 1}, {7, 0b0010111, 2, 2},
693 {8, 0b00100110, 2, 3}, {9, 0b001000011, 2, 4}, {9, 0b000111010, 2, 5}, {10, 0b0001100111, 2, 6},
694 {10, 0b0001011010, 2, 7}, {11, 0b00010100001, 2, 8}, {10, 0b0001001000, 2, 9}, {11, 0b00001111111, 2, 10},
695 {11, 0b00001110101, 2, 11}, {11, 0b00001101110, 2, 12}, {12, 0b000011010001, 2, 13},
696 {12, 0b000011001110, 2, 14}, {9, 0b000010000, 2, 15}, {8, 0b00101101, 3, 0}, {7, 0b0010101, 3, 1},
697 {8, 0b00100111, 3, 2}, {9, 0b001000101, 3, 3}, {9, 0b001000000, 3, 4}, {10, 0b0001110010, 3, 5},
698 {10, 0b0001100011, 3, 6}, {10, 0b0001010111, 3, 7}, {11, 0b00010011110, 3, 8}, {11, 0b00010001100, 3, 9},
699 {12, 0b000011111100, 3, 10}, {12, 0b000011010100, 3, 11}, {12, 0b000011000111, 3, 12},
700 {13, 0b0000110000011, 3, 13}, {13, 0b0000101101101, 3, 14}, {10, 0b0000011010, 3, 15},
701 {9, 0b001001011, 4, 0}, {8, 0b00100100, 4, 1}, {9, 0b001000100, 4, 2}, {9, 0b001000001, 4, 3},
702 {10, 0b0001110011, 4, 4}, {10, 0b0001100101, 4, 5}, {11, 0b00010110011, 4, 6}, {11, 0b00010100100, 4, 7},
703 {11, 0b00010011011, 4, 8}, {12, 0b000100001000, 4, 9}, {12, 0b000011110110, 4, 10},
704 {12, 0b000011100010, 4, 11}, {13, 0b0000110001011, 4, 12}, {13, 0b0000101111110, 4, 13},
705 {13, 0b0000101101010, 4, 14}, {9, 0b000001001, 4, 15}, {9, 0b001000010, 5, 0}, {8, 0b00011110, 5, 1},
706 {9, 0b000111011, 5, 2}, {9, 0b000111000, 5, 3}, {10, 0b0001100110, 5, 4}, {11, 0b00010111001, 5, 5},
707 {11, 0b00010101101, 5, 6}, {12, 0b000100001001, 5, 7}, {11, 0b00010001110, 5, 8},
708 {12, 0b000011111101, 5, 9}, {12, 0b000011101000, 5, 10}, {13, 0b0000110010000, 5, 11},
709 {13, 0b0000110000100, 5, 12}, {13, 0b0000101111010, 5, 13}, {14, 0b00000110111101, 5, 14},
710 {10, 0b0000010000, 5, 15}, {10, 0b0001101111, 6, 0}, {9, 0b000110110, 6, 1}, {9, 0b000110100, 6, 2},
711 {10, 0b0001100100, 6, 3}, {11, 0b00010111000, 6, 4}, {11, 0b00010110010, 6, 5}, {11, 0b00010100000, 6, 6},
712 {11, 0b00010000101, 6, 7}, {12, 0b000100000001, 6, 8}, {12, 0b000011110100, 6, 9},
713 {12, 0b000011100100, 6, 10}, {12, 0b000011011001, 6, 11}, {13, 0b0000110000001, 6, 12},
714 {13, 0b0000101101110, 6, 13}, {14, 0b00001011001011, 6, 14}, {10, 0b0000001010, 6, 15},
715 {10, 0b0001100010, 7, 0}, {9, 0b000110000, 7, 1}, {10, 0b0001011011, 7, 2}, {10, 0b0001011000, 7, 3},
716 {11, 0b00010100101, 7, 4}, {11, 0b00010011101, 7, 5}, {11, 0b00010010100, 7, 6},
717 {12, 0b000100000101, 7, 7}, {12, 0b000011111000, 7, 8}, {13, 0b0000110010111, 7, 9},
718 {13, 0b0000110001101, 7, 10}, {13, 0b0000101110100, 7, 11}, {13, 0b0000101111100, 7, 12},
719 {15, 0b000001101111001, 7, 13}, {15, 0b000001101110100, 7, 14}, {10, 0b0000001000, 7, 15},
720 {10, 0b0001010101, 8, 0}, {10, 0b0001010100, 8, 1}, {10, 0b0001010001, 8, 2}, {11, 0b00010011111, 8, 3},
721 {11, 0b00010011100, 8, 4}, {11, 0b00010001111, 8, 5}, {12, 0b000100000100, 8, 6},
722 {12, 0b000011111001, 8, 7}, {13, 0b0000110101011, 8, 8}, {13, 0b0000110010001, 8, 9},
723 {13, 0b0000110001000, 8, 10}, {13, 0b0000101111111, 8, 11}, {14, 0b00001011010111, 8, 12},
724 {14, 0b00001011001001, 8, 13}, {14, 0b00001011000100, 8, 14}, {10, 0b0000000111, 8, 15},
725 {11, 0b00010011010, 9, 0}, {10, 0b0001001100, 9, 1}, {10, 0b0001001001, 9, 2}, {11, 0b00010001101, 9, 3},
726 {11, 0b00010000011, 9, 4}, {12, 0b000100000000, 9, 5}, {12, 0b000011110101, 9, 6},
727 {13, 0b0000110101010, 9, 7}, {13, 0b0000110010110, 9, 8}, {13, 0b0000110001010, 9, 9},
728 {13, 0b0000110000000, 9, 10}, {14, 0b00001011011111, 9, 11}, {13, 0b0000101100111, 9, 12},
729 {14, 0b00001011000110, 9, 13}, {13, 0b0000101100000, 9, 14}, {11, 0b00000001011, 9, 15},
730 {11, 0b00010001011, 10, 0}, {11, 0b00010000001, 10, 1}, {10, 0b0001000011, 10, 2},
731 {11, 0b00001111101, 10, 3}, {12, 0b000011110111, 10, 4}, {12, 0b000011101001, 10, 5},
732 {12, 0b000011100101, 10, 6}, {12, 0b000011011011, 10, 7}, {13, 0b0000110001001, 10, 8},
733 {14, 0b00001011100111, 10, 9}, {14, 0b00001011100001, 10, 10}, {14, 0b00001011010000, 10, 11},
734 {15, 0b000001101110101, 10, 12}, {15, 0b000001101110010, 10, 13}, {14, 0b00000110110111, 10, 14},
735 {10, 0b0000000100, 10, 15}, {12, 0b000011110011, 11, 0}, {11, 0b00001111000, 11, 1},
736 {11, 0b00001110110, 11, 2}, {11, 0b00001110011, 11, 3}, {12, 0b000011100011, 11, 4},
737 {12, 0b000011011111, 11, 5}, {13, 0b0000110001100, 11, 6}, {14, 0b00001011101010, 11, 7},
738 {14, 0b00001011100110, 11, 8}, {14, 0b00001011100000, 11, 9}, {14, 0b00001011010001, 11, 10},
739 {14, 0b00001011001000, 11, 11}, {14, 0b00001011000010, 11, 12}, {13, 0b0000011011111, 11, 13},
740 {14, 0b00000110110100, 11, 14}, {11, 0b00000000110, 11, 15}, {12, 0b000011001010, 12, 0},
741 {12, 0b000011100000, 12, 1}, {12, 0b000011011110, 12, 2}, {12, 0b000011011010, 12, 3},
742 {12, 0b000011011000, 12, 4}, {13, 0b0000110000101, 12, 5}, {13, 0b0000110000010, 12, 6},
743 {13, 0b0000101111101, 12, 7}, {13, 0b0000101101100, 12, 8}, {15, 0b000001101111000, 12, 9},
744 {14, 0b00000110111011, 12, 10}, {14, 0b00001011000011, 12, 11}, {14, 0b00000110111000, 12, 12},
745 {14, 0b00000110110101, 12, 13}, {16, 0b0000011011000000, 12, 14}, {11, 0b00000000100, 12, 15},
746 {14, 0b00001011101011, 13, 0}, {12, 0b000011010011, 13, 1}, {12, 0b000011010010, 13, 2},
747 {12, 0b000011010000, 13, 3}, {13, 0b0000101110010, 13, 4}, {13, 0b0000101111011, 13, 5},
748 {14, 0b00001011011110, 13, 6}, {14, 0b00001011010011, 13, 7}, {14, 0b00001011001010, 13, 8},
749 {16, 0b0000011011000111, 13, 9}, {15, 0b000001101110011, 13, 10}, {15, 0b000001101101101, 13, 11},
750 {15, 0b000001101101100, 13, 12}, {17, 0b00000110110000011, 13, 13}, {15, 0b000001101100001, 13, 14},
751 {11, 0b00000000010, 13, 15}, {13, 0b0000101111001, 14, 0}, {13, 0b0000101110001, 14, 1},
752 {11, 0b00001100110, 14, 2}, {12, 0b000010111011, 14, 3}, {14, 0b00001011010110, 14, 4},
753 {14, 0b00001011010010, 14, 5}, {13, 0b0000101100110, 14, 6}, {14, 0b00001011000111, 14, 7},
754 {14, 0b00001011000101, 14, 8}, {15, 0b000001101100010, 14, 9}, {16, 0b0000011011000110, 14, 10},
755 {15, 0b000001101100111, 14, 11}, {17, 0b00000110110000010, 14, 12}, {15, 0b000001101100110, 14, 13},
756 {14, 0b00000110110010, 14, 14}, {11, 0b00000000000, 14, 15}, {9, 0b000001100, 15, 0},
757 {8, 0b00001010, 15, 1}, {8, 0b00000111, 15, 2}, {9, 0b000001011, 15, 3}, {9, 0b000001010, 15, 4},
758 {10, 0b0000010001, 15, 5}, {10, 0b0000001011, 15, 6}, {10, 0b0000001001, 15, 7},
759 {11, 0b00000001101, 15, 8}, {11, 0b00000001100, 15, 9}, {11, 0b00000001010, 15, 10},
760 {11, 0b00000000111, 15, 11}, {11, 0b00000000101, 15, 12}, {11, 0b00000000011, 15, 13},
761 {11, 0b00000000001, 15, 14}, {8, 0b00000011, 15, 15},
762 };
763
764 static constexpr HuffCode kHuff24[] = {
765 {4, 0b1111, 0, 0}, {4, 0b1101, 0, 1}, {6, 0b101110, 0, 2}, {7, 0b1010000, 0, 3}, {8, 0b10010010, 0, 4},
766 {9, 0b100000110, 0, 5}, {9, 0b011111000, 0, 6}, {10, 0b0110110010, 0, 7}, {10, 0b0110101010, 0, 8},
767 {11, 0b01010011101, 0, 9}, {11, 0b01010001101, 0, 10}, {11, 0b01010001001, 0, 11},
768 {11, 0b01001101101, 0, 12}, {11, 0b01000000101, 0, 13}, {12, 0b010000001000, 0, 14},
769 {9, 0b001011000, 0, 15}, {4, 0b1110, 1, 0}, {4, 0b1100, 1, 1}, {5, 0b10101, 1, 2}, {6, 0b100110, 1, 3},
770 {7, 0b1000111, 1, 4}, {8, 0b10000010, 1, 5}, {8, 0b01111010, 1, 6}, {9, 0b011011000, 1, 7},
771 {9, 0b011010001, 1, 8}, {9, 0b011000110, 1, 9}, {10, 0b0101000111, 1, 10}, {10, 0b0101011001, 1, 11},
772 {10, 0b0100111111, 1, 12}, {10, 0b0100101001, 1, 13}, {10, 0b0100010111, 1, 14}, {8, 0b00101010, 1, 15},
773 {6, 0b101111, 2, 0}, {5, 0b10110, 2, 1}, {6, 0b101001, 2, 2}, {7, 0b1001010, 2, 3}, {7, 0b1000100, 2, 4},
774 {8, 0b10000000, 2, 5}, {8, 0b01111000, 2, 6}, {9, 0b011011101, 2, 7}, {9, 0b011001111, 2, 8},
775 {9, 0b011000010, 2, 9}, {9, 0b010110110, 2, 10}, {10, 0b0101010100, 2, 11}, {10, 0b0100111011, 2, 12},
776 {10, 0b0100100111, 2, 13}, {11, 0b01000011101, 2, 14}, {7, 0b0010010, 2, 15}, {7, 0b1010001, 3, 0},
777 {6, 0b100111, 3, 1}, {7, 0b1001011, 3, 2}, {7, 0b1000110, 3, 3}, {8, 0b10000110, 3, 4},
778 {8, 0b01111101, 3, 5}, {8, 0b01110100, 3, 6}, {9, 0b011011100, 3, 7}, {9, 0b011001100, 3, 8},
779 {9, 0b010111110, 3, 9}, {9, 0b010110010, 3, 10}, {10, 0b0101000101, 3, 11}, {10, 0b0100110111, 3, 12},
780 {10, 0b0100100101, 3, 13}, {10, 0b0100001111, 3, 14}, {7, 0b0010000, 3, 15}, {8, 0b10010011, 4, 0},
781 {7, 0b1001000, 4, 1}, {7, 0b1000101, 4, 2}, {8, 0b10000111, 4, 3}, {8, 0b01111111, 4, 4},
782 {8, 0b01110110, 4, 5}, {8, 0b01110000, 4, 6}, {9, 0b011010010, 4, 7}, {9, 0b011001000, 4, 8},
783 {9, 0b010111100, 4, 9}, {10, 0b0101100000, 4, 10}, {10, 0b0101000011, 4, 11}, {10, 0b0100110010, 4, 12},
784 {10, 0b0100011101, 4, 13}, {11, 0b01000011100, 4, 14}, {7, 0b0001110, 4, 15}, {9, 0b100000111, 5, 0},
785 {7, 0b1000010, 5, 1}, {8, 0b10000001, 5, 2}, {8, 0b01111110, 5, 3}, {8, 0b01110111, 5, 4},
786 {8, 0b01110010, 5, 5}, {9, 0b011010110, 5, 6}, {9, 0b011001010, 5, 7}, {9, 0b011000000, 5, 8},
787 {9, 0b010110100, 5, 9}, {10, 0b0101010101, 5, 10}, {10, 0b0100111101, 5, 11}, {10, 0b0100101101, 5, 12},
788 {10, 0b0100011001, 5, 13}, {10, 0b0100000110, 5, 14}, {7, 0b0001100, 5, 15}, {9, 0b011111001, 6, 0},
789 {8, 0b01111011, 6, 1}, {8, 0b01111001, 6, 2}, {8, 0b01110101, 6, 3}, {8, 0b01110001, 6, 4},
790 {9, 0b011010111, 6, 5}, {9, 0b011001110, 6, 6}, {9, 0b011000011, 6, 7}, {9, 0b010111001, 6, 8},
791 {10, 0b0101011011, 6, 9}, {10, 0b0101001010, 6, 10}, {10, 0b0100110100, 6, 11}, {10, 0b0100100011, 6, 12},
792 {10, 0b0100010000, 6, 13}, {11, 0b01000001000, 6, 14}, {7, 0b0001010, 6, 15}, {10, 0b0110110011, 7, 0},
793 {8, 0b01110011, 7, 1}, {8, 0b01101111, 7, 2}, {8, 0b01101101, 7, 3}, {9, 0b011010011, 7, 4},
794 {9, 0b011001011, 7, 5}, {9, 0b011000100, 7, 6}, {9, 0b010111011, 7, 7}, {10, 0b0101100001, 7, 8},
795 {10, 0b0101001100, 7, 9}, {10, 0b0100111001, 7, 10}, {10, 0b0100101010, 7, 11}, {10, 0b0100011011, 7, 12},
796 {11, 0b01000010011, 7, 13}, {11, 0b00101111101, 7, 14}, {8, 0b00010001, 7, 15}, {10, 0b0110101011, 8, 0},
797 {9, 0b011010100, 8, 1}, {9, 0b011010000, 8, 2}, {9, 0b011001101, 8, 3}, {9, 0b011001001, 8, 4},
798 {9, 0b011000001, 8, 5}, {9, 0b010111010, 8, 6}, {9, 0b010110001, 8, 7}, {9, 0b010101001, 8, 8},
799 {10, 0b0101000000, 8, 9}, {10, 0b0100101111, 8, 10}, {10, 0b0100011110, 8, 11}, {10, 0b0100001100, 8, 12},
800 {11, 0b01000000010, 8, 13}, {11, 0b00101111001, 8, 14}, {8, 0b00010000, 8, 15}, {10, 0b0101001111, 9, 0},
801 {9, 0b011000111, 9, 1}, {9, 0b011000101, 9, 2}, {9, 0b010111111, 9, 3}, {9, 0b010111101, 9, 4},
802 {9, 0b010110101, 9, 5}, {9, 0b010101110, 9, 6}, {10, 0b0101001101, 9, 7}, {10, 0b0101000001, 9, 8},
803 {10, 0b0100110001, 9, 9}, {10, 0b0100100001, 9, 10}, {10, 0b0100010011, 9, 11}, {11, 0b01000001001, 9, 12},
804 {11, 0b00101111011, 9, 13}, {11, 0b00101110011, 9, 14}, {8, 0b00001011, 9, 15}, {11, 0b01010011100, 10, 0},
805 {9, 0b010111000, 10, 1}, {9, 0b010110111, 10, 2}, {9, 0b010110011, 10, 3}, {9, 0b010101111, 10, 4},
806 {10, 0b0101011000, 10, 5}, {10, 0b0101001011, 10, 6}, {10, 0b0100111010, 10, 7}, {10, 0b0100110000, 10, 8},
807 {10, 0b0100100010, 10, 9}, {10, 0b0100010101, 10, 10}, {11, 0b01000010010, 10, 11},
808 {11, 0b00101111111, 10, 12}, {11, 0b00101110101, 10, 13}, {11, 0b00101101110, 10, 14},
809 {8, 0b00001010, 10, 15}, {11, 0b01010001100, 11, 0}, {10, 0b0101011010, 11, 1}, {9, 0b010101011, 11, 2},
810 {9, 0b010101000, 11, 3}, {9, 0b010100100, 11, 4}, {10, 0b0100111110, 11, 5}, {10, 0b0100110101, 11, 6},
811 {10, 0b0100101011, 11, 7}, {10, 0b0100011111, 11, 8}, {10, 0b0100010100, 11, 9},
812 {10, 0b0100000111, 11, 10}, {11, 0b01000000001, 11, 11}, {11, 0b00101110111, 11, 12},
813 {11, 0b00101110000, 11, 13}, {11, 0b00101101010, 11, 14}, {8, 0b00000110, 11, 15},
814 {11, 0b01010001000, 12, 0}, {10, 0b0101000010, 12, 1}, {10, 0b0100111100, 12, 2},
815 {10, 0b0100111000, 12, 3}, {10, 0b0100110011, 12, 4}, {10, 0b0100101110, 12, 5}, {10, 0b0100100100, 12, 6},
816 {10, 0b0100011100, 12, 7}, {10, 0b0100001101, 12, 8}, {10, 0b0100000101, 12, 9},
817 {11, 0b01000000000, 12, 10}, {11, 0b00101111000, 12, 11}, {11, 0b00101110010, 12, 12},
818 {11, 0b00101101100, 12, 13}, {11, 0b00101100111, 12, 14}, {8, 0b00000100, 12, 15},
819 {11, 0b01001101100, 13, 0}, {10, 0b0100101100, 13, 1}, {10, 0b0100101000, 13, 2},
820 {10, 0b0100100110, 13, 3}, {10, 0b0100100000, 13, 4}, {10, 0b0100011010, 13, 5}, {10, 0b0100010001, 13, 6},
821 {10, 0b0100001010, 13, 7}, {11, 0b01000000011, 13, 8}, {11, 0b00101111100, 13, 9},
822 {11, 0b00101110110, 13, 10}, {11, 0b00101110001, 13, 11}, {11, 0b00101101101, 13, 12},
823 {11, 0b00101101001, 13, 13}, {11, 0b00101100101, 13, 14}, {8, 0b00000010, 13, 15},
824 {12, 0b010000001001, 14, 0}, {10, 0b0100011000, 14, 1}, {10, 0b0100010110, 14, 2},
825 {10, 0b0100010010, 14, 3}, {10, 0b0100001011, 14, 4}, {10, 0b0100001000, 14, 5}, {10, 0b0100000011, 14, 6},
826 {11, 0b00101111110, 14, 7}, {11, 0b00101111010, 14, 8}, {11, 0b00101110100, 14, 9},
827 {11, 0b00101101111, 14, 10}, {11, 0b00101101011, 14, 11}, {11, 0b00101101000, 14, 12},
828 {11, 0b00101100110, 14, 13}, {11, 0b00101100100, 14, 14}, {8, 0b00000000, 14, 15}, {8, 0b00101011, 15, 0},
829 {7, 0b0010100, 15, 1}, {7, 0b0010011, 15, 2}, {7, 0b0010001, 15, 3}, {7, 0b0001111, 15, 4},
830 {7, 0b0001101, 15, 5}, {7, 0b0001011, 15, 6}, {7, 0b0001001, 15, 7}, {7, 0b0000111, 15, 8},
831 {7, 0b0000110, 15, 9}, {7, 0b0000100, 15, 10}, {8, 0b00000111, 15, 11}, {8, 0b00000101, 15, 12},
832 {8, 0b00000011, 15, 13}, {8, 0b00000001, 15, 14}, {4, 0b0011, 15, 15},
833 };
834
835 // ------------------------------------------------------------------------
836 // Huffman table self-validation (regression guard).
837 //
838 // Every ISO 11172-3 table must be a *complete prefix code*: kraftComplete()
839 // proves the Kraft equality (sum of 2^-len == 1) with exact integer math, so
840 // any transcription error that alters a length or adds/drops an entry breaks
841 // the build. prefixFree() proves no codeword is a prefix of another (catches
842 // same-length value typos and duplicates). Both are constexpr; the static
843 // assertions below run them at compile time over all 15 tables.
844 // ------------------------------------------------------------------------
845 template <std::size_t N>
846 static constexpr bool kraftComplete(const HuffCode (&t)[N]) noexcept
847 {
848 int maxLen = 0;
849 for (std::size_t i = 0; i < N; ++i)
850 if (t[i].len > maxLen) maxLen = t[i].len;
851 const unsigned long long full = 1ull << maxLen;
852 unsigned long long sum = 0;
853 for (std::size_t i = 0; i < N; ++i)
854 sum += full >> t[i].len; // 2^(maxLen-len), exact
855 return sum == full; // == 2^maxLen <=> Kraft sum == 1
856 }
857
858 template <std::size_t N>
859 static constexpr bool prefixFree(const HuffCode (&t)[N]) noexcept
860 {
861 for (std::size_t i = 0; i < N; ++i)
862 for (std::size_t j = 0; j < N; ++j)
863 if (i != j && t[i].len <= t[j].len &&
864 t[i].code == static_cast<uint16_t>(t[j].code >> (t[j].len - t[i].len)))
865 return false; // codeword i is a prefix of codeword j
866 return true;
867 }
868
869 // Compile-time proof of table integrity, evaluated under MSVC only: the
870 // O(n^2) prefix checks over the 256-entry tables exceed the default
871 // constexpr step budgets of GCC (-fconstexpr-ops-limit) and Clang
872 // (-fconstexpr-steps), and a drop-in header cannot demand build flags.
873 // The tables are identical constants on every compiler, so the MSVC
874 // evaluation proves their content universally.
875#if defined(_MSC_VER) && !defined(__clang__)
876 static_assert(kraftComplete(kHuff01) && kraftComplete(kHuff02) && kraftComplete(kHuff03) &&
877 kraftComplete(kHuff05) && kraftComplete(kHuff06) && kraftComplete(kHuff07) &&
878 kraftComplete(kHuff08) && kraftComplete(kHuff09) && kraftComplete(kHuff10) &&
879 kraftComplete(kHuff11) && kraftComplete(kHuff12) && kraftComplete(kHuff13) &&
880 kraftComplete(kHuff15) && kraftComplete(kHuff16) && kraftComplete(kHuff24),
881 "DSPark: an MP3 Huffman table is not a complete prefix code (Kraft != 1).");
882 // One assertion per table: prefixFree() is O(n^2), so a single combined
883 // expression over the four 256-entry tables would exceed MSVC's default
884 // constexpr step budget. Split, each table evaluates well within the limit
885 // (no /constexpr:steps flag required - this stays a drop-in header).
886 static_assert(prefixFree(kHuff01), "kHuff01 not prefix-free.");
887 static_assert(prefixFree(kHuff02), "kHuff02 not prefix-free.");
888 static_assert(prefixFree(kHuff03), "kHuff03 not prefix-free.");
889 static_assert(prefixFree(kHuff05), "kHuff05 not prefix-free.");
890 static_assert(prefixFree(kHuff06), "kHuff06 not prefix-free.");
891 static_assert(prefixFree(kHuff07), "kHuff07 not prefix-free.");
892 static_assert(prefixFree(kHuff08), "kHuff08 not prefix-free.");
893 static_assert(prefixFree(kHuff09), "kHuff09 not prefix-free.");
894 static_assert(prefixFree(kHuff10), "kHuff10 not prefix-free.");
895 static_assert(prefixFree(kHuff11), "kHuff11 not prefix-free.");
896 static_assert(prefixFree(kHuff12), "kHuff12 not prefix-free.");
897 static_assert(prefixFree(kHuff13), "kHuff13 not prefix-free.");
898 static_assert(prefixFree(kHuff15), "kHuff15 not prefix-free.");
899 static_assert(prefixFree(kHuff16), "kHuff16 not prefix-free.");
900 static_assert(prefixFree(kHuff24), "kHuff24 not prefix-free.");
901#endif
902
903 struct Count1Code { uint8_t len; uint8_t code; uint8_t v, w, x, y; };
904
905 // ISO 11172-3 count1 table A (quadruples). Values per ffmpeg mpa_quad_{codes,bits}[0];
906 // verified prefix-free with Kraft sum == 1.
907 static constexpr Count1Code kCount1A[] = {
908 {1, 0b1, 0, 0, 0, 0}, {4, 0b0101, 0, 0, 0, 1}, {4, 0b0100, 0, 0, 1, 0}, {5, 0b00101, 0, 0, 1, 1},
909 {4, 0b0110, 0, 1, 0, 0}, {6, 0b000101, 0, 1, 0, 1}, {5, 0b00100, 0, 1, 1, 0}, {6, 0b000100, 0, 1, 1, 1},
910 {4, 0b0111, 1, 0, 0, 0}, {5, 0b00011, 1, 0, 0, 1}, {5, 0b00110, 1, 0, 1, 0}, {6, 0b000000, 1, 0, 1, 1},
911 {5, 0b00111, 1, 1, 0, 0}, {6, 0b000010, 1, 1, 0, 1}, {6, 0b000011, 1, 1, 1, 0}, {6, 0b000001, 1, 1, 1, 1},
912 };
913
914 static constexpr Count1Code kCount1B[] = {
915 {4, 0b1111, 0, 0, 0, 0}, {4, 0b1110, 0, 0, 0, 1}, {4, 0b1101, 0, 0, 1, 0}, {4, 0b1100, 0, 0, 1, 1},
916 {4, 0b1011, 0, 1, 0, 0}, {4, 0b1010, 0, 1, 0, 1}, {4, 0b1001, 0, 1, 1, 0}, {4, 0b1000, 0, 1, 1, 1},
917 {4, 0b0111, 1, 0, 0, 0}, {4, 0b0110, 1, 0, 0, 1}, {4, 0b0101, 1, 0, 1, 0}, {4, 0b0100, 1, 0, 1, 1},
918 {4, 0b0011, 1, 1, 0, 0}, {4, 0b0010, 1, 1, 0, 1}, {4, 0b0001, 1, 1, 1, 0}, {4, 0b0000, 1, 1, 1, 1},
919 };
920
921 // ========================================================================
922 // Synthesis & IMDCT Tables (ALIGNED FOR SIMD)
923 // ========================================================================
924
925 static constexpr double kSynthWindow[512] = {
926 0.000000000, -0.000015259, -0.000015259, -0.000015259, -0.000015259, -0.000015259, -0.000015259, -0.000030518,
927 -0.000030518, -0.000030518, -0.000030518, -0.000045776, -0.000045776, -0.000061035, -0.000061035, -0.000076294,
928 -0.000076294, -0.000091553, -0.000106812, -0.000106812, -0.000122070, -0.000137329, -0.000152588, -0.000167847,
929 -0.000198364, -0.000213623, -0.000244141, -0.000259399, -0.000289917, -0.000320435, -0.000366211, -0.000396729,
930 -0.000442505, -0.000473022, -0.000534058, -0.000579834, -0.000625610, -0.000686646, -0.000747681, -0.000808716,
931 -0.000885010, -0.000961304, -0.001037598, -0.001113892, -0.001205444, -0.001296997, -0.001388550, -0.001480103,
932 -0.001586914, -0.001693726, -0.001785278, -0.001907349, -0.002014160, -0.002120972, -0.002243042, -0.002349854,
933 -0.002456665, -0.002578735, -0.002685547, -0.002792358, -0.002899170, -0.002990723, -0.003082275, -0.003173828,
934 0.003250122, 0.003326416, 0.003387451, 0.003433228, 0.003463745, 0.003479004, 0.003479004, 0.003463745,
935 0.003417969, 0.003372192, 0.003280640, 0.003173828, 0.003051758, 0.002883911, 0.002700806, 0.002487183,
936 0.002227783, 0.001937866, 0.001617432, 0.001266479, 0.000869751, 0.000442505, -0.000030518, -0.000549316,
937 -0.001098633, -0.001693726, -0.002334595, -0.003005981, -0.003723145, -0.004486084, -0.005294800, -0.006118774,
938 -0.007003784, -0.007919312, -0.008865356, -0.009841919, -0.010848999, -0.011886597, -0.012939453, -0.014022827,
939 -0.015121460, -0.016235352, -0.017349243, -0.018463135, -0.019577026, -0.020690918, -0.021789551, -0.022857666,
940 -0.023910522, -0.024932861, -0.025909424, -0.026840210, -0.027725220, -0.028533936, -0.029281616, -0.029937744,
941 -0.030532837, -0.031005859, -0.031387329, -0.031661987, -0.031814575, -0.031845093, -0.031738281, -0.031478882,
942 0.031082153, 0.030517578, 0.029785156, 0.028884888, 0.027801514, 0.026535034, 0.025085449, 0.023422241,
943 0.021575928, 0.019531250, 0.017257690, 0.014801025, 0.012115479, 0.009231567, 0.006134033, 0.002822876,
944 -0.000686646, -0.004394531, -0.008316040, -0.012420654, -0.016708374, -0.021179199, -0.025817871, -0.030609131,
945 -0.035552979, -0.040634155, -0.045837402, -0.051132202, -0.056533813, -0.061996460, -0.067520142, -0.073059082,
946 -0.078628540, -0.084182739, -0.089706421, -0.095169067, -0.100540161, -0.105819702, -0.110946655, -0.115921021,
947 -0.120697021, -0.125259399, -0.129562378, -0.133590698, -0.137298584, -0.140670776, -0.143676758, -0.146255493,
948 -0.148422241, -0.150115967, -0.151306152, -0.151962280, -0.152069092, -0.151596069, -0.150497437, -0.148773193,
949 -0.146362305, -0.143264771, -0.139450073, -0.134887695, 0.129577637, 0.123474121, 0.116577148, 0.108856201,
950 0.100311279, 0.090927124, 0.080688477, 0.069595337, 0.057617187, 0.044784546, 0.031082153, 0.016510010,
951 0.001068115, -0.015228271, -0.032379150, -0.050354004, -0.069168091, -0.088775635, -0.109161377, -0.130310059,
952 -0.152206421, -0.174789429, -0.198059082, -0.221984863, -0.246505737, -0.271591187, -0.297210693, -0.323318481,
953 -0.349868774, -0.376800537, -0.404083252, -0.431655884, -0.459472656, -0.487472534, -0.515609741, -0.543823242,
954 -0.572036743, -0.600219727, -0.628295898, -0.656219482, -0.683914185, -0.711318970, -0.738372803, -0.765029907,
955 -0.791213989, -0.816864014, -0.841949463, -0.866363525, -0.890090942, -0.913055420, -0.935195923, -0.956481934,
956 -0.976852417, -0.996246338, -1.014617920, -1.031936646, -1.048156738, -1.063217163, -1.077117920, -1.089782715,
957 -1.101211548, -1.111373901, -1.120223999, -1.127746582, -1.133926392, -1.138763428, -1.142211914, -1.144287109,
958 1.144989014, 1.144287109, 1.142211914, 1.138763428, 1.133926392, 1.127746582, 1.120223999, 1.111373901,
959 1.101211548, 1.089782715, 1.077117920, 1.063217163, 1.048156738, 1.031936646, 1.014617920, 0.996246338,
960 0.976852417, 0.956481934, 0.935195923, 0.913055420, 0.890090942, 0.866363525, 0.841949463, 0.816864014,
961 0.791213989, 0.765029907, 0.738372803, 0.711318970, 0.683914185, 0.656219482, 0.628295898, 0.600219727,
962 0.572036743, 0.543823242, 0.515609741, 0.487472534, 0.459472656, 0.431655884, 0.404083252, 0.376800537,
963 0.349868774, 0.323318481, 0.297210693, 0.271591187, 0.246505737, 0.221984863, 0.198059082, 0.174789429,
964 0.152206421, 0.130310059, 0.109161377, 0.088775635, 0.069168091, 0.050354004, 0.032379150, 0.015228271,
965 -0.001068115, -0.016510010, -0.031082153, -0.044784546, -0.057617187, -0.069595337, -0.080688477, -0.090927124,
966 -0.100311279, -0.108856201, -0.116577148, -0.123474121, -0.129577637, -0.134887695, -0.139450073, -0.143264771,
967 -0.146362305, -0.148773193, -0.150497437, -0.151596069, -0.152069092, -0.151962280, -0.151306152, -0.150115967,
968 -0.148422241, -0.146255493, -0.143676758, -0.140670776, -0.137298584, -0.133590698, -0.129562378, -0.125259399,
969 -0.120697021, -0.115921021, -0.110946655, -0.105819702, -0.100540161, -0.095169067, -0.089706421, -0.084182739,
970 -0.078628540, -0.073059082, -0.067520142, -0.061996460, -0.056533813, -0.051132202, -0.045837402, -0.040634155,
971 -0.035552979, -0.030609131, -0.025817871, -0.021179199, -0.016708374, -0.012420654, -0.008316040, -0.004394531,
972 0.000686646, -0.002822876, -0.006134033, -0.009231567, -0.012115479, -0.014801025, -0.017257690, -0.019531250,
973 -0.021575928, -0.023422241, -0.025085449, -0.026535034, -0.027801514, -0.028884888, -0.029785156, -0.030517578,
974 -0.031082153, -0.031478882, -0.031738281, -0.031845093, -0.031814575, -0.031661987, -0.031387329, -0.031005859,
975 -0.030532837, -0.029937744, -0.029281616, -0.028533936, -0.027725220, -0.026840210, -0.025909424, -0.024932861,
976 -0.023910522, -0.022857666, -0.021789551, -0.020690918, -0.019577026, -0.018463135, -0.017349243, -0.016235352,
977 -0.015121460, -0.014022827, -0.012939453, -0.011886597, -0.010848999, -0.009841919, -0.008865356, -0.007919312,
978 -0.007003784, -0.006118774, -0.005294800, -0.004486084, -0.003723145, -0.003005981, -0.002334595, -0.001693726,
979 -0.001098633, -0.000549316, 0.000030518, 0.000442505, 0.000869751, 0.001266479, 0.001617432, 0.001937866,
980 0.002227783, 0.002487183, 0.002700806, 0.002883911, 0.003051758, 0.003173828, 0.003280640, 0.003372192,
981 0.003417969, 0.003463745, 0.003479004, 0.003479004, 0.003463745, 0.003433228, 0.003387451, 0.003326416,
982 0.003250122, 0.003173828, 0.003082275, 0.002990723, 0.002899170, 0.002792358, 0.002685547, 0.002578735,
983 0.002456665, 0.002349854, 0.002243042, 0.002120972, 0.002014160, 0.001907349, 0.001785278, 0.001693726,
984 0.001586914, 0.001480103, 0.001388550, 0.001296997, 0.001205444, 0.001113892, 0.001037598, 0.000961304,
985 0.000885010, 0.000808716, 0.000747681, 0.000686646, 0.000625610, 0.000579834, 0.000534058, 0.000473022,
986 0.000442505, 0.000396729, 0.000366211, 0.000320435, 0.000289917, 0.000259399, 0.000244141, 0.000213623,
987 0.000198364, 0.000167847, 0.000152588, 0.000137329, 0.000122070, 0.000106812, 0.000106812, 0.000091553,
988 0.000076294, 0.000076294, 0.000061035, 0.000061035, 0.000045776, 0.000045776, 0.000030518, 0.000030518,
989 0.000030518, 0.000030518, 0.000015259, 0.000015259, 0.000015259, 0.000015259, 0.000015259, 0.000015259,
990 };
991
992 static constexpr double kNormalWindow[36] = {
993 0.043619387, 0.130526192, 0.216439614, 0.300705800, 0.382683432, 0.461748613,
994 0.537299608, 0.608761429, 0.675590208, 0.737277337, 0.793353340, 0.843391446,
995 0.887010833, 0.923879533, 0.953716951, 0.976296007, 0.991444861, 0.999048222,
996 0.999048222, 0.991444861, 0.976296007, 0.953716951, 0.923879533, 0.887010833,
997 0.843391446, 0.793353340, 0.737277337, 0.675590208, 0.608761429, 0.537299608,
998 0.461748613, 0.382683432, 0.300705800, 0.216439614, 0.130526192, 0.043619387
999 };
1000
1001 static constexpr double kStartWindow[36] = {
1002 0.043619387, 0.130526192, 0.216439614, 0.300705800, 0.382683432, 0.461748613,
1003 0.537299608, 0.608761429, 0.675590208, 0.737277337, 0.793353340, 0.843391446,
1004 0.887010833, 0.923879533, 0.953716951, 0.976296007, 0.991444861, 0.999048222,
1005 1.000000000, 1.000000000, 1.000000000, 1.000000000, 1.000000000, 1.000000000,
1006 0.991444861, 0.923879533, 0.793353340, 0.608761429, 0.382683432, 0.130526192,
1007 0.000000000, 0.000000000, 0.000000000, 0.000000000, 0.000000000, 0.000000000
1008 };
1009
1010 static constexpr double kStopWindow[36] = {
1011 0.000000000, 0.000000000, 0.000000000, 0.000000000, 0.000000000, 0.000000000,
1012 0.130526192, 0.382683432, 0.608761429, 0.793353340, 0.923879533, 0.991444861,
1013 1.000000000, 1.000000000, 1.000000000, 1.000000000, 1.000000000, 1.000000000,
1014 0.999048222, 0.991444861, 0.976296007, 0.953716951, 0.923879533, 0.887010833,
1015 0.843391446, 0.793353340, 0.737277337, 0.675590208, 0.608761429, 0.537299608,
1016 0.461748613, 0.382683432, 0.300705800, 0.216439614, 0.130526192, 0.043619387
1017 };
1018
1019 static constexpr double kShortWindow[12] = {
1020 0.130526192, 0.382683432, 0.608761429, 0.793353340, 0.923879533, 0.991444861,
1021 0.991444861, 0.923879533, 0.793353340, 0.608761429, 0.382683432, 0.130526192
1022 };
1023
1024 struct AliasCoeffs { double cs[8]; double ca[8]; };
1025
1026 static AliasCoeffs getAliasCoeffs()
1027 {
1028 static constexpr double ci[8] = {-0.6, -0.535, -0.33, -0.185, -0.095, -0.041, -0.0142, -0.0037};
1029 AliasCoeffs c {};
1030 for (int i = 0; i < 8; ++i) {
1031 c.cs[i] = 1.0 / std::sqrt(1.0 + ci[i] * ci[i]);
1032 c.ca[i] = ci[i] / std::sqrt(1.0 + ci[i] * ci[i]);
1033 }
1034 return c;
1035 }
1036
1037 // ========================================================================
1038 // Decoder state (per-channel)
1039 // ========================================================================
1040
1041 struct ChannelState
1042 {
1043 double prevBlock[576] = {};
1044 double synthBuf[1024] = {};
1045 int synthOffset = 0;
1046 };
1047
1048 std::vector<uint8_t> fileData_;
1049 size_t filePos_ = 0;
1050 AudioFileInfo info_ {};
1051 bool isOpen_ = false;
1052
1053 std::vector<size_t> frameOffsets_;
1054 std::vector<float> decodedSamplesFlat_; // Planar contiguous buffer [channel][sample]
1055
1056 std::vector<uint8_t> reservoir_;
1057 size_t reservoirSize_ = 0;
1058 ChannelState channelState_[kChannelsMax] = {};
1059
1060 // ========================================================================
1061 // Encoder state
1062 // ========================================================================
1063
1064 struct EncChannelState
1065 {
1066 double analysisBuf[512] = {};
1067 double mdctOverlap[32][18] = {};
1068 };
1069
1070 std::ofstream outFile_;
1071 bool isWriting_ = false;
1072 int encBitrate_ = 128;
1073 int encPaddingAccum_ = 0;
1074 EncChannelState encState_[kChannelsMax] = {};
1075 double encInput_[kChannelsMax][kSamplesPerFrame] = {};
1076 int encInputPos_ = 0;
1077 std::vector<uint8_t> encFrameBuf_;
1078
1079 // ========================================================================
1080 // Implementation Methods
1081 // ========================================================================
1082
1083 void skipID3v2()
1084 {
1085 if (filePos_ + 10 > fileData_.size()) return;
1086 if (fileData_[filePos_] == 'I' &&
1087 fileData_[filePos_ + 1] == 'D' &&
1088 fileData_[filePos_ + 2] == '3')
1089 {
1090 uint32_t size = (static_cast<uint32_t>(fileData_[filePos_ + 6]) << 21)
1091 | (static_cast<uint32_t>(fileData_[filePos_ + 7]) << 14)
1092 | (static_cast<uint32_t>(fileData_[filePos_ + 8]) << 7)
1093 | static_cast<uint32_t>(fileData_[filePos_ + 9]);
1094 filePos_ += 10 + size;
1095 }
1096 }
1097
1098 bool scanFrames()
1099 {
1100 frameOffsets_.clear();
1101 size_t pos = filePos_;
1102 int sampleRate = 0;
1103 int channels = 0;
1104
1105 while (pos + 4 <= fileData_.size())
1106 {
1107 if ((fileData_[pos] & 0xFF) != 0xFF || (fileData_[pos + 1] & 0xE0) != 0xE0)
1108 {
1109 ++pos; continue;
1110 }
1111
1112 FrameHeader hdr {};
1113 if (!parseFrameHeader(pos, hdr)) { ++pos; continue; }
1114 if (hdr.version != 3 || hdr.layer != 1) { ++pos; continue; }
1115
1116 if (frameOffsets_.empty())
1117 {
1118 sampleRate = hdr.sampleRate;
1119 channels = hdr.channels;
1120 }
1121
1122 frameOffsets_.push_back(pos);
1123 pos += static_cast<size_t>(hdr.frameSize);
1124 }
1125
1126 if (frameOffsets_.empty()) return false;
1127
1128 info_.sampleRate = static_cast<double>(sampleRate);
1129 info_.numChannels = channels;
1130 info_.numSamples = static_cast<int64_t>(frameOffsets_.size()) * kSamplesPerFrame;
1131 // MP3 has no PCM bit depth; report the delivery format (32-bit float).
1132 info_.bitsPerSample = 32;
1133 info_.isFloatingPoint = true;
1134 return true;
1135 }
1136
1137 bool parseFrameHeader(size_t pos, FrameHeader& hdr) const
1138 {
1139 if (pos + 4 > fileData_.size()) return false;
1140 uint32_t header = (static_cast<uint32_t>(fileData_[pos]) << 24)
1141 | (static_cast<uint32_t>(fileData_[pos + 1]) << 16)
1142 | (static_cast<uint32_t>(fileData_[pos + 2]) << 8)
1143 | static_cast<uint32_t>(fileData_[pos + 3]);
1144
1145 if ((header & 0xFFE00000u) != 0xFFE00000u) return false;
1146
1147 hdr.version = static_cast<int>((header >> 19) & 3);
1148 hdr.layer = static_cast<int>((header >> 17) & 3);
1149 hdr.crcProtect = !((header >> 16) & 1);
1150 hdr.bitrateIdx = static_cast<int>((header >> 12) & 0xF);
1151 hdr.srateIdx = static_cast<int>((header >> 10) & 3);
1152 hdr.padding = ((header >> 9) & 1) != 0;
1153 hdr.channelMode = static_cast<int>((header >> 6) & 3);
1154 hdr.modeExt = static_cast<int>((header >> 4) & 3);
1155 hdr.copyright = ((header >> 3) & 1) != 0;
1156 hdr.original = ((header >> 2) & 1) != 0;
1157 hdr.emphasis = static_cast<int>(header & 3);
1158
1159 if (hdr.version != 3 || hdr.layer != 1) return false;
1160 if (hdr.bitrateIdx == 0 || hdr.bitrateIdx == 15) return false;
1161 if (hdr.srateIdx >= 3) return false;
1162
1163 hdr.bitrate = kBitrateTable[hdr.bitrateIdx] * 1000;
1164 hdr.sampleRate = kSampleRateTable[hdr.srateIdx];
1165 hdr.channels = (hdr.channelMode == 3) ? 1 : 2;
1166 hdr.sideInfoSize = (hdr.channels == 1) ? 17 : 32;
1167 hdr.frameSize = (144 * hdr.bitrate) / hdr.sampleRate + (hdr.padding ? 1 : 0);
1168
1169 if (hdr.frameSize < 4 + (hdr.crcProtect ? 2 : 0) + hdr.sideInfoSize) return false;
1170 return true;
1171 }
1172
1173 bool parseSideInfo(BitReader& br, const FrameHeader& hdr, SideInfo& si) const
1174 {
1175 int nch = hdr.channels;
1176 si.main_data_begin = static_cast<int>(br.readBits(9));
1177 br.readBits((nch == 1) ? 5 : 3);
1178
1179 for (int ch = 0; ch < nch; ++ch) si.scfsi[ch] = static_cast<int>(br.readBits(4));
1180
1181 for (int gr = 0; gr < kGranules; ++gr)
1182 {
1183 for (int ch = 0; ch < nch; ++ch)
1184 {
1185 auto& g = si.gr[gr][ch];
1186 g.part2_3_length = static_cast<int>(br.readBits(12));
1187 g.big_values = static_cast<int>(br.readBits(9));
1188 g.global_gain = static_cast<int>(br.readBits(8));
1189 g.scalefac_compress = static_cast<int>(br.readBits(4));
1190 g.window_switching = br.readBits(1) != 0;
1191
1192 if (g.window_switching)
1193 {
1194 g.block_type = static_cast<int>(br.readBits(2));
1195 g.mixed_block = static_cast<int>(br.readBits(1));
1196 g.table_select[0] = static_cast<int>(br.readBits(5));
1197 g.table_select[1] = static_cast<int>(br.readBits(5));
1198 g.table_select[2] = 0;
1199 g.subblock_gain[0] = static_cast<int>(br.readBits(3));
1200 g.subblock_gain[1] = static_cast<int>(br.readBits(3));
1201 g.subblock_gain[2] = static_cast<int>(br.readBits(3));
1202
1203 g.region0_count = (g.block_type == 2 && g.mixed_block == 0) ? 8 : 7;
1204 g.region1_count = 20 - g.region0_count;
1205 }
1206 else
1207 {
1208 g.block_type = 0;
1209 g.mixed_block = 0;
1210 g.table_select[0] = static_cast<int>(br.readBits(5));
1211 g.table_select[1] = static_cast<int>(br.readBits(5));
1212 g.table_select[2] = static_cast<int>(br.readBits(5));
1213 g.subblock_gain[0] = 0;
1214 g.subblock_gain[1] = 0;
1215 g.subblock_gain[2] = 0;
1216 g.region0_count = static_cast<int>(br.readBits(4));
1217 g.region1_count = static_cast<int>(br.readBits(3));
1218 }
1219
1220 g.preflag = static_cast<int>(br.readBits(1));
1221 g.scalefac_scale = static_cast<int>(br.readBits(1));
1222 g.count1table_select = static_cast<int>(br.readBits(1));
1223 }
1224 }
1225 return true;
1226 }
1227
1228 bool decodePair(BitReader& br, int tableIdx, int& x, int& y) const
1229 {
1230 if (tableIdx == 0 || tableIdx == 4 || tableIdx == 14) { x = 0; y = 0; return true; }
1231 int linbits = kHuffLinbits[tableIdx];
1232 const HuffCode* codes = nullptr;
1233 int codeCount = 0;
1234
1235 switch (tableIdx)
1236 {
1237 case 1: codes = kHuff01; codeCount = sizeof(kHuff01)/sizeof(HuffCode); break;
1238 case 2: codes = kHuff02; codeCount = sizeof(kHuff02)/sizeof(HuffCode); break;
1239 case 3: codes = kHuff03; codeCount = sizeof(kHuff03)/sizeof(HuffCode); break;
1240 case 5: codes = kHuff05; codeCount = sizeof(kHuff05)/sizeof(HuffCode); break;
1241 case 6: codes = kHuff06; codeCount = sizeof(kHuff06)/sizeof(HuffCode); break;
1242 case 7: codes = kHuff07; codeCount = sizeof(kHuff07)/sizeof(HuffCode); break;
1243 case 8: codes = kHuff08; codeCount = sizeof(kHuff08)/sizeof(HuffCode); break;
1244 case 9: codes = kHuff09; codeCount = sizeof(kHuff09)/sizeof(HuffCode); break;
1245 case 10: codes = kHuff10; codeCount = sizeof(kHuff10)/sizeof(HuffCode); break;
1246 case 11: codes = kHuff11; codeCount = sizeof(kHuff11)/sizeof(HuffCode); break;
1247 case 12: codes = kHuff12; codeCount = sizeof(kHuff12)/sizeof(HuffCode); break;
1248 case 13: codes = kHuff13; codeCount = sizeof(kHuff13)/sizeof(HuffCode); break;
1249 case 15: codes = kHuff15; codeCount = sizeof(kHuff15)/sizeof(HuffCode); break;
1250 case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23:
1251 codes = kHuff16; codeCount = sizeof(kHuff16)/sizeof(HuffCode); break;
1252 case 24: case 25: case 26: case 27: case 28: case 29: case 30: case 31:
1253 codes = kHuff24; codeCount = sizeof(kHuff24)/sizeof(HuffCode); break;
1254 default: x = 0; y = 0; return true;
1255 }
1256
1257 if (!decodeHuffSymbol(br, codes, codeCount, x, y)) return false;
1258
1259 if (linbits > 0)
1260 {
1261 if (x == 15) x += static_cast<int>(br.readBits(linbits));
1262 if (y == 15) y += static_cast<int>(br.readBits(linbits));
1263 }
1264
1265 if (x != 0 && br.readBit()) x = -x;
1266 if (y != 0 && br.readBit()) y = -y;
1267
1268 return true;
1269 }
1270
1271 bool decodeHuffSymbol(BitReader& br, const HuffCode* codes, int count, int& xOut, int& yOut) const
1272 {
1273 uint32_t acc = 0;
1274 int maxLen = 0;
1275 for (int i = 0; i < count; ++i) if (codes[i].len > maxLen) maxLen = codes[i].len;
1276 size_t startPos = br.getPos();
1277
1278 for (int len = 1; len <= maxLen; ++len)
1279 {
1280 acc = (acc << 1) | static_cast<uint32_t>(br.readBit());
1281 for (int i = 0; i < count; ++i)
1282 {
1283 if (codes[i].len == len && codes[i].code == acc)
1284 {
1285 xOut = codes[i].x; yOut = codes[i].y;
1286 return true;
1287 }
1288 }
1289 }
1290 br.setPos(startPos);
1291 xOut = 0; yOut = 0;
1292 return false;
1293 }
1294
1295 bool decodeCount1(BitReader& br, int tableSelect, int& v, int& w, int& x, int& y) const
1296 {
1297 const Count1Code* codes = (tableSelect == 0) ? kCount1A : kCount1B;
1298 int count = 16;
1299 uint32_t acc = 0;
1300 int maxLen = (tableSelect == 0) ? 6 : 4;
1301
1302 for (int len = 1; len <= maxLen; ++len)
1303 {
1304 acc = (acc << 1) | static_cast<uint32_t>(br.readBit());
1305 for (int i = 0; i < count; ++i)
1306 {
1307 if (codes[i].len == len && codes[i].code == acc)
1308 {
1309 v = codes[i].v; w = codes[i].w; x = codes[i].x; y = codes[i].y;
1310 if (v && br.readBit()) v = -1;
1311 if (w && br.readBit()) w = -1;
1312 if (x && br.readBit()) x = -1;
1313 if (y && br.readBit()) y = -1;
1314 return true;
1315 }
1316 }
1317 }
1318 v = w = x = y = 0;
1319 return false;
1320 }
1321
1322 // part2_3_end is the ABSOLUTE bit position where this granule-channel's
1323 // main data ends: part2_3_length counts scalefactor bits AND Huffman bits
1324 // (ISO 11172-3, 2.4.1.7), so the caller anchors it BEFORE the
1325 // scalefactors. Budgeting it after them (as this decoder once did)
1326 // over-reads by the scalefactor bit count and decodes the next granule's
1327 // bits as spurious count1 quads.
1328 void huffmanDecode(BitReader& br, const GranuleChannel& gc, const FrameHeader& hdr,
1329 int is[576], size_t part2_3_end) const
1330 {
1331 std::memset(is, 0, 576 * sizeof(int));
1332 BandTable bands = getBandTable(hdr.sampleRate);
1333
1334 int region1Start, region2Start;
1335 if (gc.window_switching && gc.block_type == 2)
1336 {
1337 region1Start = 36;
1338 region2Start = kSamplesPerGranule;
1339 }
1340 else
1341 {
1342 int r0 = std::min(gc.region0_count + 1, bands.longCount);
1343 int r1 = std::min(gc.region0_count + 1 + gc.region1_count + 1, bands.longCount);
1344 region1Start = bands.longBands[r0];
1345 region2Start = bands.longBands[r1];
1346 }
1347
1348 int bigValuesEnd = std::min(gc.big_values * 2, 576);
1349
1350 int idx = 0;
1351 for (; idx < bigValuesEnd && br.getPos() < part2_3_end; idx += 2)
1352 {
1353 int tableIdx = (idx < region1Start) ? gc.table_select[0] :
1354 (idx < region2Start) ? gc.table_select[1] : gc.table_select[2];
1355 int x = 0, y = 0;
1356 // Cannot fail with the complete (Kraft-verified) tables below;
1357 // kept as a formal guard against running out of buffered bits.
1358 if (!decodePair(br, tableIdx, x, y)) break;
1359 if (idx < 576) is[idx] = x;
1360 if (idx + 1 < 576) is[idx + 1] = y;
1361 }
1362
1363 while (idx + 3 < 576 && br.getPos() < part2_3_end)
1364 {
1365 int v = 0, w = 0, x = 0, y = 0;
1366 if (!decodeCount1(br, gc.count1table_select, v, w, x, y)) break;
1367 if (br.getPos() > part2_3_end + 2) break;
1368
1369 is[idx] = v; is[idx + 1] = w; is[idx + 2] = x; is[idx + 3] = y;
1370 idx += 4;
1371 }
1372 br.setPos(part2_3_end);
1373 }
1374
1375 void decodeScalefactors(BitReader& br, const GranuleChannel& gc, int gr, int /*ch*/,
1376 int scfsi, int scalefac[39], size_t& bitsRead) const
1377 {
1378 std::memset(scalefac, 0, 39 * sizeof(int));
1379 int slen1 = kSlen1[gc.scalefac_compress];
1380 int slen2 = kSlen2[gc.scalefac_compress];
1381 size_t startBits = br.getPos();
1382
1383 if (gc.window_switching && gc.block_type == 2)
1384 {
1385 if (gc.mixed_block)
1386 {
1387 for (int sfb = 0; sfb < 8; ++sfb) scalefac[sfb] = static_cast<int>(br.readBits(slen1));
1388 for (int sfb = 3; sfb < 6; ++sfb)
1389 for (int win = 0; win < 3; ++win)
1390 scalefac[sfb * 3 + win - 1] = static_cast<int>(br.readBits(slen1));
1391 for (int sfb = 6; sfb < 12; ++sfb)
1392 for (int win = 0; win < 3; ++win)
1393 scalefac[sfb * 3 + win - 1] = static_cast<int>(br.readBits(slen2));
1394 }
1395 else
1396 {
1397 for (int sfb = 0; sfb < 6; ++sfb)
1398 for (int win = 0; win < 3; ++win)
1399 scalefac[sfb * 3 + win] = static_cast<int>(br.readBits(slen1));
1400 for (int sfb = 6; sfb < 12; ++sfb)
1401 for (int win = 0; win < 3; ++win)
1402 scalefac[sfb * 3 + win] = static_cast<int>(br.readBits(slen2));
1403 }
1404 }
1405 else
1406 {
1407 static constexpr int bandStart[4] = {0, 6, 11, 16};
1408 static constexpr int bandEnd[4] = {6, 11, 16, 21};
1409 static constexpr int lens[4] = {0, 0, 1, 1};
1410
1411 for (int group = 0; group < 4; ++group)
1412 {
1413 int slen = (lens[group] == 0) ? slen1 : slen2;
1414 if (!(gr == 1 && (scfsi & (8 >> group))))
1415 {
1416 for (int sfb = bandStart[group]; sfb < bandEnd[group]; ++sfb)
1417 scalefac[sfb] = static_cast<int>(br.readBits(slen));
1418 }
1419 }
1420 }
1421 bitsRead = br.getPos() - startBits;
1422 }
1423
1424 void requantize(const int is[576], const int scalefac[39], const GranuleChannel& gc,
1425 const FrameHeader& hdr, double xr[576]) const
1426 {
1427 // BUGFIX: Increased size to 8208. Max legal value in table 23 is 8206.
1428 // 8192 previously caused out-of-bounds reads on peaks.
1429 static const std::array<double, 8208> kPow43 = [] {
1430 std::array<double, 8208> t{};
1431 for (int i = 0; i < 8208; ++i)
1432 t[i] = std::pow(static_cast<double>(i), 4.0 / 3.0);
1433 return t;
1434 }();
1435
1436 auto pow43 = [](int v) -> double {
1437 int a = (v < 0) ? -v : v;
1438 if (a >= 8208) a = 8207;
1439 return (v < 0) ? -kPow43[a] : kPow43[a];
1440 };
1441
1442 BandTable bands = getBandTable(hdr.sampleRate);
1443 double globalGainFactor = std::exp2((static_cast<double>(gc.global_gain) - 210.0) / 4.0);
1444 double scalefacMult = (gc.scalefac_scale) ? 1.0 : 0.5;
1445
1446 if (gc.window_switching && gc.block_type == 2)
1447 {
1448 if (gc.mixed_block)
1449 {
1450 int longEnd = bands.longBands[8];
1451 for (int sfb = 0; sfb < 8; ++sfb)
1452 {
1453 int start = bands.longBands[sfb];
1454 int end = bands.longBands[sfb + 1];
1455 double sfPow = std::exp2(-scalefacMult * (scalefac[sfb] + gc.preflag * kPretab[sfb]));
1456 double mult = globalGainFactor * sfPow;
1457 for (int i = start; i < end && i < 576; ++i) xr[i] = mult * pow43(is[i]);
1458 }
1459
1460 for (int sfb = 3; sfb < bands.shortCount; ++sfb)
1461 {
1462 int width = bands.shortBands[sfb + 1] - bands.shortBands[sfb];
1463 for (int win = 0; win < 3; ++win)
1464 {
1465 double sbGain = std::exp2(-2.0 * gc.subblock_gain[win]);
1466 int sfIdx = std::max(0, sfb * 3 + win - 1);
1467 double sfPow = std::exp2(-scalefacMult * scalefac[sfIdx]);
1468 double mult = globalGainFactor * sbGain * sfPow;
1469
1470 for (int k = 0; k < width; ++k)
1471 {
1472 int i = longEnd + (sfb - 3) * 3 * width + win * width + k;
1473 if (i >= 576) break;
1474 xr[i] = mult * pow43(is[i]);
1475 }
1476 }
1477 }
1478 }
1479 else
1480 {
1481 for (int sfb = 0; sfb < bands.shortCount; ++sfb)
1482 {
1483 int width = bands.shortBands[sfb + 1] - bands.shortBands[sfb];
1484 for (int win = 0; win < 3; ++win)
1485 {
1486 double sbGain = std::exp2(-2.0 * gc.subblock_gain[win]);
1487 double sfPow = std::exp2(-scalefacMult * scalefac[sfb * 3 + win]);
1488 double mult = globalGainFactor * sbGain * sfPow;
1489
1490 for (int k = 0; k < width; ++k)
1491 {
1492 int i = sfb * width * 3 + win * width + k;
1493 if (i >= 576) break;
1494 xr[i] = mult * pow43(is[i]);
1495 }
1496 }
1497 }
1498 }
1499 }
1500 else
1501 {
1502 for (int sfb = 0; sfb < bands.longCount; ++sfb)
1503 {
1504 int start = bands.longBands[sfb];
1505 int end = bands.longBands[sfb + 1];
1506 double sfPow = std::exp2(-scalefacMult * (scalefac[sfb] + gc.preflag * kPretab[sfb]));
1507 double mult = globalGainFactor * sfPow;
1508 for (int i = start; i < end && i < 576; ++i) xr[i] = mult * pow43(is[i]);
1509 }
1510 }
1511 }
1512
1513 void stereoProcess(double xr[2][576], const GranuleChannel gc[2], const FrameHeader& hdr, const int scalefac[2][39]) const
1514 {
1515 if (hdr.channels < 2) return;
1516 bool msStereo = (hdr.channelMode == 1) && ((hdr.modeExt & 2) != 0);
1517 bool iStereo = (hdr.channelMode == 1) && ((hdr.modeExt & 1) != 0);
1518
1519 if (msStereo)
1520 {
1521 static constexpr double kInvSqrt2 = 0.7071067811865476;
1522 int isEnd = 576;
1523 if (iStereo)
1524 {
1525 isEnd = 0;
1526 for (int i = 575; i >= 0; --i)
1527 if (xr[1][i] != 0.0) { isEnd = i + 1; break; }
1528 }
1529 for (int i = 0; i < isEnd; ++i)
1530 {
1531 double m = xr[0][i], s = xr[1][i];
1532 xr[0][i] = (m + s) * kInvSqrt2;
1533 xr[1][i] = (m - s) * kInvSqrt2;
1534 }
1535 }
1536
1537 if (iStereo)
1538 {
1539 BandTable bands = getBandTable(hdr.sampleRate);
1540 static constexpr double kISRatio[7] = { 0.0, 0.267949192, 0.577350269, 1.0, 1.732050808, 3.732050808, 1e10 };
1541
1542 if (gc[1].window_switching && gc[1].block_type == 2)
1543 {
1544 for (int sfb = 0; sfb < bands.shortCount; ++sfb)
1545 {
1546 int width = bands.shortBands[sfb + 1] - bands.shortBands[sfb];
1547 for (int win = 0; win < 3; ++win)
1548 {
1549 int sfIdx = sfb * 3 + win;
1550 if (sfIdx >= 36) break;
1551 int sf = scalefac[1][sfIdx];
1552 if (sf >= 7) continue;
1553
1554 bool allZero = true;
1555 int baseIdx = sfb * width * 3 + win * width;
1556 for (int k = 0; k < width; ++k)
1557 if (baseIdx + k < 576 && xr[1][baseIdx + k] != 0.0) { allZero = false; break; }
1558
1559 if (allZero)
1560 {
1561 double ratio = kISRatio[sf];
1562 double kl = ratio / (1.0 + ratio);
1563 double kr = 1.0 / (1.0 + ratio);
1564 for (int k = 0; k < width; ++k)
1565 {
1566 int i = baseIdx + k;
1567 if (i >= 576) break;
1568 xr[1][i] = xr[0][i] * kr;
1569 xr[0][i] = xr[0][i] * kl;
1570 }
1571 }
1572 }
1573 }
1574 }
1575 else
1576 {
1577 for (int sfb = 0; sfb < bands.longCount; ++sfb)
1578 {
1579 int start = bands.longBands[sfb];
1580 int end = bands.longBands[sfb + 1];
1581 int sf = scalefac[1][sfb];
1582 if (sf >= 7) continue;
1583
1584 bool allZero = true;
1585 for (int i = start; i < end; ++i)
1586 if (xr[1][i] != 0.0) { allZero = false; break; }
1587
1588 if (allZero)
1589 {
1590 double ratio = kISRatio[sf];
1591 double kl = ratio / (1.0 + ratio);
1592 double kr = 1.0 / (1.0 + ratio);
1593 for (int i = start; i < end; ++i)
1594 {
1595 xr[1][i] = xr[0][i] * kr;
1596 xr[0][i] = xr[0][i] * kl;
1597 }
1598 }
1599 }
1600 }
1601 }
1602 }
1603
1604 void reorder(double xr[576], const GranuleChannel& gc, const FrameHeader& hdr) const
1605 {
1606 if (!gc.window_switching || gc.block_type != 2) return;
1607 BandTable bands = getBandTable(hdr.sampleRate);
1608 double tmp[576] = {};
1609
1610 int startBand = gc.mixed_block ? 3 : 0;
1611 int startIdx = gc.mixed_block ? bands.longBands[8] : 0;
1612
1613 if (gc.mixed_block)
1614 for (int i = 0; i < startIdx; ++i) tmp[i] = xr[i];
1615
1616 for (int sfb = startBand; sfb < bands.shortCount; ++sfb)
1617 {
1618 int width = bands.shortBands[sfb + 1] - bands.shortBands[sfb];
1619 for (int win = 0; win < 3; ++win)
1620 {
1621 for (int k = 0; k < width; ++k)
1622 {
1623 int srcIdx = startIdx + (sfb - startBand) * width * 3 + win * width + k;
1624 int dstIdx = startIdx + (sfb - startBand) * width * 3 + k * 3 + win;
1625 if (srcIdx < 576 && dstIdx < 576) tmp[dstIdx] = xr[srcIdx];
1626 }
1627 }
1628 }
1629 std::memcpy(xr, tmp, sizeof(tmp));
1630 }
1631
1632 void aliasReduction(double xr[576], const GranuleChannel& gc) const
1633 {
1634 if (gc.window_switching && gc.block_type == 2 && !gc.mixed_block) return;
1635 static const AliasCoeffs ac = getAliasCoeffs();
1636 int sbLimit = gc.window_switching ? 1 : 31;
1637
1638 for (int sb = 0; sb < sbLimit; ++sb)
1639 {
1640 for (int i = 0; i < 8; ++i)
1641 {
1642 int idx1 = (sb + 1) * 18 - 1 - i;
1643 int idx2 = (sb + 1) * 18 + i;
1644 if (idx1 < 0 || idx2 >= 576) break;
1645
1646 double a = xr[idx1];
1647 double b = xr[idx2];
1648 xr[idx1] = a * ac.cs[i] - b * ac.ca[i];
1649 xr[idx2] = b * ac.cs[i] + a * ac.ca[i];
1650 }
1651 }
1652 }
1653
1654 void imdct(const double xr[576], const GranuleChannel& gc, int ch, double output[576])
1655 {
1656 ChannelState& state = channelState_[ch];
1657
1658 if (gc.window_switching && gc.block_type == 2)
1659 {
1660 if (gc.mixed_block)
1661 {
1662 for (int sb = 0; sb < 2; ++sb)
1663 {
1664 double in[18], out36[36];
1665 for (int i = 0; i < 18; ++i) in[i] = xr[sb * 18 + i];
1666 imdct36(in, out36);
1667 applyWindow(out36, 0);
1668 for (int i = 0; i < 18; ++i)
1669 {
1670 output[sb * 18 + i] = out36[i] + state.prevBlock[sb * 18 + i];
1671 state.prevBlock[sb * 18 + i] = out36[i + 18];
1672 }
1673 }
1674 for (int sb = 2; sb < 32; ++sb)
1675 {
1676 double tmp[36] = {};
1677 for (int win = 0; win < 3; ++win)
1678 {
1679 double in[6], out12[12];
1680 for (int i = 0; i < 6; ++i) in[i] = xr[sb * 18 + win * 6 + i];
1681 imdct12(in, out12);
1682 for (int i = 0; i < 12; ++i) tmp[6 * win + i] += out12[i] * kShortWindow[i];
1683 }
1684 for (int i = 0; i < 18; ++i)
1685 {
1686 output[sb * 18 + i] = tmp[i] + state.prevBlock[sb * 18 + i];
1687 state.prevBlock[sb * 18 + i] = tmp[i + 18];
1688 }
1689 }
1690 }
1691 else
1692 {
1693 for (int sb = 0; sb < 32; ++sb)
1694 {
1695 double tmp[36] = {};
1696 for (int win = 0; win < 3; ++win)
1697 {
1698 double in[6], out12[12];
1699 for (int i = 0; i < 6; ++i) in[i] = xr[sb * 18 + win * 6 + i];
1700 imdct12(in, out12);
1701 for (int i = 0; i < 12; ++i) tmp[6 * win + i] += out12[i] * kShortWindow[i];
1702 }
1703 for (int i = 0; i < 18; ++i)
1704 {
1705 output[sb * 18 + i] = tmp[i] + state.prevBlock[sb * 18 + i];
1706 state.prevBlock[sb * 18 + i] = tmp[i + 18];
1707 }
1708 }
1709 }
1710 }
1711 else
1712 {
1713 int windowType = gc.block_type;
1714 for (int sb = 0; sb < 32; ++sb)
1715 {
1716 double in[18], out36[36];
1717 for (int i = 0; i < 18; ++i) in[i] = xr[sb * 18 + i];
1718 imdct36(in, out36);
1719 applyWindow(out36, windowType);
1720 for (int i = 0; i < 18; ++i)
1721 {
1722 output[sb * 18 + i] = out36[i] + state.prevBlock[sb * 18 + i];
1723 state.prevBlock[sb * 18 + i] = out36[i + 18];
1724 }
1725 }
1726 }
1727 }
1728
1729 static void imdct36(const double in[18], double out[36])
1730 {
1731 static const auto kCos = [] {
1732 std::array<std::array<double, 18>, 36> t{};
1733 constexpr double kPi = 3.14159265358979323846;
1734 for (int k = 0; k < 36; ++k)
1735 for (int n = 0; n < 18; ++n)
1736 t[k][n] = std::cos(kPi / 72.0 * (2.0 * k + 19.0) * (2.0 * n + 1.0));
1737 return t;
1738 }();
1739
1740 for (int k = 0; k < 36; ++k)
1741 {
1742 double sum = 0.0;
1743 for (int n = 0; n < 18; ++n) sum += in[n] * kCos[k][n];
1744 out[k] = sum;
1745 }
1746 }
1747
1748 static void imdct12(const double in[6], double out[12])
1749 {
1750 static const auto kCos = [] {
1751 std::array<std::array<double, 6>, 12> t{};
1752 constexpr double kPi = 3.14159265358979323846;
1753 for (int k = 0; k < 12; ++k)
1754 for (int n = 0; n < 6; ++n)
1755 t[k][n] = std::cos(kPi / 24.0 * (2.0 * k + 7.0) * (2.0 * n + 1.0));
1756 return t;
1757 }();
1758
1759 for (int k = 0; k < 12; ++k)
1760 {
1761 double sum = 0.0;
1762 for (int n = 0; n < 6; ++n) sum += in[n] * kCos[k][n];
1763 out[k] = sum;
1764 }
1765 }
1766
1767 static void applyWindow(double out[36], int blockType)
1768 {
1769 const double* win = (blockType == 1) ? kStartWindow : (blockType == 3) ? kStopWindow : kNormalWindow;
1770 for (int i = 0; i < 36; ++i) out[i] *= win[i];
1771 }
1772
1773 static void frequencyInversion(double output[576])
1774 {
1775 for (int sb = 1; sb < 32; sb += 2)
1776 for (int i = 1; i < 18; i += 2)
1777 output[sb * 18 + i] = -output[sb * 18 + i];
1778 }
1779
1780 void synthesize(const double input[576], int ch, float pcm[576])
1781 {
1782 static const auto kMatrixCos = [] {
1783 std::array<std::array<double, 32>, 64> t{};
1784 constexpr double kPi = 3.14159265358979323846;
1785 for (int i = 0; i < 64; ++i)
1786 for (int k = 0; k < 32; ++k)
1787 t[i][k] = std::cos(kPi / 64.0 * (16.0 + static_cast<double>(i)) * (2.0 * k + 1.0));
1788 return t;
1789 }();
1790
1791 ChannelState& state = channelState_[ch];
1792
1793 for (int ss = 0; ss < 18; ++ss)
1794 {
1795 double S[32];
1796 for (int sb = 0; sb < 32; ++sb) S[sb] = input[sb * 18 + ss];
1797
1798 double V[64];
1799 for (int i = 0; i < 64; ++i)
1800 {
1801 double sum = 0.0;
1802 const auto& row = kMatrixCos[i];
1803 for (int k = 0; k < 32; ++k) sum += S[k] * row[k];
1804 V[i] = sum;
1805 }
1806
1807 state.synthOffset = (state.synthOffset - 64) & 1023;
1808 for (int i = 0; i < 64; ++i) state.synthBuf[(state.synthOffset + i) & 1023] = V[i];
1809
1810 double U[512];
1811 for (int i = 0; i < 8; ++i)
1812 {
1813 for (int j = 0; j < 32; ++j)
1814 {
1815 U[i * 64 + j] = state.synthBuf[(state.synthOffset + i * 128 + j) & 1023];
1816 U[i * 64 + 32 + j] = state.synthBuf[(state.synthOffset + i * 128 + 96 + j) & 1023];
1817 }
1818 }
1819
1820 for (int j = 0; j < 32; ++j)
1821 {
1822 double sum = 0.0;
1823 for (int i = 0; i < 16; ++i) sum += U[i * 32 + j] * kSynthWindow[i * 32 + j];
1824 pcm[ss * 32 + j] = static_cast<float>(std::clamp(sum, -1.0, 1.0));
1825 }
1826 }
1827 }
1828
1829 class BitWriter
1830 {
1831 public:
1832 BitWriter() = default;
1833 void init(std::vector<uint8_t>& buf) { buf_ = &buf; bitPos_ = 0; }
1834
1835 void writeBits(uint32_t val, int n)
1836 {
1837 for (int i = n - 1; i >= 0; --i)
1838 {
1839 size_t byteIdx = bitPos_ >> 3;
1840 while (byteIdx >= buf_->size()) buf_->push_back(0);
1841 int bitIdx = 7 - static_cast<int>(bitPos_ & 7);
1842 if ((val >> static_cast<unsigned>(i)) & 1u)
1843 (*buf_)[byteIdx] |= static_cast<uint8_t>(1u << bitIdx);
1844 ++bitPos_;
1845 }
1846 }
1847
1848 [[nodiscard]] size_t getBitPos() const { return bitPos_; }
1849 void padToByte() { while (bitPos_ & 7) writeBits(0, 1); }
1850
1851 private:
1852 std::vector<uint8_t>* buf_ = nullptr;
1853 size_t bitPos_ = 0;
1854 };
1855
1856 void encAnalysis(const double* pcm32, int ch, double S[32])
1857 {
1858 auto& st = encState_[ch];
1859 std::memmove(st.analysisBuf + 32, st.analysisBuf, 480 * sizeof(double));
1860 for (int i = 0; i < 32; ++i) st.analysisBuf[i] = pcm32[31 - i];
1861
1862 double Y[64] = {};
1863 for (int i = 0; i < 64; ++i)
1864 for (int j = 0; j < 8; ++j)
1865 Y[i] += st.analysisBuf[i + j * 64] * kSynthWindow[i + j * 64];
1866
1867 static constexpr double kPi = 3.14159265358979323846;
1868 for (int k = 0; k < 32; ++k)
1869 {
1870 double sum = 0.0;
1871 for (int i = 0; i < 64; ++i)
1872 sum += Y[i] * std::cos(kPi / 64.0 * (2.0 * k + 1.0) * (i - 16.0));
1873 S[k] = sum;
1874 }
1875 }
1876
1877 static void encMdct36(const double z[36], double X[18])
1878 {
1879 static constexpr double kPi = 3.14159265358979323846;
1880 double zw[36];
1881 for (int n = 0; n < 36; ++n) zw[n] = z[n] * kNormalWindow[n];
1882
1883 for (int k = 0; k < 18; ++k)
1884 {
1885 double sum = 0.0;
1886 for (int n = 0; n < 36; ++n)
1887 sum += zw[n] * std::cos(kPi / 36.0 * (2.0 * n + 19.0) * (2.0 * k + 1.0));
1888 X[k] = sum;
1889 }
1890 }
1891
1892 static int encSelectTable(const int* ix, int count, int& tableOut)
1893 {
1894 if (count <= 0) { tableOut = 0; return 0; }
1895
1896 int maxVal = 0;
1897 for (int i = 0; i < count; ++i)
1898 {
1899 int v = ix[i] < 0 ? -ix[i] : ix[i];
1900 if (v > maxVal) maxVal = v;
1901 }
1902
1903 if (maxVal == 0) { tableOut = 0; return 0; }
1904
1905 struct TableCandidate { int table; int xmax; };
1906 static constexpr TableCandidate candidates[] = {
1907 {1, 1}, {2, 2}, {5, 3}, {7, 5}, {10, 7}, {13, 15},
1908 {16, 16}, {17, 18}, {18, 22}, {19, 30}, {20, 46},
1909 {21, 78}, {22, 142}, {23, 8206},
1910 {24, 30}, {25, 46}, {26, 78}, {27, 142}, {28, 270},
1911 {29, 526}, {30, 2062}, {31, 8206}
1912 };
1913
1914 int bestBits = 999999;
1915 int bestTable = 0;
1916 for (auto& c : candidates)
1917 {
1918 if (c.xmax < maxVal) continue;
1919 int bits = encCountTableBits(ix, count, c.table);
1920 if (bits < bestBits) { bestBits = bits; bestTable = c.table; }
1921 }
1922 tableOut = bestTable;
1923 return bestBits;
1924 }
1925
1926 static int encCountTableBits(const int* ix, int count, int tableIdx)
1927 {
1928 int linbits = kHuffLinbits[tableIdx];
1929 const HuffCode* codes = nullptr;
1930 int codeCount = 0;
1931 encGetTable(tableIdx, codes, codeCount);
1932 if (tableIdx != 0 && codes == nullptr) return 999999;
1933
1934 int totalBits = 0;
1935 for (int i = 0; i < count; i += 2)
1936 {
1937 int x = ix[i] < 0 ? -ix[i] : ix[i];
1938 int y = (i + 1 < count) ? (ix[i+1] < 0 ? -ix[i+1] : ix[i+1]) : 0;
1939 if (tableIdx == 0) { if (x != 0 || y != 0) return 999999; continue; }
1940
1941 int xBase = (linbits > 0 && x > 14) ? 15 : x;
1942 int yBase = (linbits > 0 && y > 14) ? 15 : y;
1943
1944 int cLen = 0;
1945 bool found = false;
1946 for (int c = 0; c < codeCount; ++c)
1947 {
1948 if (codes[c].x == xBase && codes[c].y == yBase)
1949 {
1950 cLen = codes[c].len; found = true; break;
1951 }
1952 }
1953 if (!found) return 999999;
1954
1955 totalBits += cLen;
1956 if (linbits > 0 && x > 14) totalBits += linbits;
1957 if (linbits > 0 && y > 14) totalBits += linbits;
1958 if (x != 0) totalBits += 1;
1959 if (y != 0) totalBits += 1;
1960 }
1961 return totalBits;
1962 }
1963
1964 static void encGetTable(int tableIdx, const HuffCode*& codes, int& count)
1965 {
1966 codes = nullptr; count = 0;
1967 switch (tableIdx)
1968 {
1969 case 1: codes = kHuff01; count = sizeof(kHuff01)/sizeof(HuffCode); break;
1970 case 2: codes = kHuff02; count = sizeof(kHuff02)/sizeof(HuffCode); break;
1971 case 3: codes = kHuff03; count = sizeof(kHuff03)/sizeof(HuffCode); break;
1972 case 5: codes = kHuff05; count = sizeof(kHuff05)/sizeof(HuffCode); break;
1973 case 6: codes = kHuff06; count = sizeof(kHuff06)/sizeof(HuffCode); break;
1974 case 7: codes = kHuff07; count = sizeof(kHuff07)/sizeof(HuffCode); break;
1975 case 8: codes = kHuff08; count = sizeof(kHuff08)/sizeof(HuffCode); break;
1976 case 9: codes = kHuff09; count = sizeof(kHuff09)/sizeof(HuffCode); break;
1977 case 10: codes = kHuff10; count = sizeof(kHuff10)/sizeof(HuffCode); break;
1978 case 11: codes = kHuff11; count = sizeof(kHuff11)/sizeof(HuffCode); break;
1979 case 12: codes = kHuff12; count = sizeof(kHuff12)/sizeof(HuffCode); break;
1980 case 13: codes = kHuff13; count = sizeof(kHuff13)/sizeof(HuffCode); break;
1981 case 15: codes = kHuff15; count = sizeof(kHuff15)/sizeof(HuffCode); break;
1982 case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23:
1983 codes = kHuff16; count = sizeof(kHuff16)/sizeof(HuffCode); break;
1984 case 24: case 25: case 26: case 27: case 28: case 29: case 30: case 31:
1985 codes = kHuff24; count = sizeof(kHuff24)/sizeof(HuffCode); break;
1986 default: break;
1987 }
1988 }
1989
1990 static int encQuantize(const double xr[576], int ix[576], int globalGain)
1991 {
1992 double step = std::pow(2.0, 0.25 * (globalGain - 210));
1993 if (step < 1e-30) step = 1e-30;
1994
1995 int maxIx = 0;
1996 for (int i = 0; i < 576; ++i)
1997 {
1998 double val = std::abs(xr[i]) / step;
1999 int q = static_cast<int>(std::pow(val, 0.75) + 0.4054);
2000 if (q > 8206) q = 8206; // Clamped to absolute standard maximum
2001 ix[i] = (xr[i] >= 0.0) ? q : -q;
2002 if (q > maxIx) maxIx = q;
2003 }
2004 return maxIx;
2005 }
2006
2007 static int encCountGranuleBits(const int ix[576], GranuleChannel& gc, const BandTable& bands)
2008 {
2009 int rzero = 576;
2010 while (rzero > 0 && ix[rzero - 1] == 0) --rzero;
2011 if (rzero == 0) { gc.big_values = 0; return 0; }
2012
2013 int count1End = rzero;
2014 int count1Start = count1End;
2015 while (count1Start >= 4)
2016 {
2017 bool allSmall = true;
2018 for (int j = count1Start - 4; j < count1Start; ++j)
2019 {
2020 int v = ix[j] < 0 ? -ix[j] : ix[j];
2021 if (v > 1) { allSmall = false; break; }
2022 }
2023 if (!allSmall) break;
2024 count1Start -= 4;
2025 }
2026
2027 gc.big_values = count1Start / 2;
2028 int bigEnd = gc.big_values * 2;
2029
2030 int r0 = 0, r1 = 0;
2031 if (bigEnd > 0)
2032 {
2033 int bestR0 = 1, bestR1 = 2;
2034 for (int t = 1; t < bands.longCount && bands.longBands[t] < bigEnd; ++t) bestR1 = t;
2035 bestR0 = (bestR1 > 1) ? bestR1 / 2 : 1;
2036 if (bestR0 >= bestR1) bestR0 = bestR1 - 1;
2037 if (bestR0 < 1) bestR0 = 1;
2038 r0 = bestR0; r1 = bestR1;
2039 }
2040
2041 gc.region0_count = std::max(r0 - 1, 0);
2042 gc.region1_count = std::max(r1 - r0 - 1, 0);
2043
2044 int reg0End = (r0 < bands.longCount) ? std::min(bands.longBands[r0], bigEnd) : bigEnd;
2045 int reg1End = (r1 < bands.longCount) ? std::min(bands.longBands[r1], bigEnd) : bigEnd;
2046
2047 int bits = 0;
2048 bits += encSelectTable(ix, reg0End, gc.table_select[0]);
2049 bits += encSelectTable(ix + reg0End, reg1End - reg0End, gc.table_select[1]);
2050 bits += encSelectTable(ix + reg1End, bigEnd - reg1End, gc.table_select[2]);
2051
2052 int count1Bits_A = 0, count1Bits_B = 0;
2053 for (int i = count1Start; i < count1End; i += 4)
2054 {
2055 int v = ix[i] != 0 ? 1 : 0;
2056 int w = (i+1 < 576 && ix[i+1] != 0) ? 1 : 0;
2057 int x = (i+2 < 576 && ix[i+2] != 0) ? 1 : 0;
2058 int y = (i+3 < 576 && ix[i+3] != 0) ? 1 : 0;
2059 int signBits = v + w + x + y;
2060
2061 for (int c = 0; c < 16; ++c)
2062 if (kCount1A[c].v == v && kCount1A[c].w == w && kCount1A[c].x == x && kCount1A[c].y == y)
2063 { count1Bits_A += kCount1A[c].len + signBits; break; }
2064
2065 count1Bits_B += 4 + signBits;
2066 }
2067
2068 if (count1Bits_A <= count1Bits_B)
2069 {
2070 gc.count1table_select = 0;
2071 bits += count1Bits_A;
2072 }
2073 else
2074 {
2075 gc.count1table_select = 1;
2076 bits += count1Bits_B;
2077 }
2078
2079 return bits;
2080 }
2081
2082 static void encHuffWrite(BitWriter& bw, const int* ix, int count, int tableIdx)
2083 {
2084 if (tableIdx == 0 || count <= 0) return;
2085 int linbits = kHuffLinbits[tableIdx];
2086 const HuffCode* codes = nullptr;
2087 int codeCount = 0;
2088 encGetTable(tableIdx, codes, codeCount);
2089
2090 for (int i = 0; i < count; i += 2)
2091 {
2092 int x = ix[i] < 0 ? -ix[i] : ix[i];
2093 int y = (i + 1 < count) ? (ix[i+1] < 0 ? -ix[i+1] : ix[i+1]) : 0;
2094 int xBase = (linbits > 0 && x > 14) ? 15 : x;
2095 int yBase = (linbits > 0 && y > 14) ? 15 : y;
2096
2097 for (int c = 0; c < codeCount; ++c)
2098 {
2099 if (codes[c].x == xBase && codes[c].y == yBase)
2100 {
2101 bw.writeBits(codes[c].code, codes[c].len); break;
2102 }
2103 }
2104
2105 if (linbits > 0 && x > 14) bw.writeBits(static_cast<uint32_t>(x - 15), linbits);
2106 if (x != 0) bw.writeBits(ix[i] < 0 ? 1u : 0u, 1);
2107
2108 if (linbits > 0 && y > 14) bw.writeBits(static_cast<uint32_t>(y - 15), linbits);
2109 if (y != 0) bw.writeBits((i+1 < count && ix[i+1] < 0) ? 1u : 0u, 1);
2110 }
2111 }
2112
2113 static void encCount1Write(BitWriter& bw, const int* ix, int start, int end, int tableSelect)
2114 {
2115 const Count1Code* codes = (tableSelect == 0) ? kCount1A : kCount1B;
2116 for (int i = start; i < end; i += 4)
2117 {
2118 int v = (ix[i] != 0) ? 1 : 0;
2119 int w = (i+1 < 576 && ix[i+1] != 0) ? 1 : 0;
2120 int x = (i+2 < 576 && ix[i+2] != 0) ? 1 : 0;
2121 int y = (i+3 < 576 && ix[i+3] != 0) ? 1 : 0;
2122
2123 for (int c = 0; c < 16; ++c)
2124 {
2125 if (codes[c].v == v && codes[c].w == w && codes[c].x == x && codes[c].y == y)
2126 {
2127 bw.writeBits(codes[c].code, codes[c].len); break;
2128 }
2129 }
2130
2131 if (v) bw.writeBits(ix[i] < 0 ? 1u : 0u, 1);
2132 if (w) bw.writeBits((i+1<576 && ix[i+1]<0) ? 1u : 0u, 1);
2133 if (x) bw.writeBits((i+2<576 && ix[i+2]<0) ? 1u : 0u, 1);
2134 if (y) bw.writeBits((i+3<576 && ix[i+3]<0) ? 1u : 0u, 1);
2135 }
2136 }
2137
2138 void encEncodeFrame()
2139 {
2140 const int nch = info_.numChannels;
2141 const int sr = static_cast<int>(info_.sampleRate);
2142 BandTable bands = getBandTable(sr);
2143
2144 int srIdx = (sr == 44100) ? 0 : (sr == 48000) ? 1 : 2;
2145 int brIdx = 0;
2146 for (int i = 1; i < 15; ++i) if (kBitrateTable[i] == encBitrate_) { brIdx = i; break; }
2147
2148 int baseFrameSize = 144 * encBitrate_ * 1000 / sr;
2149 int remainder = (144 * encBitrate_ * 1000) % sr;
2150 encPaddingAccum_ += remainder;
2151 bool padding = false;
2152 if (encPaddingAccum_ >= sr) { padding = true; encPaddingAccum_ -= sr; }
2153 int frameSize = baseFrameSize + (padding ? 1 : 0);
2154
2155 int sideInfoSize = (nch == 1) ? 17 : 32;
2156 int headerSize = 4;
2157 int availBytes = frameSize - headerSize - sideInfoSize;
2158 int availBits = availBytes * 8;
2159
2160 double subbands[2][32][36] = {};
2161 for (int ch = 0; ch < nch; ++ch)
2162 {
2163 for (int ts = 0; ts < 36; ++ts)
2164 {
2165 double S[32];
2166 encAnalysis(&encInput_[ch][ts * 32], ch, S);
2167 for (int sb = 0; sb < 32; ++sb) subbands[ch][sb][ts] = S[sb];
2168 }
2169 }
2170
2171 SideInfo si {};
2172 int ix[2][2][576] = {};
2173 double xr[2][2][576] = {};
2174
2175 for (int gr = 0; gr < 2; ++gr)
2176 {
2177 for (int ch = 0; ch < nch; ++ch)
2178 {
2179 for (int sb = 0; sb < 32; ++sb)
2180 {
2181 double mdctIn[36];
2182 for (int n = 0; n < 18; ++n) mdctIn[n] = encState_[ch].mdctOverlap[sb][n];
2183 for (int n = 0; n < 18; ++n) mdctIn[18 + n] = subbands[ch][sb][gr * 18 + n];
2184 for (int n = 0; n < 18; ++n) encState_[ch].mdctOverlap[sb][n] = subbands[ch][sb][gr * 18 + n];
2185
2186 double mdctOut[18];
2187 encMdct36(mdctIn, mdctOut);
2188 for (int k = 0; k < 18; ++k) xr[gr][ch][sb * 18 + k] = mdctOut[k];
2189 }
2190 }
2191 }
2192
2193 int bitsPerGranule = availBits / 2;
2194 for (int gr = 0; gr < 2; ++gr)
2195 {
2196 for (int ch = 0; ch < nch; ++ch)
2197 {
2198 auto& gc = si.gr[gr][ch];
2199 gc.block_type = 0; gc.window_switching = false; gc.mixed_block = 0;
2200 gc.preflag = 0; gc.scalefac_scale = 0; gc.scalefac_compress = 0;
2201
2202 int targetBits = bitsPerGranule / nch;
2203 int lo = 0, hi = 255, bestGain = 210, bestBits = 999999;
2204
2205 while (lo <= hi)
2206 {
2207 int mid = (lo + hi) / 2;
2208 int tmpIx[576];
2209 encQuantize(xr[gr][ch], tmpIx, mid);
2210
2211 GranuleChannel tmpGc = gc;
2212 int bits = encCountGranuleBits(tmpIx, tmpGc, bands);
2213
2214 if (bits <= targetBits)
2215 {
2216 if (bits <= bestBits || mid < bestGain)
2217 {
2218 bestBits = bits; bestGain = mid; gc = tmpGc;
2219 std::memcpy(ix[gr][ch], tmpIx, sizeof(tmpIx));
2220 }
2221 hi = mid - 1;
2222 }
2223 else lo = mid + 1;
2224 }
2225 gc.global_gain = bestGain;
2226 gc.part2_3_length = bestBits;
2227 }
2228 }
2229
2230 encFrameBuf_.clear();
2231 encFrameBuf_.resize(static_cast<size_t>(frameSize), 0);
2232 BitWriter bw;
2233 bw.init(encFrameBuf_);
2234
2235 bw.writeBits(0xFFF, 12);
2236 bw.writeBits(1, 1);
2237 bw.writeBits(0b01, 2);
2238 bw.writeBits(1, 1);
2239 bw.writeBits(static_cast<uint32_t>(brIdx), 4);
2240 bw.writeBits(static_cast<uint32_t>(srIdx), 2);
2241 bw.writeBits(padding ? 1u : 0u, 1);
2242 bw.writeBits(0, 1);
2243 bw.writeBits(nch == 1 ? 3u : 0u, 2);
2244 bw.writeBits(0, 2);
2245 bw.writeBits(0, 1);
2246 bw.writeBits(1, 1);
2247 bw.writeBits(0, 2);
2248
2249 bw.writeBits(0, 9);
2250 bw.writeBits(0, nch == 1 ? 5 : 3);
2251
2252 for (int ch = 0; ch < nch; ++ch) bw.writeBits(0, 4);
2253
2254 for (int gr = 0; gr < 2; ++gr)
2255 {
2256 for (int ch = 0; ch < nch; ++ch)
2257 {
2258 auto& gc = si.gr[gr][ch];
2259 bw.writeBits(static_cast<uint32_t>(gc.part2_3_length), 12);
2260 bw.writeBits(static_cast<uint32_t>(gc.big_values), 9);
2261 bw.writeBits(static_cast<uint32_t>(gc.global_gain), 8);
2262 bw.writeBits(static_cast<uint32_t>(gc.scalefac_compress), 4);
2263 bw.writeBits(0, 1);
2264 bw.writeBits(static_cast<uint32_t>(gc.table_select[0]), 5);
2265 bw.writeBits(static_cast<uint32_t>(gc.table_select[1]), 5);
2266 bw.writeBits(static_cast<uint32_t>(gc.table_select[2]), 5);
2267 bw.writeBits(static_cast<uint32_t>(gc.region0_count), 4);
2268 bw.writeBits(static_cast<uint32_t>(gc.region1_count), 3);
2269 bw.writeBits(static_cast<uint32_t>(gc.preflag), 1);
2270 bw.writeBits(static_cast<uint32_t>(gc.scalefac_scale), 1);
2271 bw.writeBits(static_cast<uint32_t>(gc.count1table_select), 1);
2272 }
2273 }
2274
2275 for (int gr = 0; gr < 2; ++gr)
2276 {
2277 for (int ch = 0; ch < nch; ++ch)
2278 {
2279 auto& gc = si.gr[gr][ch];
2280 int bigEnd = gc.big_values * 2;
2281
2282 int r0 = std::min(gc.region0_count + 1, bands.longCount);
2283 int r1 = std::min(gc.region0_count + gc.region1_count + 2, bands.longCount);
2284 int reg0End = std::min(bands.longBands[r0], bigEnd);
2285 int reg1End = std::min(bands.longBands[r1], bigEnd);
2286
2287 encHuffWrite(bw, ix[gr][ch], reg0End, gc.table_select[0]);
2288 encHuffWrite(bw, ix[gr][ch] + reg0End, reg1End - reg0End, gc.table_select[1]);
2289 encHuffWrite(bw, ix[gr][ch] + reg1End, bigEnd - reg1End, gc.table_select[2]);
2290
2291 int rzero = 576;
2292 while (rzero > bigEnd && ix[gr][ch][rzero - 1] == 0) --rzero;
2293 encCount1Write(bw, ix[gr][ch], bigEnd, rzero, gc.count1table_select);
2294 }
2295 }
2296
2297 bw.padToByte();
2298 encFrameBuf_.resize(static_cast<size_t>(frameSize), 0);
2299 outFile_.write(reinterpret_cast<const char*>(encFrameBuf_.data()), static_cast<std::streamsize>(frameSize));
2300 }
2301
2302 bool decodeAll()
2303 {
2304 int nch = info_.numChannels;
2305 int64_t totalSamples = info_.numSamples;
2306
2307 decodedSamplesFlat_.resize(static_cast<size_t>(nch * totalSamples), 0.0f);
2308
2309 for (int ch = 0; ch < kChannelsMax; ++ch) channelState_[ch] = {};
2310
2311 reservoir_.resize(kMaxReservoir, 0);
2312 reservoirSize_ = 0;
2313
2314 int prevScalefac[2][39] = {};
2315 int64_t sampleIdx = 0;
2316
2317 const size_t totalFrames = frameOffsets_.size();
2318 for (size_t frameIdx = 0; frameIdx < totalFrames; ++frameIdx)
2319 {
2320 size_t frameStart = frameOffsets_[frameIdx];
2321
2322 // A frame that fails to parse leaves its 1152-sample slot silent
2323 // instead of shifting the rest of the file earlier in time.
2324 FrameHeader hdr {};
2325 if (!parseFrameHeader(frameStart, hdr)) { sampleIdx += kSamplesPerFrame; continue; }
2326
2327 size_t headerSize = 4 + (hdr.crcProtect ? 2 : 0);
2328
2329 BitReader siBr;
2330 siBr.init(fileData_.data() + frameStart + headerSize, static_cast<size_t>(hdr.sideInfoSize));
2331
2332 SideInfo si {};
2333 if (!parseSideInfo(siBr, hdr, si)) { sampleIdx += kSamplesPerFrame; continue; }
2334
2335 size_t mainDataStart = frameStart + headerSize + static_cast<size_t>(hdr.sideInfoSize);
2336 size_t mainDataSize = static_cast<size_t>(hdr.frameSize) - headerSize - static_cast<size_t>(hdr.sideInfoSize);
2337
2338 size_t mainDataBegin = static_cast<size_t>(si.main_data_begin);
2339 std::vector<uint8_t> mainData;
2340
2341 if (mainDataBegin > 0)
2342 {
2343 if (mainDataBegin > reservoirSize_) mainDataBegin = reservoirSize_;
2344 size_t resStart = reservoirSize_ - mainDataBegin;
2345 mainData.insert(mainData.end(),
2346 reservoir_.begin() + static_cast<ptrdiff_t>(resStart),
2347 reservoir_.begin() + static_cast<ptrdiff_t>(reservoirSize_));
2348 }
2349
2350 if (mainDataStart + mainDataSize <= fileData_.size())
2351 {
2352 mainData.insert(mainData.end(),
2353 fileData_.begin() + static_cast<ptrdiff_t>(mainDataStart),
2354 fileData_.begin() + static_cast<ptrdiff_t>(mainDataStart + mainDataSize));
2355 }
2356
2357 if (mainDataSize > 0 && mainDataStart + mainDataSize <= fileData_.size())
2358 {
2359 size_t newTotal = reservoirSize_ + mainDataSize;
2360 if (newTotal > kMaxReservoir)
2361 {
2362 size_t shift = newTotal - kMaxReservoir;
2363 if (shift < reservoirSize_)
2364 {
2365 std::memmove(reservoir_.data(), reservoir_.data() + shift, reservoirSize_ - shift);
2366 reservoirSize_ -= shift;
2367 }
2368 else reservoirSize_ = 0;
2369 }
2370 size_t canCopy = std::min(mainDataSize, kMaxReservoir - reservoirSize_);
2371 std::memcpy(reservoir_.data() + reservoirSize_, fileData_.data() + mainDataStart, canCopy);
2372 reservoirSize_ += canCopy;
2373 }
2374
2375 BitReader mainBr;
2376 mainBr.init(mainData.data(), mainData.size());
2377
2378 int scalefac[2][39] = {};
2379
2380 for (int gr = 0; gr < kGranules; ++gr)
2381 {
2382 double xr[2][576] = {};
2383
2384 for (int ch = 0; ch < nch; ++ch)
2385 {
2386 const auto& gc = si.gr[gr][ch];
2387
2388 if (gr == 1)
2389 {
2390 for (int i = 0; i < 39; ++i) scalefac[ch][i] = prevScalefac[ch][i];
2391 }
2392
2393 size_t sfBits = 0;
2394 size_t posBeforeSf = mainBr.getPos();
2395 decodeScalefactors(mainBr, gc, gr, ch, si.scfsi[ch], scalefac[ch], sfBits);
2396
2397 // part2_3_length spans scalefactors + Huffman data, so the
2398 // end position anchors at posBeforeSf. huffmanDecode also
2399 // leaves the reader exactly there (resync).
2400 int is[576] = {};
2401 huffmanDecode(mainBr, gc, hdr, is,
2402 posBeforeSf + static_cast<size_t>(gc.part2_3_length));
2403
2404 requantize(is, scalefac[ch], gc, hdr, xr[ch]);
2405
2406 if (gr == 0)
2407 {
2408 for (int i = 0; i < 39; ++i) prevScalefac[ch][i] = scalefac[ch][i];
2409 }
2410 }
2411
2412 if (nch == 2) stereoProcess(xr, si.gr[gr], hdr, scalefac);
2413
2414 for (int ch = 0; ch < nch; ++ch)
2415 {
2416 reorder(xr[ch], si.gr[gr][ch], hdr);
2417 aliasReduction(xr[ch], si.gr[gr][ch]);
2418
2419 double imdctOut[576];
2420 imdct(xr[ch], si.gr[gr][ch], ch, imdctOut);
2421 frequencyInversion(imdctOut);
2422
2423 float pcm[576];
2424 synthesize(imdctOut, ch, pcm);
2425
2426 for (int i = 0; i < kSamplesPerGranule; ++i)
2427 {
2428 int64_t outIdx = sampleIdx + i;
2429 if (outIdx < totalSamples)
2430 decodedSamplesFlat_[static_cast<size_t>(ch * totalSamples + outIdx)] = pcm[i];
2431 }
2432 }
2433
2434 sampleIdx += kSamplesPerGranule;
2435 }
2436 }
2437
2438 return true;
2439 }
2440};
2441
2442} // namespace dspark
Abstract interface for reading and writing audio files.
Non-owning view over audio channel data.
Definition AudioBuffer.h:50
int getNumSamples() const noexcept
Returns the number of samples per channel.
int getNumChannels() const noexcept
Returns the number of channels in this view.
T * getChannel(int ch) const noexcept
Returns a pointer to the sample data for the given channel.
Abstract base class for audio file readers and writers.
Definition AudioFile.h:107
bool openRead(const std::filesystem::path &path) override
Opens a file for reading.
Definition Mp3File.h:63
bool openWrite(const std::filesystem::path &path, const AudioFileInfo &info) override
Opens a file for writing, creating it or overwriting if it exists.
Definition Mp3File.h:107
bool writeSamples(AudioBufferView< const float > src) override
Writes samples from the view to the file.
Definition Mp3File.h:169
bool readSamples(AudioBufferView< float > dest) override
Reads samples from the start of the file into the destination view.
Definition Mp3File.h:143
~Mp3File() override
Definition Mp3File.h:59
bool readSamples(AudioBufferView< float > dest, int64_t startFrame, int64_t numFrames) override
Reads a specific range of sample frames. Useful for chunked streaming.
Definition Mp3File.h:148
bool isOpen() const noexcept override
Checks if a valid file handle is currently open.
Definition Mp3File.h:217
AudioFileInfo getInfo() const override
Retrieves metadata of the currently opened file.
Definition Mp3File.h:141
void close() override
Finalizes file headers and releases system handles.
Definition Mp3File.h:194
Main namespace for the DSPark framework.
Metadata describing an audio file's format and dimensions.
Definition AudioFile.h:39
uint32_t numChannels
Number of audio channels (1 = mono, 2 = stereo).
Definition AudioFile.h:44
bool isFloatingPoint
True if the file stores floating-point samples (IEEE 754).
Definition AudioFile.h:59
uint32_t bitsPerSample
Bits per sample in the stored format (8, 16, 24, 32, 64).
Definition AudioFile.h:56
double sampleRate
Sample rate in Hz (e.g., 44100.0, 48000.0, 96000.0).
Definition AudioFile.h:41
int64_t numSamples
Total number of sample frames in the file.
Definition AudioFile.h:47