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