Initial release

This commit is contained in:
civ
2026-08-16 18:24:52 +07:00
commit 876886a39a
13244 changed files with 2353959 additions and 0 deletions
+184
View File
@@ -0,0 +1,184 @@
// gen_final.c: correct Huffman encoder table generator
// The key insight: leaf>>8 is only the FINAL flush.
// Total bits = sum of all intermediate flushes + leaf>>8.
// Only the first peek (5 bits) is NOT flushed if we get a direct hit.
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "tabs_data.h"
static const int tmax[] = {
0, 1, 2, 2, 0, 3, 3, 5, 5, 5, 7, 7, 7, 15, 0, 15,
15,15,15,15,15,15,15,15, 15,15,15,15,15,15,15,15
};
typedef struct { uint32_t code; uint8_t len; } henc_t;
static henc_t enc[16][16];
// Walk the minimp3 tree and return {leaf, total_bits_consumed}
// Returns -1 if cannot decode
static int walk_tree(const int16_t *codebook, uint32_t bits, int nbits,
int *total_consumed) {
uint32_t cache = (nbits < 32) ? (bits << (32 - nbits)) : bits;
int w = 5;
int leaf = codebook[cache >> (32 - w)];
int flushed = 0; // bits flushed so far
if (leaf >= 0) {
// Direct hit: only flush leaf>>8 bits (subset of the initial 5 peeked)
*total_consumed = leaf >> 8;
return leaf;
}
// Tree traversal: flush the initial 5 bits, then follow nodes
cache <<= w;
flushed = w;
while (leaf < 0) {
w = leaf & 7;
if (w == 0) return -1;
int peek = (int)(cache >> (32 - w));
int idx = peek - (leaf >> 3);
leaf = codebook[idx];
if (leaf < 0) {
// Not a leaf yet, flush these w bits and continue
cache <<= w;
flushed += w;
if (flushed > 30) return -1;
}
}
// leaf is positive: flush leaf>>8 more bits
*total_consumed = flushed + (leaf >> 8);
return leaf;
}
static void build_pair_table(int tab_num) {
int mx = tmax[tab_num];
memset(enc, 0, sizeof(enc));
const int16_t *codebook = tabs + tabindex[tab_num];
for (int len = 1; len <= 19; len++) {
for (uint32_t code = 0; code < (1u << len); code++) {
int total = 0;
int leaf = walk_tree(codebook, code, len, &total);
if (leaf < 0) continue;
if (total != len) continue;
int x = (leaf >> 4) & 0xF;
int y = leaf & 0xF;
if (x > mx || y > mx) continue;
if (enc[x][y].len == 0) {
enc[x][y].code = code;
enc[x][y].len = (uint8_t)len;
}
}
}
}
int main(void) {
// Verify completeness first
int ok = 1;
for (int t = 1; t < 32; t++) {
if (t == 0 || t == 4 || t == 14) continue;
int mx = tmax[t]; if (mx == 0) continue;
build_pair_table(t);
int dim = mx + 1, found = 0;
for (int x = 0; x < dim; x++)
for (int y = 0; y < dim; y++)
if (enc[x][y].len > 0) found++;
int expected = dim * dim;
if (found != expected) {
fprintf(stderr, "Table %2d: %d/%d INCOMPLETE\n", t, found, expected);
ok = 0;
} else {
fprintf(stderr, "Table %2d: %d/%d OK\n", t, found, expected);
}
}
if (!ok) {
fprintf(stderr, "WARNING: some tables incomplete\n");
}
// Generate output
printf("// mp3 Huffman encoder lookup tables\n");
printf("// Generated from minimp3 (CC0). ISO 11172-3 Table B.7.\n");
printf("// code = MSB first bit pattern. len = number of bits.\n");
printf("// Append sign bits for nonzero |x| and |y|.\n");
printf("// Values >= 15 use linbits extension.\n\n");
printf("static const uint8_t mp3enc_linbits[32] = {\n");
printf(" 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n");
printf(" 1,2,3,4,6,8,10,13,4,5,6,7,8,9,11,13\n};\n\n");
for (int t = 1; t < 32; t++) {
if (t == 0 || t == 4 || t == 14) continue;
int mx = tmax[t]; if (mx == 0) continue;
// Skip duplicate trees
int skip = 0;
for (int j = 1; j < t; j++) {
if (j == 4 || j == 14) continue;
if (tabindex[t] == tabindex[j] && tmax[t] == tmax[j]) {
printf("// table %d: same tree as table %d (linbits=%d)\n\n", t, j, g_linbits[t]);
skip = 1; break;
}
}
if (skip) continue;
build_pair_table(t);
int dim = mx + 1;
printf("static const uint16_t mp3enc_hcode_%d[%d][%d] = {\n", t, dim, dim);
for (int x = 0; x < dim; x++) {
printf(" {");
for (int y = 0; y < dim; y++) {
printf("0x%x", enc[x][y].code);
if (y < dim-1) printf(",");
}
printf("}%s\n", x < dim-1 ? "," : "");
}
printf("};\nstatic const uint8_t mp3enc_hlen_%d[%d][%d] = {\n", t, dim, dim);
for (int x = 0; x < dim; x++) {
printf(" {");
for (int y = 0; y < dim; y++) {
printf("%d", enc[x][y].len);
if (y < dim-1) printf(",");
}
printf("}%s\n", x < dim-1 ? "," : "");
}
printf("};\n\n");
}
// Count1 tables
for (int tbl = 0; tbl < 2; tbl++) {
const uint8_t *cb = tbl ? tab33 : tab32;
printf("// count1 table %c (count1table_select=%d)\n", 'A'+tbl, tbl);
printf("// index = v*8 + w*4 + x*2 + y\n");
uint32_t codes[16]={0}; uint8_t lens[16]={0};
for (int len = 1; len <= 10; len++) {
for (uint32_t code = 0; code < (1u<<len); code++) {
uint32_t cache = (len<32) ? (code<<(32-len)) : code;
int peek4 = (int)(cache>>28);
int leaf = cb[peek4];
int consumed;
if (leaf & 8) { consumed = leaf & 7; }
else {
int extra = leaf & 3, offset = leaf >> 3;
cache <<= 4;
int peek2 = (int)(cache >> (32-extra));
leaf = cb[offset + peek2];
consumed = leaf & 7;
}
if (consumed != len) continue;
int v=(leaf>>7)&1, w=(leaf>>6)&1, x=(leaf>>5)&1, y=(leaf>>4)&1;
int idx = v*8+w*4+x*2+y;
if (lens[idx]==0) { codes[idx]=code; lens[idx]=(uint8_t)consumed; }
}
}
printf("static const uint8_t mp3enc_count1%c_code[16] = {\n ", 'a'+tbl);
for (int i=0;i<16;i++) { printf("%d",codes[i]); if(i<15) printf(","); if(i==7) printf("\n "); }
printf("\n};\nstatic const uint8_t mp3enc_count1%c_len[16] = {\n ", 'a'+tbl);
for (int i=0;i<16;i++) { printf("%d",lens[i]); if(i<15) printf(","); if(i==7) printf("\n "); }
printf("\n};\n\n");
}
return 0;
}
+220
View File
@@ -0,0 +1,220 @@
#pragma once
// mp3enc-bits.h
// Bitstream writer, frame header, side information packer.
// Part of mp3enc. MIT license.
#include <cstdint>
#include <cstring>
// Bitstream writer: accumulates bits MSB first into a byte buffer.
// The encoder writes frame header, side info, and Huffman data through this.
struct mp3enc_bs {
uint8_t * buf; // output buffer (caller owned)
int capacity; // total bytes available
int byte_pos; // current byte offset
int bit_pos; // bits used in current byte (0..7, 0 = empty)
void init(uint8_t * dst, int cap) {
buf = dst;
capacity = cap;
byte_pos = 0;
bit_pos = 0;
memset(dst, 0, cap);
}
// Write n bits (1..32) from val, MSB first.
void put(uint32_t val, int n) {
for (int i = n - 1; i >= 0; i--) {
buf[byte_pos] |= (uint8_t) (((val >> i) & 1) << (7 - bit_pos));
bit_pos++;
if (bit_pos == 8) {
bit_pos = 0;
byte_pos++;
}
}
}
// Total bits written so far
int total_bits() const { return byte_pos * 8 + bit_pos; }
// Byte align (pad with zeros)
void align() {
if (bit_pos > 0) {
byte_pos++;
bit_pos = 0;
}
}
};
// Frame header: 4 bytes, fixed format for MPEG1 Layer III.
// ISO 11172-3, clause 2.4.2.3
struct mp3enc_header {
int bitrate_kbps; // from mp3enc_bitrate_kbps[]
int samplerate; // 44100, 48000, or 32000
int mode; // 0=stereo, 1=joint, 2=dual, 3=mono
int mode_ext; // for joint stereo: bit0=intensity, bit1=ms
int padding; // 0 or 1
// Compute bitrate_index from kbps
int bitrate_index() const {
// Match against the Layer III table
static const int br[] = { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 };
for (int i = 1; i < 15; i++) {
if (br[i] == bitrate_kbps) {
return i;
}
}
return 0; // free format
}
// Compute sampling_frequency field
int sr_index() const {
if (samplerate == 44100) {
return 0;
}
if (samplerate == 48000) {
return 1;
}
if (samplerate == 32000) {
return 2;
}
return 0;
}
// Frame size in bytes (including header)
int frame_bytes() const { return 144 * bitrate_kbps * 1000 / samplerate + padding; }
// Write 4 byte header to bitstream
void write(mp3enc_bs & bs) const {
bs.put(0xFFF, 12); // syncword
bs.put(1, 1); // ID = MPEG1
bs.put(1, 2); // layer = III (01)
bs.put(1, 1); // protection_bit = 1 (no CRC)
bs.put(bitrate_index(), 4); // bitrate_index
bs.put(sr_index(), 2); // sampling_frequency
bs.put(padding, 1); // padding_bit
bs.put(0, 1); // private_bit
bs.put(mode, 2); // mode
bs.put(mode_ext, 2); // mode_extension
bs.put(0, 1); // copyright
bs.put(1, 1); // original
bs.put(0, 2); // emphasis = none
}
};
// Granule side information for one channel.
// ISO 11172-3, clause 2.4.1.7
struct mp3enc_granule_info {
int part2_3_length; // total bits: scalefactors + Huffman data
int big_values; // number of pairs in big_values region
int global_gain; // quantizer step size (0..255)
int scalefac_compress; // index into slen table (0..15)
int block_type; // 0=normal, 1=start, 2=short, 3=stop
int mixed_block_flag; // 1 if lower bands use long windows
int table_select[3]; // Huffman table for each region
int subblock_gain[3]; // gain offset per short window
int region0_count; // sfb count in region 0
int region1_count; // sfb count in region 1
int preflag; // high frequency boost
int scalefac_scale; // 0 = sqrt(2) step, 1 = 2 step
int count1table_select; // 0 = table A, 1 = table B
// Scale factors (filled by quantization loop)
int scalefac_l[21]; // long block scalefactors
int scalefac_s[12][3]; // short block scalefactors
};
// Side information for one frame.
// Stereo: 32 bytes, mono: 17 bytes.
struct mp3enc_side_info {
int main_data_begin; // bit reservoir backpointer (bytes)
int scfsi[2][4]; // scalefactor selection info per channel
mp3enc_granule_info gr[2][2]; // [granule][channel]
// Write side info to bitstream (after header).
// nch = 1 for mono, 2 for stereo/joint/dual
void write(mp3enc_bs & bs, int nch) const {
bs.put(main_data_begin, 9);
// private bits
if (nch == 1) {
bs.put(0, 5);
} else {
bs.put(0, 3);
}
// scfsi
for (int ch = 0; ch < nch; ch++) {
for (int band = 0; band < 4; band++) {
bs.put(scfsi[ch][band], 1);
}
}
// per granule, per channel
for (int g = 0; g < 2; g++) {
for (int ch = 0; ch < nch; ch++) {
const mp3enc_granule_info & gi = gr[g][ch];
bs.put(gi.part2_3_length, 12);
bs.put(gi.big_values, 9);
bs.put(gi.global_gain, 8);
bs.put(gi.scalefac_compress, 4);
int window_switching = (gi.block_type != 0) ? 1 : 0;
bs.put(window_switching, 1);
if (window_switching) {
bs.put(gi.block_type, 2);
bs.put(gi.mixed_block_flag, 1);
for (int r = 0; r < 2; r++) {
bs.put(gi.table_select[r], 5);
}
for (int w = 0; w < 3; w++) {
bs.put(gi.subblock_gain[w], 3);
}
} else {
for (int r = 0; r < 3; r++) {
bs.put(gi.table_select[r], 5);
}
bs.put(gi.region0_count, 4);
bs.put(gi.region1_count, 3);
}
bs.put(gi.preflag, 1);
bs.put(gi.scalefac_scale, 1);
bs.put(gi.count1table_select, 1);
}
}
}
};
// Write scalefactors for one granule/channel into main_data.
// Returns number of bits written.
static int mp3enc_write_scalefactors(mp3enc_bs & bs,
const mp3enc_granule_info & gi,
int gr,
int nch_unused,
const int scfsi[4]) {
(void) nch_unused;
int slen1 = mp3enc_slen[0][gi.scalefac_compress];
int slen2 = mp3enc_slen[1][gi.scalefac_compress];
int bits = 0;
// Long blocks: 21 scalefactor bands, split by scfsi
// bands 0..5 (scfsi band 0)
// bands 6..10 (scfsi band 1)
// bands 11..15 (scfsi band 2)
// bands 16..20 (scfsi band 3)
static const int band_start[4] = { 0, 6, 11, 16 };
static const int band_end[4] = { 6, 11, 16, 21 };
for (int b = 0; b < 4; b++) {
if (gr == 0 || scfsi[b] == 0) {
int slen = (b < 2) ? slen1 : slen2;
for (int sfb = band_start[b]; sfb < band_end[b]; sfb++) {
bs.put(gi.scalefac_l[sfb], slen);
bits += slen;
}
}
}
return bits;
}
+69
View File
@@ -0,0 +1,69 @@
#pragma once
// mp3enc-filter.h
// Polyphase analysis filterbank: 32 new PCM samples in, 32 subband samples out.
// ISO 11172-3 clause 2.4.3.2 (encoder side, Annex C).
// Part of mp3enc. MIT license.
#include <cmath>
#include <cstring>
#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif
// The analysis filterbank state for one channel.
// Holds the 512 sample FIFO and produces 32 subband outputs per call.
struct mp3enc_filter {
float buf[512]; // circular buffer of past PCM samples
int off; // current write offset into buf
void init() {
memset(buf, 0, sizeof(buf));
off = 0;
}
// Feed 32 new PCM samples, produce 32 subband samples.
// pcm: pointer to 32 float samples (mono, this channel only)
// sb_out: output array of 32 subband values
//
// Algorithm (ISO 11172-3 Annex C, encoding process):
// 1. Shift 32 new samples into the 512 sample FIFO
// 2. Window: multiply by 512 Ci coefficients (mp3enc_enwindow)
// 3. Partial sum: 512 windowed values -> 64 values
// 4. Matrixing: 64 values -> 32 subband samples via DCT
void process(const float * pcm, float * sb_out) {
// Step 1: shift new samples into the buffer.
// The newest sample goes at buf[off], oldest at buf[off+31].
// We store them in reverse order so windowing is a straight multiply.
off = (off - 32) & 511;
for (int i = 0; i < 32; i++) {
buf[(off + i) & 511] = pcm[31 - i];
}
// Step 2 + 3: window and partial sum.
// z[i] = sum over j=0..7 of: buf[(off + i + 64*j) & 511] * Ci[i + 64*j]
// This produces 64 values from the 512 windowed samples.
float z[64];
for (int i = 0; i < 64; i++) {
float sum = 0.0f;
for (int j = 0; j < 8; j++) {
int buf_idx = (off + i + 64 * j) & 511;
int win_idx = i + 64 * j;
sum += buf[buf_idx] * mp3enc_enwindow[win_idx];
}
z[i] = sum;
}
// Step 4: matrixing (ISO 11172-3, Annex C, analysis filter).
// sb_out[k] = sum over i=0..63 of: z[i] * cos((2*k + 1) * (16 - i) * PI / 64)
// for k = 0..31 (subbands)
// Formula verified against ISO 11172-3 Table C.1
for (int k = 0; k < 32; k++) {
float sum = 0.0f;
for (int i = 0; i < 64; i++) {
float angle = (float) M_PI * (float) (2 * k + 1) * (float) (16 - i) / 64.0f;
sum += z[i] * cosf(angle);
}
sb_out[k] = sum;
}
}
};
+357
View File
@@ -0,0 +1,357 @@
#pragma once
// mp3enc-huff.h
// Huffman encoding of quantized spectral values.
// ISO 11172-3 clause 2.4.2.7.
// Part of mp3enc. MIT license.
#include <cstdlib>
// Count trailing zero pairs in quantized spectrum.
// Returns number of pairs of zeros from the end.
static int mp3enc_count_rzero(const int * ix, int n) {
int i = n - 2;
while (i >= 0 && ix[i] == 0 && ix[i + 1] == 0) {
i -= 2;
}
return (n - i - 2) / 2;
}
// Count quadruples with |val| <= 1 after big_values region.
// start: index right after big_values*2
// end: index right before rzero
// Returns number of quadruples.
static int mp3enc_count_count1(const int * ix, int start, int end) {
int count = 0;
int i = end - 4;
while (i >= start) {
if (abs(ix[i]) <= 1 && abs(ix[i + 1]) <= 1 && abs(ix[i + 2]) <= 1 && abs(ix[i + 3]) <= 1) {
count++;
i -= 4;
} else {
break;
}
}
return count;
}
// Compute bits needed to encode a pair (x, y) with a given table.
// Returns total bits (Huffman code + linbits + sign bits).
static int mp3enc_pair_bits(int table, int x, int y) {
if (table == 0) {
return 0; // table 0 = all zeros, no bits emitted
}
int ax = abs(x);
int ay = abs(y);
int bits = 0;
// Clamp to 15 for Huffman lookup; excess goes to linbits
int cx = (ax < 15) ? ax : 15;
int cy = (ay < 15) ? ay : 15;
int lb = mp3enc_linbits[table];
// Get Huffman code length.
// Tables share trees; we select the right code/len arrays based on table number.
// For phase 1, we use tables 1, 2, 5, 6, 7, 10, 13, 15 (the common choices).
int hlen = 0;
switch (table) {
case 1:
hlen = mp3enc_hlen_1[cy][cx];
break;
case 2:
hlen = mp3enc_hlen_2[cy][cx];
break;
case 3:
hlen = mp3enc_hlen_3[cy][cx];
break;
case 5:
hlen = mp3enc_hlen_5[cy][cx];
break;
case 6:
hlen = mp3enc_hlen_6[cy][cx];
break;
case 7:
hlen = mp3enc_hlen_7[cy][cx];
break;
case 8:
hlen = mp3enc_hlen_8[cy][cx];
break;
case 9:
hlen = mp3enc_hlen_9[cy][cx];
break;
case 10:
hlen = mp3enc_hlen_10[cy][cx];
break;
case 11:
hlen = mp3enc_hlen_11[cy][cx];
break;
case 12:
hlen = mp3enc_hlen_12[cy][cx];
break;
case 13:
hlen = mp3enc_hlen_13[cy][cx];
break;
case 15:
hlen = mp3enc_hlen_15[cy][cx];
break;
// 16..23 use table 16 tree; 24..31 use table 24 tree
case 16:
case 17:
case 18:
case 19:
case 20:
case 21:
case 22:
case 23:
hlen = mp3enc_hlen_16[cy][cx];
break;
case 24:
case 25:
case 26:
case 27:
case 28:
case 29:
case 30:
case 31:
hlen = mp3enc_hlen_24[cy][cx];
break;
default:
return 9999; // invalid table
}
if (hlen == 0 && (cx || cy)) {
return 9999; // no valid code
}
bits = hlen;
if (ax >= 15) {
bits += lb; // linbits for x
}
if (ay >= 15) {
bits += lb; // linbits for y
}
if (ax > 0) {
bits += 1; // sign bit for x
}
if (ay > 0) {
bits += 1; // sign bit for y
}
return bits;
}
// Write a Huffman coded pair to the bitstream.
static void mp3enc_write_pair(mp3enc_bs & bs, int table, int x, int y) {
if (table == 0) {
return; // table 0 = all zeros, nothing to write
}
int ax = abs(x);
int ay = abs(y);
int cx = (ax < 15) ? ax : 15;
int cy = (ay < 15) ? ay : 15;
int lb = mp3enc_linbits[table];
// Get Huffman code and length
uint16_t code = 0;
int len = 0;
switch (table) {
case 1:
code = mp3enc_hcode_1[cy][cx];
len = mp3enc_hlen_1[cy][cx];
break;
case 2:
code = mp3enc_hcode_2[cy][cx];
len = mp3enc_hlen_2[cy][cx];
break;
case 3:
code = mp3enc_hcode_3[cy][cx];
len = mp3enc_hlen_3[cy][cx];
break;
case 5:
code = mp3enc_hcode_5[cy][cx];
len = mp3enc_hlen_5[cy][cx];
break;
case 6:
code = mp3enc_hcode_6[cy][cx];
len = mp3enc_hlen_6[cy][cx];
break;
case 7:
code = mp3enc_hcode_7[cy][cx];
len = mp3enc_hlen_7[cy][cx];
break;
case 8:
code = mp3enc_hcode_8[cy][cx];
len = mp3enc_hlen_8[cy][cx];
break;
case 9:
code = mp3enc_hcode_9[cy][cx];
len = mp3enc_hlen_9[cy][cx];
break;
case 10:
code = mp3enc_hcode_10[cy][cx];
len = mp3enc_hlen_10[cy][cx];
break;
case 11:
code = mp3enc_hcode_11[cy][cx];
len = mp3enc_hlen_11[cy][cx];
break;
case 12:
code = mp3enc_hcode_12[cy][cx];
len = mp3enc_hlen_12[cy][cx];
break;
case 13:
code = mp3enc_hcode_13[cy][cx];
len = mp3enc_hlen_13[cy][cx];
break;
case 15:
code = mp3enc_hcode_15[cy][cx];
len = mp3enc_hlen_15[cy][cx];
break;
case 16:
case 17:
case 18:
case 19:
case 20:
case 21:
case 22:
case 23:
code = mp3enc_hcode_16[cy][cx];
len = mp3enc_hlen_16[cy][cx];
break;
case 24:
case 25:
case 26:
case 27:
case 28:
case 29:
case 30:
case 31:
code = mp3enc_hcode_24[cy][cx];
len = mp3enc_hlen_24[cy][cx];
break;
}
bs.put(code, len);
if (cx == 15 && lb > 0) {
bs.put(ax - 15, lb);
}
if (ax > 0) {
bs.put(x < 0 ? 1 : 0, 1);
}
if (cy == 15 && lb > 0) {
bs.put(ay - 15, lb);
}
if (ay > 0) {
bs.put(y < 0 ? 1 : 0, 1);
}
}
// Write count1 region (quadruples of {-1, 0, 1}).
static void mp3enc_write_count1(mp3enc_bs & bs, const int * ix, int start, int count, int table_sel) {
const uint8_t * ctab_code = table_sel ? mp3enc_count1b_code : mp3enc_count1a_code;
const uint8_t * ctab_len = table_sel ? mp3enc_count1b_len : mp3enc_count1a_len;
for (int q = 0; q < count; q++) {
int i = start + q * 4;
int v = abs(ix[i]);
int w = abs(ix[i + 1]);
int x = abs(ix[i + 2]);
int y = abs(ix[i + 3]);
int idx = v * 8 + w * 4 + x * 2 + y;
bs.put(ctab_code[idx], ctab_len[idx]);
if (v) {
bs.put(ix[i] < 0 ? 1 : 0, 1);
}
if (w) {
bs.put(ix[i + 1] < 0 ? 1 : 0, 1);
}
if (x) {
bs.put(ix[i + 2] < 0 ? 1 : 0, 1);
}
if (y) {
bs.put(ix[i + 3] < 0 ? 1 : 0, 1);
}
}
}
// Choose the best Huffman table for a region of pairs.
// Tries all candidate tables and returns the one with fewest bits.
static int mp3enc_choose_table(const int * ix, int start, int count) {
if (count <= 0) {
return 0;
}
// Find max absolute value in this region
int maxval = 0;
for (int i = start; i < start + count * 2; i++) {
int a = abs(ix[i]);
if (a > maxval) {
maxval = a;
}
}
if (maxval == 0) {
return 0;
}
// Candidate tables grouped by max entry:
// max 1: tables 1
// max 2: tables 2, 3
// max 3: tables 5, 6
// max 5: tables 7, 8, 9
// max 7: tables 10, 11, 12
// max 15: tables 13, 15
// max >15: tables 16..31 (with linbits)
static const int candidates[][8] = {
{ 1, 0 }, // maxval = 1
{ 2, 3, 0 }, // maxval = 2
{ 5, 6, 0 }, // maxval = 3
{ 7, 8, 9, 0 }, // maxval = 4..5
{ 7, 8, 9, 0 }, // (same)
{ 10, 11, 12, 0 }, // maxval = 6..7
{ 10, 11, 12, 0 }, // (same)
{ 13, 15, 0 }, // maxval = 8..15
};
// For values > 15, need linbits tables
static const int linbit_tables[] = { 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0 };
const int * cands;
if (maxval <= 1) {
cands = candidates[0];
} else if (maxval <= 2) {
cands = candidates[1];
} else if (maxval <= 3) {
cands = candidates[2];
} else if (maxval <= 5) {
cands = candidates[3];
} else if (maxval <= 7) {
cands = candidates[5];
} else if (maxval <= 15) {
cands = candidates[7];
} else {
cands = linbit_tables;
}
int best_table = cands[0];
int best_bits = 999999;
for (int c = 0; cands[c] != 0; c++) {
int t = cands[c];
// For linbits tables, skip if linbits too small for our max value
if (maxval > 15 && mp3enc_linbits[t] > 0) {
int max_encodable = 15 + (1 << mp3enc_linbits[t]) - 1;
if (maxval > max_encodable) {
continue;
}
}
int total = 0;
for (int p = 0; p < count; p++) {
total += mp3enc_pair_bits(t, ix[start + p * 2], ix[start + p * 2 + 1]);
}
if (total < best_bits) {
best_bits = total;
best_table = t;
}
}
return best_table;
}
+64
View File
@@ -0,0 +1,64 @@
#pragma once
// mp3enc-mdct.h
// Forward MDCT for the MP3 encoder: 36 subband samples -> 18 frequency lines.
// Window and MDCT are combined into a single step (ISO 11172-3 Annex C).
// Part of mp3enc. MIT license.
#include <cmath>
#include <cstring>
#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif
// Forward MDCT-36 for long blocks.
// in[36] = prev[18] + cur[18] (raw subband samples)
// out[18] = MDCT frequency coefficients
//
// Formula (ISO 11172-3 Annex C):
// out[k] = (1/9) * sum(n=0..35) in[n] * sin(pi/36*(n+0.5)) * cos(pi/72*(2n+19)*(2k+1))
static void mp3enc_mdct36(const float * in, float * out) {
for (int k = 0; k < 18; k++) {
float sum = 0.0f;
for (int n = 0; n < 36; n++) {
float w = sinf((float) M_PI / 36.0f * ((float) n + 0.5f));
float c = cosf((float) M_PI / 72.0f * (float) (2 * n + 19) * (float) (2 * k + 1));
sum += in[n] * w * c;
}
out[k] = sum * (1.0f / 9.0f);
}
}
// Alias reduction butterfly between adjacent subbands.
// Applied after MDCT, before quantization.
// ISO 11172-3 Table B.9 coefficients (from minimp3 CC0).
//
// For each pair of adjacent bands (band, band+1):
// mdct[band][17-i] and mdct[band+1][i] are butterflied with cs/ca.
static void mp3enc_alias_reduce(float * mdct_out) {
for (int band = 1; band < 32; band++) {
float * a = mdct_out + (band - 1) * 18; // previous band
float * b = mdct_out + band * 18; // current band
for (int i = 0; i < 8; i++) {
float u = a[17 - i];
float d = b[i];
a[17 - i] = u * mp3enc_cs[i] - d * mp3enc_ca[i];
b[i] = d * mp3enc_cs[i] + u * mp3enc_ca[i];
}
}
}
// Process all 32 subbands for one granule (long blocks only).
// sb_samples layout: prev_gr[32][18] and cur_gr[32][18] (band major).
// mdct_out[576]: output frequency lines (32 subbands * 18 lines)
static void mp3enc_mdct_granule(const float sb_prev[32][18], const float sb_cur[32][18], float * mdct_out) {
for (int band = 0; band < 32; band++) {
float mdct_in[36];
for (int k = 0; k < 18; k++) {
mdct_in[k] = sb_prev[band][k];
mdct_in[k + 18] = sb_cur[band][k];
}
mp3enc_mdct36(mdct_in, mdct_out + band * 18);
}
mp3enc_alias_reduce(mdct_out);
}
+303
View File
@@ -0,0 +1,303 @@
#pragma once
// mp3enc-psy.h
// Psychoacoustic model for MP3 encoding.
// Computes masking thresholds per scalefactor band from MDCT coefficients.
//
// Based on ISO 11172-3 Annex D principles:
// - Absolute threshold of hearing (ATH)
// - Bark-domain asymmetric spreading function (Schroeder)
// - Tonal vs noise masking detection (spectral flatness)
// - Variable masking offset: tonal -14.5 dB, noise -5.5 dB
//
// Constants from ISO 11172-3 Annex D and Zwicker (1961).
// MIT license.
#include <cmath>
// Number of scalefactor bands for long blocks
#define MP3ENC_PSY_SFB_MAX 21
// Absolute threshold of hearing in dB SPL.
// ISO formula: ATH(f) = 3.64*(f/1000)^-0.8 - 6.5*exp(-0.6*(f/1000-3.3)^2) + 1e-3*(f/1000)^4
// Minimum clamped at -20 dB to avoid numerical issues.
static inline float mp3enc_ath_db(float freq_hz) {
if (freq_hz < 10.0f) {
freq_hz = 10.0f;
}
float fk = freq_hz * 0.001f;
float ath = 3.64f * powf(fk, -0.8f) - 6.5f * expf(-0.6f * (fk - 3.3f) * (fk - 3.3f)) + 0.001f * fk * fk * fk * fk;
if (ath < -20.0f) {
ath = -20.0f;
}
return ath;
}
// Convert frequency in Hz to Bark scale.
// Traunmuller (1990) approximation, accurate to ~0.05 Bark.
static inline float mp3enc_hz_to_bark(float f) {
if (f < 1.0f) {
f = 1.0f;
}
return 13.0f * atanf(0.00076f * f) + 3.5f * atanf((f / 7500.0f) * (f / 7500.0f));
}
// Schroeder spreading function in dB.
// dz = bark distance from masker to maskee (positive = maskee above masker).
// This models the asymmetric excitation pattern of the basilar membrane:
// steep below the masker (~27 dB/Bark), shallow above (~10-25 dB/Bark).
// From Schroeder, Atal, Hall (1979).
static inline float mp3enc_spreading_db(float dz) {
float t = dz + 0.474f;
return 15.81f + 7.5f * t - 17.5f * sqrtf(1.0f + t * t);
}
// Psychoacoustic model state.
struct mp3enc_psy {
// Output: allowed distortion energy per SFB
float xmin[MP3ENC_PSY_SFB_MAX];
// Output: perceptual entropy for this granule/channel (ISO 11172-3 Annex D).
// Higher PE = more complex signal = needs more bits.
float pe;
// Forward masking: previous granule's masking energy (per channel)
float prev_mask[2][MP3ENC_PSY_SFB_MAX];
// Pre-echo control: 2 previous granules of spread energy (per channel).
// Used to prevent masking threshold from rising too fast on transients
// (ISO 11172-3 Annex D, l3psy.c lines 610-616).
float nb_1[2][MP3ENC_PSY_SFB_MAX]; // previous granule spread energy
float nb_2[2][MP3ENC_PSY_SFB_MAX]; // 2 granules ago spread energy
// Precomputed per-SFB data (set once per sample rate)
float ath_energy[3][MP3ENC_PSY_SFB_MAX]; // [sr_index][sfb]: ATH in linear power
float sfb_bark[3][MP3ENC_PSY_SFB_MAX]; // [sr_index][sfb]: center freq in Bark
bool ath_valid;
void init() {
ath_valid = false;
pe = 0.0f;
memset(xmin, 0, sizeof(xmin));
memset(prev_mask, 0, sizeof(prev_mask));
memset(nb_1, 0, sizeof(nb_1));
memset(nb_2, 0, sizeof(nb_2));
}
// Precompute ATH energy and Bark positions per SFB.
// Must be called once before compute().
void init_ath(int sr_index, const uint8_t * sfb_table, int sample_rate) {
// MDCT has 576 lines covering 0 to samplerate/2.
// Each line represents a frequency bin of width samplerate / (2*576).
float freq_per_line = (float) sample_rate / (2.0f * 576.0f);
int pos = 0;
for (int sfb = 0; sfb < MP3ENC_PSY_SFB_MAX; sfb++) {
int width = sfb_table[sfb];
if (width == 0) {
ath_energy[sr_index][sfb] = 1e-20f;
sfb_bark[sr_index][sfb] = 0.0f;
continue;
}
// Center frequency of this SFB
float center_freq = ((float) pos + (float) width * 0.5f) * freq_per_line;
sfb_bark[sr_index][sfb] = mp3enc_hz_to_bark(center_freq);
// ATH: minimum of all lines in the band (most permissive)
float ath_min_db = 200.0f;
for (int j = 0; j < width; j++) {
float freq = ((float) (pos + j) + 0.5f) * freq_per_line;
float db = mp3enc_ath_db(freq);
if (db < ath_min_db) {
ath_min_db = db;
}
}
// Convert dB SPL to linear power, scaled by band width.
// Reference at 120 dB SPL (tuned empirically). A higher reference
// makes the ATH floor less dominant relative to the spreading
// function, so bits are spent on perceptual masking rather than
// fighting the absolute hearing threshold in quiet passages.
float ath_linear = powf(10.0f, (ath_min_db - 120.0f) * 0.1f) * (float) width;
ath_energy[sr_index][sfb] = ath_linear;
pos += width;
}
ath_valid = true;
}
// Compute masking thresholds for one granule/channel.
//
// Algorithm:
// 1. Compute energy per SFB from MDCT coefficients
// 2. Estimate tonality per SFB (spectral flatness measure)
// 3. Compute masking offset per SFB based on tonality
// 4. Apply Bark-domain spreading function
// 5. Combine spread masking with ATH
//
// mdct: 576 MDCT coefficients (after MS stereo if applicable)
// sfb_table: SFB widths for this sample rate
// sr_index: sample rate index
void compute(const float * mdct, const uint8_t * sfb_table, int sr_index, int ch = 0) {
float energy[MP3ENC_PSY_SFB_MAX];
float tonality[MP3ENC_PSY_SFB_MAX];
// Step 1: compute energy per SFB
int pos = 0;
for (int sfb = 0; sfb < MP3ENC_PSY_SFB_MAX; sfb++) {
int width = sfb_table[sfb];
float e = 0.0f;
for (int j = 0; j < width; j++) {
float x = mdct[pos + j];
e += x * x;
}
energy[sfb] = e;
pos += width;
}
// Step 2: estimate tonality per SFB using spectral flatness measure (SFM).
// SFM = geometric_mean(power) / arithmetic_mean(power)
// SFM = 1.0 for flat noise, SFM -> 0 for a single tone.
// We use log domain to avoid overflow: log(geometric_mean) = mean(log(power)).
pos = 0;
for (int sfb = 0; sfb < MP3ENC_PSY_SFB_MAX; sfb++) {
int width = sfb_table[sfb];
if (width == 0 || energy[sfb] < 1e-20f) {
tonality[sfb] = 0.5f; // default: assume mixed
pos += width;
continue;
}
float log_sum = 0.0f;
float arith = 0.0f;
int n_active = 0;
for (int j = 0; j < width; j++) {
float p = mdct[pos + j] * mdct[pos + j];
if (p > 1e-20f) {
log_sum += logf(p);
n_active++;
}
arith += p;
}
if (n_active < 2) {
// Single line or silence: treat as tonal
tonality[sfb] = 0.0f;
} else {
float geom_log = log_sum / (float) n_active;
float arith_mean = arith / (float) n_active;
// SFM in log domain: log(geom/arith) = geom_log - log(arith)
float sfm_log = geom_log - logf(arith_mean);
// sfm_log is <= 0. For flat spectrum sfm_log ~ 0, for tonal sfm_log << 0.
// Map to tonality index alpha in [0,1]:
// alpha = min(sfm_log / log(0.01), 1.0)
// log(0.01) = -4.605; so if sfm_log < -4.6 we consider it fully tonal.
float alpha = sfm_log / -4.605f;
if (alpha < 0.0f) {
alpha = 0.0f;
}
if (alpha > 1.0f) {
alpha = 1.0f;
}
tonality[sfb] = alpha; // 0 = noise, 1 = tonal
}
pos += width;
}
// Step 3: compute masking offset per SFB.
// TMN/NMT from ISO 11172-3, relaxed empirically for 128kbps.
// TMN=13.0 (tonal masking noise), NMT=4.5 (noise masking tone).
float offset_linear[MP3ENC_PSY_SFB_MAX];
for (int sfb = 0; sfb < MP3ENC_PSY_SFB_MAX; sfb++) {
float alpha = tonality[sfb];
float offset_db = alpha * 13.0f + (1.0f - alpha) * 4.5f;
offset_linear[sfb] = powf(10.0f, -offset_db * 0.1f);
}
// Step 4: Bark-domain spreading function.
// For each target SFB, sum the spread contributions from all source SFBs.
// The spreading function is asymmetric: steep below, shallow above.
float spread_energy[MP3ENC_PSY_SFB_MAX];
for (int j = 0; j < MP3ENC_PSY_SFB_MAX; j++) {
float sum = 0.0f;
float bark_j = sfb_bark[sr_index][j];
for (int i = 0; i < MP3ENC_PSY_SFB_MAX; i++) {
if (energy[i] < 1e-20f) {
continue;
}
float bark_i = sfb_bark[sr_index][i];
float dz_raw = bark_j - bark_i;
// Asymmetric spreading (ISO 11172-3 psy model 2, L3para_read).
// Upward masking (dz > 0): gentle slope, low freqs mask highs well.
// Downward masking (dz < 0): steep slope, highs mask lows poorly.
float dz = (dz_raw >= 0.0f) ? dz_raw * 1.35f : dz_raw * 2.7f;
// Spreading function value in dB
float sf_db = mp3enc_spreading_db(dz);
// Only apply if spreading is above -60 dB (optimization)
if (sf_db < -60.0f) {
continue;
}
float sf_linear = powf(10.0f, sf_db * 0.1f);
sum += energy[i] * sf_linear;
}
spread_energy[j] = sum;
}
// Step 5: combine spreading + offset, then apply pre-echo control.
// Pre-echo (ISO 11172-3 Annex D): prevent threshold from rising too fast
// on transients. Clamp current nb by 2x previous and 16x two-back.
// xmin = max(ath, min(nb, 2*nb_1, 16*nb_2))
for (int sfb = 0; sfb < MP3ENC_PSY_SFB_MAX; sfb++) {
float nb = spread_energy[sfb] * offset_linear[sfb];
// Pre-echo clamp: use history to limit sudden threshold rises
float clamped = nb;
float lim1 = 2.0f * nb_1[ch][sfb];
float lim2 = 16.0f * nb_2[ch][sfb];
if (lim1 > 0.0f && lim1 < clamped) {
clamped = lim1;
}
if (lim2 > 0.0f && lim2 < clamped) {
clamped = lim2;
}
// Update history (store UN-clamped nb for future reference)
nb_2[ch][sfb] = nb_1[ch][sfb];
nb_1[ch][sfb] = nb;
// ATH floor
float ath = ath_energy[sr_index][sfb];
xmin[sfb] = (clamped > ath) ? clamped : ath;
}
// Step 6: forward masking (temporal).
// A loud granule raises the masking threshold for the next granule.
// At 44.1kHz one granule = 13ms. Forward masking decays ~12dB over 13ms.
// Decay factor: 10^(-12/10) = ~0.063.
static const float fwd_decay = 0.063f;
for (int sfb = 0; sfb < MP3ENC_PSY_SFB_MAX; sfb++) {
float fwd = prev_mask[ch][sfb] * fwd_decay;
if (fwd > xmin[sfb]) {
xmin[sfb] = fwd;
}
// Save current mask (spread_energy, not xmin) for next granule
prev_mask[ch][sfb] = spread_energy[sfb];
}
// Step 7: perceptual entropy (ISO 11172-3 Annex D).
// PE = sum of width * log(energy/threshold) for bands where energy > threshold.
// Used by the bit reservoir to give more bits to complex granules.
pe = 0.0f;
for (int sfb = 0; sfb < MP3ENC_PSY_SFB_MAX; sfb++) {
if (energy[sfb] > xmin[sfb] && xmin[sfb] > 1e-20f) {
pe += (float) sfb_table[sfb] * logf(energy[sfb] / xmin[sfb]);
}
}
}
};
+650
View File
@@ -0,0 +1,650 @@
#pragma once
// mp3enc-quant.h
// Quantization: inner loop (global_gain search) + outer loop (scalefactor iteration).
// ISO 11172-3 Annex C, encoding process.
// Part of mp3enc. MIT license.
#include <cmath>
#include <cstring>
// Quantize one MDCT coefficient using the MP3 power law quantizer.
// xr = input MDCT value (float)
// istep = 2^(-3/16 * (global_gain - 210))
// Returns quantized integer (always >= 0; sign stored separately).
static inline int mp3enc_quantize_value(float xr, float istep) {
float ax = fabsf(xr);
// ix = nint(ax^0.75 * istep)
float val = sqrtf(ax * sqrtf(ax)) * istep;
if (val > 8191.0f) {
return 8191;
}
int ix = (int) (val + 0.36f); // rounding bias for better SNR
return ix;
}
// Quantize 576 MDCT coefficients with per-band scalefactors.
// The scalefactor amplifies each band's coefficients before quantization,
// giving finer resolution to bands that need it.
//
// Decoder (minimp3) dequantization:
// scf_shift = scalefac_scale + 1
// band_gain = 2^(-(sf << scf_shift) / 4)
// which gives 2^(-sf/2) for scalefac_scale=0, 2^(-sf) for scalefac_scale=1
//
// Encoder compensates: sfb_amp = 2^(ss * sf) where ss = 0.5 or 1.0
static void mp3enc_quantize_sfb(const float * xr,
int * ix,
int global_gain,
const int * scalefac,
int scalefac_scale,
int preflag,
const uint8_t * sfb_table) {
float istep = powf(2.0f, -0.1875f * (float) (global_gain - 210));
float ss = scalefac_scale ? 1.0f : 0.5f;
int pos = 0;
for (int sfb = 0; sfb_table[sfb] != 0 && pos < 576; sfb++) {
int width = sfb_table[sfb];
int sf = scalefac[sfb] + (preflag ? mp3enc_pretab[sfb] : 0);
float sfb_amp = (sf > 0) ? powf(2.0f, ss * (float) sf) : 1.0f;
for (int j = 0; j < width && pos < 576; j++, pos++) {
float xr_adj = fabsf(xr[pos]) * sfb_amp;
float val = sqrtf(xr_adj * sqrtf(xr_adj)) * istep;
int q;
if (val > 8191.0f) {
q = 8191;
} else {
q = (int) (val + 0.36f);
}
ix[pos] = (xr[pos] >= 0.0f) ? q : -q;
}
}
while (pos < 576) {
ix[pos++] = 0;
}
}
// Simple quantize without scalefactors (Phase 1 compatible).
// Kept for the initial global_gain search before outer loop kicks in.
static void mp3enc_quantize(const float * xr, int * ix, int global_gain) {
float istep = powf(2.0f, -0.1875f * (float) (global_gain - 210));
for (int i = 0; i < 576; i++) {
int q = mp3enc_quantize_value(xr[i], istep);
ix[i] = (xr[i] >= 0.0f) ? q : -q;
}
}
// Compute quantization noise energy per SFB.
// Noise = sum((xr[i] - dequant(ix[i]))^2) for each band.
// Dequant matches minimp3: xr = |ix|^(4/3) * 2^((gg-210)/4) * 2^(-ss*sf)
// where ss = 0.5 (scalefac_scale=0) or 1.0 (scalefac_scale=1).
static void mp3enc_calc_noise(const float * xr,
const int * ix,
int global_gain,
const int * scalefac,
int scalefac_scale,
int preflag,
const uint8_t * sfb_table,
float * noise) {
float step = powf(2.0f, 0.25f * (float) (global_gain - 210));
float ss = scalefac_scale ? 1.0f : 0.5f;
int pos = 0;
for (int sfb = 0; sfb_table[sfb] != 0 && pos < 576; sfb++) {
int width = sfb_table[sfb];
int sf = scalefac[sfb] + (preflag ? mp3enc_pretab[sfb] : 0);
float sfb_gain = (sf > 0) ? powf(2.0f, -ss * (float) sf) : 1.0f;
float n = 0.0f;
for (int j = 0; j < width && pos < 576; j++, pos++) {
// Dequantize
int aix = abs(ix[pos]);
float dequant = (float) aix;
// |ix|^(4/3): use pow for accuracy
if (aix > 0) {
dequant = powf((float) aix, 4.0f / 3.0f) * step * sfb_gain;
} else {
dequant = 0.0f;
}
if (ix[pos] < 0) {
dequant = -dequant;
}
float diff = xr[pos] - dequant;
n += diff * diff;
}
noise[sfb] = n;
}
}
// Count total Huffman bits for 576 quantized values.
// Also fills out granule info: big_values, table_select, count1, etc.
// Returns total bits for Huffman data (not including scalefactors).
static int mp3enc_count_bits(const int * ix, mp3enc_granule_info & gi, const uint8_t * sfb_table, int sr_index) {
(void) sr_index;
// Find the three regions: big_values, count1, rzero
int rzero_pairs = mp3enc_count_rzero(ix, 576);
int nz_end = 576 - rzero_pairs * 2;
// count1: quadruples with |val| <= 1, scanning from end of nonzero region
int c1_start = nz_end;
int c1_count = 0;
{
int i = nz_end - 4;
while (i >= 0 && abs(ix[i]) <= 1 && abs(ix[i + 1]) <= 1 && abs(ix[i + 2]) <= 1 && abs(ix[i + 3]) <= 1) {
c1_start = i;
c1_count++;
i -= 4;
}
}
gi.big_values = c1_start / 2;
int bv_end = c1_start; // end of big_values region (pair aligned)
// Region boundaries from SFB table.
int region_end[3] = { 0, 0, bv_end };
if (gi.block_type == 0) {
// Try a few region0_count values and pick the best.
int total_sfb = 0;
int sfb_acc[22] = {};
{
int acc = 0;
for (int sfb = 0; sfb < 22; sfb++) {
acc += sfb_table[sfb];
sfb_acc[sfb] = acc;
if (acc <= bv_end) {
total_sfb = sfb + 1;
}
}
}
int best_r0 = 7, best_r1 = 0, best_rbits = 999999;
for (int r0t = 5; r0t < 11 && r0t < total_sfb; r0t++) {
int r1t = total_sfb - r0t - 1;
if (r1t < 0) {
r1t = 0;
}
if (r1t > 7) {
r1t = 7;
}
int re0 = (sfb_acc[r0t] < bv_end) ? sfb_acc[r0t] : bv_end;
int sfb1 = r0t + r1t + 1;
if (sfb1 > 21) {
sfb1 = 21;
}
int re1 = (sfb_acc[sfb1] < bv_end) ? sfb_acc[sfb1] : bv_end;
int t0 = mp3enc_choose_table(ix, 0, re0 / 2);
int t1 = mp3enc_choose_table(ix, re0, (re1 - re0) / 2);
int t2 = mp3enc_choose_table(ix, re1, (bv_end - re1) / 2);
int rbits = 0;
for (int i = 0; i < re0; i += 2) {
rbits += mp3enc_pair_bits(t0, ix[i], ix[i + 1]);
}
for (int i = re0; i < re1; i += 2) {
rbits += mp3enc_pair_bits(t1, ix[i], ix[i + 1]);
}
for (int i = re1; i < bv_end; i += 2) {
rbits += mp3enc_pair_bits(t2, ix[i], ix[i + 1]);
}
if (rbits < best_rbits) {
best_rbits = rbits;
best_r0 = r0t;
best_r1 = r1t;
}
}
gi.region0_count = best_r0;
gi.region1_count = best_r1;
// Compute region end positions
{
int acc = 0;
for (int sfb = 0; sfb <= gi.region0_count; sfb++) {
acc += sfb_table[sfb];
}
region_end[0] = (acc < bv_end) ? acc : bv_end;
}
{
int acc = 0;
for (int sfb = 0; sfb <= gi.region0_count + gi.region1_count + 1; sfb++) {
acc += sfb_table[sfb];
}
region_end[1] = (acc < bv_end) ? acc : bv_end;
}
region_end[2] = bv_end;
}
// Choose Huffman tables for each region (3 regions for long blocks)
int n_regions = 3;
int total_bits = 0;
int prev_end = 0;
for (int r = 0; r < n_regions; r++) {
int pairs = (region_end[r] - prev_end) / 2;
gi.table_select[r] = mp3enc_choose_table(ix, prev_end, pairs);
for (int p = 0; p < pairs; p++) {
int i = prev_end + p * 2;
total_bits += mp3enc_pair_bits(gi.table_select[r], ix[i], ix[i + 1]);
}
prev_end = region_end[r];
}
// Count1 region: try both tables, pick the smaller
int c1_bits_a = 0, c1_bits_b = 0;
for (int q = 0; q < c1_count; q++) {
int i = c1_start + q * 4;
int v = abs(ix[i]), w = abs(ix[i + 1]), x = abs(ix[i + 2]), y = abs(ix[i + 3]);
int idx = v * 8 + w * 4 + x * 2 + y;
int signs = (v > 0) + (w > 0) + (x > 0) + (y > 0);
c1_bits_a += mp3enc_count1a_len[idx] + signs;
c1_bits_b += mp3enc_count1b_len[idx] + signs;
}
if (c1_bits_a <= c1_bits_b) {
gi.count1table_select = 0;
total_bits += c1_bits_a;
} else {
gi.count1table_select = 1;
total_bits += c1_bits_b;
}
return total_bits;
}
// Compute part2_length: number of bits for scalefactors.
// Depends on scalefac_compress and which bands are transmitted.
static int mp3enc_part2_length(const mp3enc_granule_info & gi, int gr, const int scfsi[4]) {
int slen1 = mp3enc_slen[0][gi.scalefac_compress];
int slen2 = mp3enc_slen[1][gi.scalefac_compress];
int bits = 0;
// Long blocks: 4 scfsi groups
static const int band_start[4] = { 0, 6, 11, 16 };
static const int band_end[4] = { 6, 11, 16, 21 };
for (int b = 0; b < 4; b++) {
if (gr == 0 || scfsi[b] == 0) {
int slen = (b < 2) ? slen1 : slen2;
int count = band_end[b] - band_start[b];
bits += count * slen;
}
}
return bits;
}
// Find the best scalefac_compress for the current scalefactors.
// Returns the compress index (0..15) that can represent all scalefactors
// with the fewest total bits.
static int mp3enc_best_scalefac_compress(const int * scalefac_l) {
// Find max scalefactor in each group
int max1 = 0; // bands 0..10 (slen1)
int max2 = 0; // bands 11..20 (slen2)
for (int sfb = 0; sfb < 11; sfb++) {
if (scalefac_l[sfb] > max1) {
max1 = scalefac_l[sfb];
}
}
for (int sfb = 11; sfb < 21; sfb++) {
if (scalefac_l[sfb] > max2) {
max2 = scalefac_l[sfb];
}
}
// Try all 16 compress values, pick the one with fewest bits
// that can represent the max values
int best_compress = 0;
int best_bits = 999;
for (int c = 0; c < 16; c++) {
int s1 = mp3enc_slen[0][c];
int s2 = mp3enc_slen[1][c];
int max_val1 = (s1 > 0) ? ((1 << s1) - 1) : 0;
int max_val2 = (s2 > 0) ? ((1 << s2) - 1) : 0;
// Can this compress value represent our scalefactors?
if (max1 > max_val1 || max2 > max_val2) {
continue;
}
// Total bits for scalefactors (granule 0, no scfsi)
int bits = 11 * s1 + 10 * s2;
if (bits < best_bits) {
best_bits = bits;
best_compress = c;
}
}
return best_compress;
}
// Inner loop: find minimum global_gain where Huffman bits fit the budget.
// Bit count is monotonically decreasing with global_gain (higher gain = coarser
// quantization = fewer bits). We want the smallest gain where bits <= budget.
//
// When hint_gain >= 0 (from a previous inner_loop call in the same outer loop),
// the optimal gain is typically within a few steps. We scan linearly from the
// hint instead of doing a full binary search on [0, 255]. This cuts the typical
// iteration count from 8 to 3-4.
//
// scalefac: per-band scalefactors (NULL for initial call before outer loop).
// hint_gain: previous global_gain from last inner_loop call, or -1 for full search.
static int mp3enc_inner_loop(const float * xr,
int * ix,
mp3enc_granule_info & gi,
int available_bits,
const uint8_t * sfb_table,
int sr_index,
const int * scalefac = nullptr,
int hint_gain = -1) {
// quantize + count_bits helper (avoids repeating the branch 5 times)
auto try_gain = [&](int g) -> int {
if (!scalefac || gi.scalefac_compress == 0) {
mp3enc_quantize(xr, ix, g);
} else {
mp3enc_quantize_sfb(xr, ix, g, scalefac, gi.scalefac_scale, gi.preflag, sfb_table);
}
for (int i = 0; i < 576; i++) {
if (abs(ix[i]) >= 8191) {
return available_bits + 1; // saturated
}
}
return mp3enc_count_bits(ix, gi, sfb_table, sr_index);
};
int best_gain = 210;
int best_bits = available_bits + 1;
if (hint_gain >= 0) {
// Linear scan from hint. Typical cost: 3-4 try_gain calls.
int bits = try_gain(hint_gain);
if (bits <= available_bits) {
// Hint fits. Scan downward to find the minimum valid gain.
best_gain = hint_gain;
best_bits = bits;
for (int g = hint_gain - 1; g >= 0 && g >= hint_gain - 10; g--) {
bits = try_gain(g);
if (bits > available_bits) {
break;
}
best_gain = g;
best_bits = bits;
}
} else {
// Hint doesn't fit. Scan upward to find the first valid gain.
bool found = false;
for (int g = hint_gain + 1; g <= 255 && g <= hint_gain + 20; g++) {
bits = try_gain(g);
if (bits <= available_bits) {
best_gain = g;
best_bits = bits;
found = true;
break;
}
}
// Fallback: if scan didn't find it (rare, e.g. scalefac_scale toggle),
// binary search on the remaining range.
if (!found) {
int lo = hint_gain + 21;
int hi = 255;
while (lo <= hi) {
int mid = (lo + hi) / 2;
bits = try_gain(mid);
if (bits <= available_bits) {
best_gain = mid;
best_bits = bits;
hi = mid - 1;
} else {
lo = mid + 1;
}
}
}
}
} else {
// No hint: full binary search on [0, 255].
int lo = 0, hi = 255;
while (lo <= hi) {
int mid = (lo + hi) / 2;
int bits = try_gain(mid);
if (bits <= available_bits) {
best_gain = mid;
best_bits = bits;
hi = mid - 1;
} else {
lo = mid + 1;
}
}
}
// Final quantization with the best gain
gi.global_gain = best_gain;
if (!scalefac || gi.scalefac_compress == 0) {
mp3enc_quantize(xr, ix, best_gain);
} else {
mp3enc_quantize_sfb(xr, ix, best_gain, scalefac, gi.scalefac_scale, gi.preflag, sfb_table);
}
best_bits = mp3enc_count_bits(ix, gi, sfb_table, sr_index);
return best_bits;
}
// Outer loop: iteratively adjust scalefactors to push quantization noise
// below the masking thresholds computed by the psy model.
//
// Algorithm:
// 1. Start with all scalefactors = 0, run inner loop
// 2. Compute noise per SFB
// 3. For each SFB where noise > xmin, bump its scalefactor
// 4. Update scalefac_compress, recompute bit budget, re-run inner loop
// 5. Repeat until noise is under control or we run out of iterations/bits
//
// xr: 576 MDCT coefficients
// ix: 576 quantized output
// gi: granule info (filled on return)
// xmin: masking thresholds per SFB from psy model
// available_bits: total bits for part2_3 (scalefactors + Huffman)
// sfb_table: SFB widths
// sr_index: sample rate index
// gr: granule number (0 or 1)
// scfsi: scfsi flags (for part2_length calculation)
// Returns part2_3_length (scalefactor bits + Huffman bits).
static int mp3enc_outer_loop(const float * xr,
int * ix,
mp3enc_granule_info & gi,
const float * xmin,
int available_bits,
const uint8_t * sfb_table,
int sr_index,
int gr,
const int scfsi[4]) {
// Initialize: no scalefactors
memset(&gi, 0, sizeof(gi));
gi.block_type = 0;
// Initial inner loop with flat quantization
int huff_bits = mp3enc_inner_loop(xr, ix, gi, available_bits, sfb_table, sr_index);
gi.part2_3_length = huff_bits;
// If no psy thresholds (all zero), skip outer loop
bool have_psy = false;
for (int sfb = 0; sfb < 21; sfb++) {
if (xmin[sfb] > 0.0f) {
have_psy = true;
break;
}
}
if (!have_psy) {
return gi.part2_3_length;
}
// Outer iteration loop (ISO 11172-3 Annex C.1.5.4.3).
// For each iteration:
// - compute distortion per SFB
// - bump scalefactor for EVERY band where noise > xmin
// - re-run inner loop with updated scalefactors
// - stop when all bands are under threshold or no bits left
//
// Max 25 passes: enough for convergence at all bitrates.
float noise[22]; // 22 SFB bands before table terminator
int best_ix[576];
mp3enc_granule_info best_gi = gi;
int best_total = gi.part2_3_length;
int best_over = 21; // start pessimistic
float best_max_db = 999.0f; // worst-band noise in dB over threshold
float best_tot_db = 999.0f; // total over-threshold noise in dB
memcpy(best_ix, ix, sizeof(best_ix));
for (int iter = 0; iter < 25; iter++) {
// Compute noise per SFB with current quantization
mp3enc_calc_noise(xr, ix, gi.global_gain, gi.scalefac_l, gi.scalefac_scale, gi.preflag, sfb_table, noise);
// Compute noise metrics for 3-axis comparison (GPSYCHO approach).
// Instead of just counting bands over threshold, track:
// - max_over_db: worst violation in dB (peak distortion)
// - tot_over_db: sum of violations in dB (for average)
// - over_count: number of distorted bands
// This prefers solutions that minimize peak distortion and spread
// remaining noise evenly, rather than concentrating it in one band.
int over_count = 0;
float max_over_db = 0.0f;
float tot_over_db = 0.0f;
for (int sfb = 0; sfb < 21; sfb++) {
if (xmin[sfb] > 0.0f && noise[sfb] > xmin[sfb]) {
over_count++;
float over_db = 10.0f * log10f(noise[sfb] / xmin[sfb]);
tot_over_db += over_db;
if (over_db > max_over_db) {
max_over_db = over_db;
}
}
}
// 3-axis quant_compare (inspired by LAME GPSYCHO outer_loop):
// 1. Clean (over=0) always beats dirty (over>0)
// 2. Among clean solutions: prefer fewer bits
// 3. Among dirty solutions: minimize peak, then average, then count
bool is_better = false;
if (over_count == 0 && best_over > 0) {
is_better = true;
} else if (over_count == 0 && best_over == 0) {
is_better = (gi.part2_3_length < best_total);
} else if (over_count > 0 && best_over > 0) {
// both dirty: compare peak distortion first
if (max_over_db < best_max_db - 0.5f) {
// significantly lower peak -> better
is_better = true;
} else if (max_over_db < best_max_db + 0.5f) {
// similar peak: compare average violation
float avg = tot_over_db / (float) over_count;
float best_avg = (best_over > 0) ? best_tot_db / (float) best_over : 0.0f;
if (avg < best_avg - 0.3f) {
is_better = true;
} else if (avg < best_avg + 0.3f) {
// similar average: prefer fewer violated bands
is_better = (over_count < best_over);
}
}
}
if (is_better) {
best_gi = gi;
best_total = gi.part2_3_length;
best_over = over_count;
best_max_db = max_over_db;
best_tot_db = tot_over_db;
memcpy(best_ix, ix, sizeof(best_ix));
}
// If all bands are under threshold, we are done
if (over_count == 0) {
break;
}
// Bump scalefactor for EVERY band where noise > threshold.
// ISO outer loop: amplify all distorted bands by 1 step per iteration.
bool any_changed = false;
for (int sfb = 0; sfb < 21; sfb++) {
if (xmin[sfb] > 0.0f && noise[sfb] > xmin[sfb]) {
gi.scalefac_l[sfb]++;
any_changed = true;
}
}
if (!any_changed) {
break;
}
// Preflag: if HF bands need large scalefactors, enable preflag
// to get free amplification from the pretab table (ISO Table B.6).
// This saves bits: pretab adds 0-3 to HF scalefactors for free
// (encoded in a single bit rather than per-band bits).
if (!gi.preflag) {
int hf_need = 0;
for (int sfb = 11; sfb < 21; sfb++) {
if (gi.scalefac_l[sfb] >= 2 && mp3enc_pretab[sfb] > 0) {
hf_need++;
}
}
// Enable if at least 3 HF bands need boosting
if (hf_need >= 3) {
gi.preflag = 1;
for (int sfb = 0; sfb < 21; sfb++) {
gi.scalefac_l[sfb] -= mp3enc_pretab[sfb];
if (gi.scalefac_l[sfb] < 0) {
gi.scalefac_l[sfb] = 0;
}
}
}
}
// scalefac_scale: if any scalefactor exceeds 15 (4 bit max),
// double the step size. This halves all scalefactors but each
// step now represents sqrt(2) instead of 2^(1/4).
int max_sf = 0;
for (int sfb = 0; sfb < 21; sfb++) {
if (gi.scalefac_l[sfb] > max_sf) {
max_sf = gi.scalefac_l[sfb];
}
}
if (max_sf > 15 && !gi.scalefac_scale) {
gi.scalefac_scale = 1;
for (int sfb = 0; sfb < 21; sfb++) {
gi.scalefac_l[sfb] = (gi.scalefac_l[sfb] + 1) / 2;
}
}
// Clamp to 15
for (int sfb = 0; sfb < 21; sfb++) {
if (gi.scalefac_l[sfb] > 15) {
gi.scalefac_l[sfb] = 15;
}
}
// Update scalefac_compress and compute part2 bits
gi.scalefac_compress = mp3enc_best_scalefac_compress(gi.scalefac_l);
int part2 = mp3enc_part2_length(gi, gr, scfsi);
int huff_budget = available_bits - part2;
if (huff_budget < 0) {
break;
}
// Re-run inner loop
huff_bits = mp3enc_inner_loop(xr, ix, gi, huff_budget, sfb_table, sr_index, gi.scalefac_l, gi.global_gain);
int total = part2 + huff_bits;
if (total <= available_bits) {
gi.part2_3_length = total;
} else {
break;
}
}
// Restore best result
gi = best_gi;
memcpy(ix, best_ix, sizeof(best_ix));
gi.part2_3_length = best_total;
return gi.part2_3_length;
}
+485
View File
@@ -0,0 +1,485 @@
#pragma once
// mp3enc-tables.h
// Numerical constants for the MP3 encoder.
// Extracted from minimp3 (CC0, github.com/lieff/minimp3).
// Values match ISO 11172-3 Annex B+C.
// MIT license.
#include <stdint.h>
// Layer III bitrates in kbps, indexed by bitrate_index 0..14
// Index 0 = free format, index 15 = forbidden
static const int mp3enc_bitrate_kbps[15] = { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 };
// MPEG1 sample rates, indexed by sampling_frequency field (2 bits)
static const int mp3enc_samplerate[3] = { 44100, 48000, 32000 };
// slen1 and slen2 from scalefac_compress (0..15)
// slen1 = mp3enc_slen[0][i], slen2 = mp3enc_slen[1][i]
static const uint8_t mp3enc_slen[2][16] = {
{ 0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4 },
{ 0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3 }
};
// Pretab values added to scalefactors when preflag=1 (ISO Table B.6)
static const uint8_t mp3enc_pretab[22] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 2, 0 };
// SFB boundaries: long blocks (ISO Table B.8, from minimp3 CC0)
// MPEG1 only: [0]=44100Hz, [1]=48000Hz, [2]=32000Hz
// These correspond to minimp3 g_scf_long[5..7].
static const uint8_t mp3enc_sfb_long[3][23] = {
{ 4, 4, 4, 4, 4, 4, 6, 6, 8, 8, 10, 12, 16, 20, 24, 28, 34, 42, 50, 54, 76, 158, 0 },
{ 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, 10, 12, 16, 18, 22, 28, 34, 40, 46, 54, 54, 192, 0 },
{ 4, 4, 4, 4, 4, 4, 6, 6, 8, 10, 12, 16, 20, 24, 30, 38, 46, 56, 68, 84, 102, 26, 0 }
};
// SFB boundaries: short blocks (ISO Table B.8, from minimp3 CC0)
// [sr_index][band_width]
// SFB boundaries: short blocks (ISO Table B.8, from minimp3 CC0)
// MPEG1 only: [0]=44100Hz, [1]=48000Hz, [2]=32000Hz
static const uint8_t mp3enc_sfb_short[3][40] = {
{ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, 8, 8, 10, 10,
10, 12, 12, 12, 14, 14, 14, 18, 18, 18, 22, 22, 22, 30, 30, 30, 56, 56, 56, 0 },
{ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 6, 6, 6, 10, 10,
10, 12, 12, 12, 14, 14, 14, 16, 16, 16, 20, 20, 20, 26, 26, 26, 66, 66, 66, 0 },
{ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, 8, 8, 12, 12,
12, 16, 16, 16, 20, 20, 20, 26, 26, 26, 34, 34, 34, 42, 42, 42, 12, 12, 12, 0 }
};
// SFB boundaries: mixed blocks (ISO Table B.8, from minimp3 CC0)
// [sr_index][band_width]
static const uint8_t mp3enc_sfb_mixed[8][40] = {
{ 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 8, 8, 10, 10, 10, 12, 12, 12, 14,
14, 14, 18, 18, 18, 24, 24, 24, 30, 30, 30, 40, 40, 40, 18, 18, 18, 0 },
{ 12, 12, 12, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16, 20, 20, 20, 24, 24,
24, 28, 28, 28, 36, 36, 36, 2, 2, 2, 2, 2, 2, 2, 2, 2, 26, 26, 26, 0 },
{ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 8, 8, 10, 10, 10, 14,
14, 14, 18, 18, 18, 26, 26, 26, 32, 32, 32, 42, 42, 42, 18, 18, 18, 0 },
{ 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 8, 8, 10, 10, 10, 12, 12, 12, 14,
14, 14, 18, 18, 18, 24, 24, 24, 32, 32, 32, 44, 44, 44, 12, 12, 12, 0 },
{ 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 8, 8, 10, 10, 10, 12, 12, 12, 14,
14, 14, 18, 18, 18, 24, 24, 24, 30, 30, 30, 40, 40, 40, 18, 18, 18, 0 },
{ 4, 4, 4, 4, 4, 4, 6, 6, 4, 4, 4, 6, 6, 6, 8, 8, 8, 10, 10, 10,
12, 12, 12, 14, 14, 14, 18, 18, 18, 22, 22, 22, 30, 30, 30, 56, 56, 56, 0 },
{ 4, 4, 4, 4, 4, 4, 6, 6, 4, 4, 4, 6, 6, 6, 6, 6, 6, 10, 10, 10,
12, 12, 12, 14, 14, 14, 16, 16, 16, 20, 20, 20, 26, 26, 26, 66, 66, 66, 0 },
{ 4, 4, 4, 4, 4, 4, 6, 6, 4, 4, 4, 6, 6, 6, 8, 8, 8, 12, 12, 12,
16, 16, 16, 20, 20, 20, 26, 26, 26, 34, 34, 34, 42, 42, 42, 12, 12, 12, 0 }
};
// Alias reduction butterfly coefficients (ISO Table B.9, from minimp3 CC0)
// cs[i] = 1/sqrt(1 + ci^2), ca[i] = ci/sqrt(1 + ci^2)
static const float mp3enc_cs[8] = { 0.85749293f, 0.88174200f, 0.94962865f, 0.98331459f,
0.99551782f, 0.99916056f, 0.99989920f, 0.99999316f };
static const float mp3enc_ca[8] = { 0.51449576f, 0.47173197f, 0.31337745f, 0.18191320f,
0.09457419f, 0.04096558f, 0.01419856f, 0.00369997f };
// MDCT window shapes for overlap add (from minimp3 CC0)
// [0] = normal/start, [1] = stop block
// First 9 values: sin(pi/36 * (i + 0.5)) for i=0..8
// Last 9 values: sin(pi/36 * (i + 18.5)) for i=0..8
static const float mp3enc_mdct_win[2][18] = {
{ 0.99904822f, 0.99144486f, 0.97629601f, 0.95371695f, 0.92387953f, 0.88701083f, 0.84339145f, 0.79335334f,
0.73727734f, 0.04361938f, 0.13052619f, 0.21643961f, 0.30070580f, 0.38268343f, 0.46174861f, 0.53729961f,
0.60876143f, 0.67559021f },
{ 1, 1, 1, 1, 1, 1, 0.99144486f, 0.92387953f, 0.79335334f, 0, 0, 0, 0, 0, 0, 0.13052619f, 0.38268343f, 0.60876143f }
};
// MDCT twiddle factors for 18 point and 6 point transforms (from minimp3 CC0)
static const float mp3enc_twid9[18] = { 0.73727734f, 0.79335334f, 0.84339145f, 0.88701083f, 0.92387953f, 0.95371695f,
0.97629601f, 0.99144486f, 0.99904822f, 0.67559021f, 0.60876143f, 0.53729961f,
0.46174861f, 0.38268343f, 0.30070580f, 0.21643961f, 0.13052619f, 0.04361938f };
static const float mp3enc_twid3[6] = { 0.79335334f, 0.92387953f, 0.99144486f, 0.60876143f, 0.38268343f, 0.13052619f };
// Analysis filterbank window, 512 coefficients.
// Ci coefficients for the polyphase analysis filter (ISO 11172-3 Table C.1).
// Extracted from minimp3 (CC0).
static const float mp3enc_enwindow[512] = {
0.000000e+00f, -0.000000e+00f, -0.000000e+00f, -0.000000e+00f, -0.000000e+00f, -0.000000e+00f, -0.000000e+00f,
-1.000000e-06f, -1.000000e-06f, -1.000000e-06f, -1.000000e-06f, -1.000000e-06f, -1.000000e-06f, -2.000000e-06f,
-2.000000e-06f, -2.000000e-06f, -2.000000e-06f, -3.000000e-06f, -3.000000e-06f, -3.000000e-06f, -4.000000e-06f,
-4.000000e-06f, -5.000000e-06f, -5.000000e-06f, -6.000000e-06f, -7.000000e-06f, -8.000000e-06f, -8.000000e-06f,
-9.000000e-06f, -1.000000e-05f, -1.100000e-05f, -1.200000e-05f, -1.400000e-05f, -1.500000e-05f, -1.700000e-05f,
-1.800000e-05f, -2.000000e-05f, -2.100000e-05f, -2.300000e-05f, -2.500000e-05f, -2.800000e-05f, -3.000000e-05f,
-3.200000e-05f, -3.500000e-05f, -3.800000e-05f, -4.100000e-05f, -4.300000e-05f, -4.600000e-05f, -5.000000e-05f,
-5.300000e-05f, -5.600000e-05f, -6.000000e-05f, -6.300000e-05f, -6.600000e-05f, -7.000000e-05f, -7.300000e-05f,
-7.700000e-05f, -8.100000e-05f, -8.400000e-05f, -8.700000e-05f, -9.100000e-05f, -9.300000e-05f, -9.600000e-05f,
-9.900000e-05f, 1.020000e-04f, 1.040000e-04f, 1.060000e-04f, 1.070000e-04f, 1.080000e-04f, 1.090000e-04f,
1.090000e-04f, 1.080000e-04f, 1.070000e-04f, 1.050000e-04f, 1.030000e-04f, 9.900000e-05f, 9.500000e-05f,
9.000000e-05f, 8.400000e-05f, 7.800000e-05f, 7.000000e-05f, 6.100000e-05f, 5.100000e-05f, 4.000000e-05f,
2.700000e-05f, 1.400000e-05f, -1.000000e-06f, -1.700000e-05f, -3.400000e-05f, -5.300000e-05f, -7.300000e-05f,
-9.400000e-05f, -1.160000e-04f, -1.400000e-04f, -1.650000e-04f, -1.910000e-04f, -2.190000e-04f, -2.470000e-04f,
-2.770000e-04f, -3.080000e-04f, -3.390000e-04f, -3.710000e-04f, -4.040000e-04f, -4.380000e-04f, -4.730000e-04f,
-5.070000e-04f, -5.420000e-04f, -5.770000e-04f, -6.120000e-04f, -6.470000e-04f, -6.810000e-04f, -7.140000e-04f,
-7.470000e-04f, -7.790000e-04f, -8.100000e-04f, -8.390000e-04f, -8.660000e-04f, -8.920000e-04f, -9.150000e-04f,
-9.360000e-04f, -9.540000e-04f, -9.690000e-04f, -9.810000e-04f, -9.890000e-04f, -9.940000e-04f, -9.950000e-04f,
-9.920000e-04f, -9.840000e-04f, 9.710000e-04f, 9.540000e-04f, 9.310000e-04f, 9.030000e-04f, 8.690000e-04f,
8.290000e-04f, 7.840000e-04f, 7.320000e-04f, 6.740000e-04f, 6.100000e-04f, 5.390000e-04f, 4.630000e-04f,
3.790000e-04f, 2.880000e-04f, 1.920000e-04f, 8.800000e-05f, -2.100000e-05f, -1.370000e-04f, -2.600000e-04f,
-3.880000e-04f, -5.220000e-04f, -6.620000e-04f, -8.070000e-04f, -9.570000e-04f, -1.111000e-03f, -1.270000e-03f,
-1.432000e-03f, -1.598000e-03f, -1.767000e-03f, -1.937000e-03f, -2.110000e-03f, -2.283000e-03f, -2.457000e-03f,
-2.631000e-03f, -2.803000e-03f, -2.974000e-03f, -3.142000e-03f, -3.307000e-03f, -3.467000e-03f, -3.623000e-03f,
-3.772000e-03f, -3.914000e-03f, -4.049000e-03f, -4.175000e-03f, -4.291000e-03f, -4.396000e-03f, -4.490000e-03f,
-4.570000e-03f, -4.638000e-03f, -4.691000e-03f, -4.728000e-03f, -4.749000e-03f, -4.752000e-03f, -4.737000e-03f,
-4.703000e-03f, -4.649000e-03f, -4.574000e-03f, -4.477000e-03f, -4.358000e-03f, -4.215000e-03f, -4.049000e-03f,
-3.859000e-03f, -3.643000e-03f, -3.402000e-03f, 3.135000e-03f, 2.841000e-03f, 2.522000e-03f, 2.175000e-03f,
1.801000e-03f, 1.400000e-03f, 9.710000e-04f, 5.160000e-04f, 3.300000e-05f, -4.760000e-04f, -1.012000e-03f,
-1.574000e-03f, -2.162000e-03f, -2.774000e-03f, -3.411000e-03f, -4.072000e-03f, -4.756000e-03f, -5.462000e-03f,
-6.189000e-03f, -6.937000e-03f, -7.703000e-03f, -8.487000e-03f, -9.288000e-03f, -1.010400e-02f, -1.093300e-02f,
-1.177500e-02f, -1.262800e-02f, -1.348900e-02f, -1.435900e-02f, -1.523400e-02f, -1.611300e-02f, -1.699400e-02f,
-1.787600e-02f, -1.875700e-02f, -1.963400e-02f, -2.050700e-02f, -2.137200e-02f, -2.222900e-02f, -2.307400e-02f,
-2.390700e-02f, -2.472500e-02f, -2.552700e-02f, -2.631100e-02f, -2.707400e-02f, -2.781500e-02f, -2.853300e-02f,
-2.922500e-02f, -2.989000e-02f, -3.052700e-02f, -3.113300e-02f, -3.170700e-02f, -3.224800e-02f, -3.275500e-02f,
-3.322600e-02f, -3.366000e-02f, -3.405600e-02f, -3.441300e-02f, -3.473000e-02f, -3.500700e-02f, -3.524200e-02f,
-3.543500e-02f, -3.558600e-02f, -3.569400e-02f, -3.575900e-02f, 3.578100e-02f, 3.575900e-02f, 3.569400e-02f,
3.558600e-02f, 3.543500e-02f, 3.524200e-02f, 3.500700e-02f, 3.473000e-02f, 3.441300e-02f, 3.405600e-02f,
3.366000e-02f, 3.322600e-02f, 3.275500e-02f, 3.224800e-02f, 3.170700e-02f, 3.113300e-02f, 3.052700e-02f,
2.989000e-02f, 2.922500e-02f, 2.853300e-02f, 2.781500e-02f, 2.707400e-02f, 2.631100e-02f, 2.552700e-02f,
2.472500e-02f, 2.390700e-02f, 2.307400e-02f, 2.222900e-02f, 2.137200e-02f, 2.050700e-02f, 1.963400e-02f,
1.875700e-02f, 1.787600e-02f, 1.699400e-02f, 1.611300e-02f, 1.523400e-02f, 1.435900e-02f, 1.348900e-02f,
1.262800e-02f, 1.177500e-02f, 1.093300e-02f, 1.010400e-02f, 9.288000e-03f, 8.487000e-03f, 7.703000e-03f,
6.937000e-03f, 6.189000e-03f, 5.462000e-03f, 4.756000e-03f, 4.072000e-03f, 3.411000e-03f, 2.774000e-03f,
2.162000e-03f, 1.574000e-03f, 1.012000e-03f, 4.760000e-04f, -3.300000e-05f, -5.160000e-04f, -9.710000e-04f,
-1.400000e-03f, -1.801000e-03f, -2.175000e-03f, -2.522000e-03f, -2.841000e-03f, 3.135000e-03f, 3.402000e-03f,
3.643000e-03f, 3.859000e-03f, 4.049000e-03f, 4.215000e-03f, 4.358000e-03f, 4.477000e-03f, 4.574000e-03f,
4.649000e-03f, 4.703000e-03f, 4.737000e-03f, 4.752000e-03f, 4.749000e-03f, 4.728000e-03f, 4.691000e-03f,
4.638000e-03f, 4.570000e-03f, 4.490000e-03f, 4.396000e-03f, 4.291000e-03f, 4.175000e-03f, 4.049000e-03f,
3.914000e-03f, 3.772000e-03f, 3.623000e-03f, 3.467000e-03f, 3.307000e-03f, 3.142000e-03f, 2.974000e-03f,
2.803000e-03f, 2.631000e-03f, 2.457000e-03f, 2.283000e-03f, 2.110000e-03f, 1.937000e-03f, 1.767000e-03f,
1.598000e-03f, 1.432000e-03f, 1.270000e-03f, 1.111000e-03f, 9.570000e-04f, 8.070000e-04f, 6.620000e-04f,
5.220000e-04f, 3.880000e-04f, 2.600000e-04f, 1.370000e-04f, 2.100000e-05f, -8.800000e-05f, -1.920000e-04f,
-2.880000e-04f, -3.790000e-04f, -4.630000e-04f, -5.390000e-04f, -6.100000e-04f, -6.740000e-04f, -7.320000e-04f,
-7.840000e-04f, -8.290000e-04f, -8.690000e-04f, -9.030000e-04f, -9.310000e-04f, -9.540000e-04f, 9.710000e-04f,
9.840000e-04f, 9.920000e-04f, 9.950000e-04f, 9.940000e-04f, 9.890000e-04f, 9.810000e-04f, 9.690000e-04f,
9.540000e-04f, 9.360000e-04f, 9.150000e-04f, 8.920000e-04f, 8.660000e-04f, 8.390000e-04f, 8.100000e-04f,
7.790000e-04f, 7.470000e-04f, 7.140000e-04f, 6.810000e-04f, 6.470000e-04f, 6.120000e-04f, 5.770000e-04f,
5.420000e-04f, 5.070000e-04f, 4.730000e-04f, 4.380000e-04f, 4.040000e-04f, 3.710000e-04f, 3.390000e-04f,
3.080000e-04f, 2.770000e-04f, 2.470000e-04f, 2.190000e-04f, 1.910000e-04f, 1.650000e-04f, 1.400000e-04f,
1.160000e-04f, 9.400000e-05f, 7.300000e-05f, 5.300000e-05f, 3.400000e-05f, 1.700000e-05f, 1.000000e-06f,
-1.400000e-05f, -2.700000e-05f, -4.000000e-05f, -5.100000e-05f, -6.100000e-05f, -7.000000e-05f, -7.800000e-05f,
-8.400000e-05f, -9.000000e-05f, -9.500000e-05f, -9.900000e-05f, -1.030000e-04f, -1.050000e-04f, -1.070000e-04f,
-1.080000e-04f, -1.090000e-04f, -1.090000e-04f, -1.080000e-04f, -1.070000e-04f, -1.060000e-04f, -1.040000e-04f,
1.020000e-04f, 9.900000e-05f, 9.600000e-05f, 9.300000e-05f, 9.100000e-05f, 8.700000e-05f, 8.400000e-05f,
8.100000e-05f, 7.700000e-05f, 7.300000e-05f, 7.000000e-05f, 6.600000e-05f, 6.300000e-05f, 6.000000e-05f,
5.600000e-05f, 5.300000e-05f, 5.000000e-05f, 4.600000e-05f, 4.300000e-05f, 4.100000e-05f, 3.800000e-05f,
3.500000e-05f, 3.200000e-05f, 3.000000e-05f, 2.800000e-05f, 2.500000e-05f, 2.300000e-05f, 2.100000e-05f,
2.000000e-05f, 1.800000e-05f, 1.700000e-05f, 1.500000e-05f, 1.400000e-05f, 1.200000e-05f, 1.100000e-05f,
1.000000e-05f, 9.000000e-06f, 8.000000e-06f, 8.000000e-06f, 7.000000e-06f, 6.000000e-06f, 5.000000e-06f,
5.000000e-06f, 4.000000e-06f, 4.000000e-06f, 3.000000e-06f, 3.000000e-06f, 3.000000e-06f, 2.000000e-06f,
2.000000e-06f, 2.000000e-06f, 2.000000e-06f, 1.000000e-06f, 1.000000e-06f, 1.000000e-06f, 1.000000e-06f,
1.000000e-06f, 1.000000e-06f, 0.000000e+00f, 0.000000e+00f, 0.000000e+00f, 0.000000e+00f, 0.000000e+00f,
0.000000e+00f
};
// Huffman encoder tables (generated from minimp3 CC0 decoder trees)
// See gen_huff_enc.c for the generator source.
static const uint8_t mp3enc_linbits[32] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 2, 3, 4, 6, 8, 10, 13, 4, 5, 6, 7, 8, 9, 11, 13 };
static const uint16_t mp3enc_hcode_1[2][2] = {
{ 0x1, 0x1 },
{ 0x1, 0x0 }
};
static const uint8_t mp3enc_hlen_1[2][2] = {
{ 1, 2 },
{ 3, 3 }
};
static const uint16_t mp3enc_hcode_2[3][3] = {
{ 0x1, 0x3, 0x3 },
{ 0x2, 0x1, 0x2 },
{ 0x1, 0x1, 0x0 }
};
static const uint8_t mp3enc_hlen_2[3][3] = {
{ 1, 3, 5 },
{ 3, 3, 5 },
{ 6, 5, 6 }
};
static const uint16_t mp3enc_hcode_3[3][3] = {
{ 0x3, 0x1, 0x3 },
{ 0x2, 0x1, 0x2 },
{ 0x1, 0x1, 0x0 }
};
static const uint8_t mp3enc_hlen_3[3][3] = {
{ 2, 3, 5 },
{ 2, 2, 5 },
{ 6, 5, 6 }
};
static const uint16_t mp3enc_hcode_5[4][4] = {
{ 0x1, 0x3, 0x7, 0x6 },
{ 0x2, 0x1, 0x5, 0x1 },
{ 0x6, 0x4, 0x7, 0x1 },
{ 0x5, 0x4, 0x1, 0x0 }
};
static const uint8_t mp3enc_hlen_5[4][4] = {
{ 1, 3, 6, 7 },
{ 3, 3, 6, 6 },
{ 6, 6, 7, 7 },
{ 7, 7, 8, 8 }
};
static const uint16_t mp3enc_hcode_6[4][4] = {
{ 0x7, 0x6, 0x5, 0x3 },
{ 0x3, 0x2, 0x4, 0x3 },
{ 0x5, 0x3, 0x4, 0x2 },
{ 0x1, 0x2, 0x1, 0x0 }
};
static const uint8_t mp3enc_hlen_6[4][4] = {
{ 3, 3, 4, 6 },
{ 3, 2, 4, 5 },
{ 5, 4, 5, 6 },
{ 7, 5, 6, 7 }
};
static const uint16_t mp3enc_hcode_7[6][6] = {
{ 0x1, 0x3, 0xb, 0xc, 0x7, 0x6 },
{ 0x2, 0x3, 0x4, 0xb, 0x6, 0x4 },
{ 0xa, 0x7, 0xd, 0x12, 0x9, 0x5 },
{ 0x13, 0xa, 0x11, 0xf, 0xe, 0x3 },
{ 0x10, 0x5, 0x8, 0xb, 0x3, 0x2 },
{ 0xa, 0x3, 0x4, 0x2, 0x1, 0x0 }
};
static const uint8_t mp3enc_hlen_7[6][6] = {
{ 1, 3, 6, 7, 7, 8 },
{ 3, 4, 5, 7, 7, 8 },
{ 6, 6, 7, 8, 8, 9 },
{ 8, 7, 8, 9, 9, 10 },
{ 8, 7, 8, 9, 9, 10 },
{ 9, 8, 9, 9, 10, 10 }
};
static const uint16_t mp3enc_hcode_8[6][6] = {
{ 0x3, 0x5, 0x7, 0x13, 0xd, 0xc },
{ 0x4, 0x1, 0x3, 0x11, 0x5, 0x4 },
{ 0x6, 0x2, 0x5, 0xf, 0x8, 0x4 },
{ 0x12, 0x10, 0xe, 0xd, 0xb, 0x1 },
{ 0xc, 0x9, 0x7, 0xa, 0x5, 0x1 },
{ 0x5, 0x3, 0x3, 0x4, 0x1, 0x0 }
};
static const uint8_t mp3enc_hlen_8[6][6] = {
{ 2, 3, 6, 8, 8, 9 },
{ 3, 2, 4, 8, 7, 8 },
{ 6, 4, 6, 8, 8, 9 },
{ 8, 8, 8, 9, 9, 9 },
{ 8, 8, 8, 9, 10, 11 },
{ 9, 8, 9, 10, 10, 11 }
};
static const uint16_t mp3enc_hcode_9[6][6] = {
{ 0x7, 0x6, 0x7, 0xf, 0xb, 0xe },
{ 0x5, 0x4, 0x6, 0x6, 0x7, 0x4 },
{ 0x9, 0x5, 0x8, 0x9, 0x9, 0x6 },
{ 0xe, 0x5, 0x8, 0xa, 0x6, 0x2 },
{ 0xf, 0x6, 0x8, 0x5, 0x4, 0x6 },
{ 0x7, 0x7, 0x5, 0x1, 0x1, 0x0 }
};
static const uint8_t mp3enc_hlen_9[6][6] = {
{ 3, 3, 4, 6, 7, 8 },
{ 3, 3, 4, 5, 6, 7 },
{ 5, 4, 5, 6, 7, 8 },
{ 6, 5, 6, 7, 7, 8 },
{ 8, 6, 7, 7, 8, 9 },
{ 9, 8, 8, 8, 9, 9 }
};
static const uint16_t mp3enc_hcode_10[8][8] = {
{ 0x1, 0x3, 0xb, 0xe, 0x14, 0x1f, 0xe, 0x9 },
{ 0x2, 0x3, 0x9, 0xd, 0x13, 0x16, 0xd, 0x8 },
{ 0xa, 0x8, 0xf, 0x16, 0x21, 0x29, 0xa, 0x7 },
{ 0x17, 0xc, 0x15, 0x22, 0x2f, 0x1a, 0xb, 0x8 },
{ 0x23, 0x12, 0x20, 0x2e, 0x1b, 0x15, 0x10, 0x4 },
{ 0x1e, 0x15, 0x28, 0x17, 0x16, 0x14, 0x6, 0x4 },
{ 0xc, 0xc, 0x13, 0x12, 0x9, 0x5, 0x5, 0x2 },
{ 0x11, 0x7, 0x6, 0x7, 0x3, 0x3, 0x1, 0x0 }
};
static const uint8_t mp3enc_hlen_10[8][8] = {
{ 1, 3, 6, 7, 8, 9, 8, 9 },
{ 3, 4, 6, 7, 8, 9, 8, 8 },
{ 6, 6, 7, 8, 9, 10, 9, 9 },
{ 8, 7, 8, 9, 10, 10, 10, 10 },
{ 9, 8, 9, 10, 10, 11, 10, 10 },
{ 9, 9, 10, 10, 10, 11, 10, 11 },
{ 9, 8, 9, 9, 10, 10, 11, 11 },
{ 10, 8, 9, 10, 10, 11, 11, 11 }
};
static const uint16_t mp3enc_hcode_11[8][8] = {
{ 0x3, 0x5, 0xb, 0x19, 0x23, 0x1c, 0xe, 0xb },
{ 0x4, 0x3, 0x7, 0xb, 0x21, 0x1a, 0xc, 0x4 },
{ 0xa, 0x4, 0xd, 0x13, 0x1f, 0x20, 0x9, 0x6 },
{ 0x18, 0xa, 0x12, 0x3b, 0x3a, 0x13, 0xd, 0x6 },
{ 0x22, 0x20, 0x1e, 0x1b, 0x1e, 0x11, 0xe, 0x6 },
{ 0x21, 0x11, 0x1f, 0x12, 0x10, 0xf, 0x9, 0x3 },
{ 0x15, 0xb, 0x14, 0xc, 0x7, 0x8, 0x4, 0x2 },
{ 0xf, 0xa, 0x5, 0x5, 0x5, 0xe, 0x1, 0x0 }
};
static const uint8_t mp3enc_hlen_11[8][8] = {
{ 2, 3, 5, 7, 8, 8, 8, 8 },
{ 3, 3, 5, 6, 8, 8, 7, 7 },
{ 5, 4, 6, 7, 8, 9, 7, 8 },
{ 7, 6, 7, 9, 9, 10, 8, 9 },
{ 8, 8, 8, 8, 9, 10, 9, 10 },
{ 9, 8, 9, 10, 10, 11, 10, 10 },
{ 8, 7, 8, 8, 9, 10, 10, 10 },
{ 9, 8, 8, 9, 10, 11, 10, 10 }
};
static const uint16_t mp3enc_hcode_12[8][8] = {
{ 0x9, 0x7, 0x11, 0x11, 0x20, 0x28, 0x1b, 0x1b },
{ 0x6, 0x5, 0x7, 0xa, 0xd, 0x11, 0xc, 0xc },
{ 0x10, 0x6, 0xb, 0xf, 0x16, 0x1f, 0xb, 0x8 },
{ 0x21, 0x9, 0xe, 0xc, 0x13, 0x1d, 0xf, 0xc },
{ 0x29, 0x17, 0x15, 0x12, 0x12, 0x11, 0xa, 0x6 },
{ 0x27, 0x10, 0x1e, 0x1c, 0x10, 0xd, 0x7, 0x3 },
{ 0x26, 0x1a, 0xa, 0xe, 0x9, 0x4, 0x4, 0x1 },
{ 0x1a, 0xb, 0x7, 0x5, 0x5, 0x2, 0x1, 0x0 }
};
static const uint8_t mp3enc_hlen_12[8][8] = {
{ 4, 3, 5, 6, 7, 8, 8, 9 },
{ 3, 3, 4, 5, 6, 7, 7, 8 },
{ 5, 4, 5, 6, 7, 8, 7, 8 },
{ 7, 5, 6, 6, 7, 8, 8, 9 },
{ 8, 7, 7, 7, 8, 8, 8, 9 },
{ 9, 7, 8, 8, 8, 9, 9, 9 },
{ 9, 8, 7, 8, 8, 8, 9, 9 },
{ 9, 8, 8, 8, 9, 9, 10, 10 }
};
static const uint16_t mp3enc_hcode_13[16][16] = {
{ 0x1, 0x3, 0xf, 0x16, 0x23, 0x3a, 0x2f, 0x48, 0x2b, 0x35, 0x23, 0x35, 0x22, 0x2d, 0x30, 0x10 },
{ 0x5, 0x4, 0xd, 0x14, 0x10, 0x1b, 0x2d, 0x22, 0x14, 0x19, 0x21, 0x19, 0x20, 0x15, 0x17, 0xf },
{ 0xe, 0xc, 0x17, 0x25, 0x3c, 0x32, 0x4e, 0x38, 0x1e, 0x29, 0x1f, 0x17, 0x1c, 0x22, 0x14, 0x11 },
{ 0x15, 0x13, 0x24, 0x3d, 0x39, 0x60, 0x4a, 0x5f, 0x2c, 0x25, 0x39, 0x26, 0x27, 0x40, 0x27, 0x1b },
{ 0x22, 0x1f, 0x3b, 0x38, 0x61, 0x4c, 0x73, 0x5c, 0x37, 0x2c, 0x2a, 0x46, 0x31, 0x38, 0x24, 0x19 },
{ 0x33, 0x1a, 0x31, 0x4f, 0x4b, 0x46, 0x5e, 0x55, 0x4e, 0x3b, 0x52, 0x3c, 0x4b, 0x32, 0x23, 0x14 },
{ 0x2e, 0x2c, 0x4d, 0x49, 0x72, 0x5d, 0x5a, 0x5b, 0x48, 0x36, 0x48, 0x33, 0x1e, 0x31, 0x35, 0x1d },
{ 0x47, 0x21, 0x41, 0x40, 0x5b, 0x54, 0x4f, 0x5a, 0x57, 0x51, 0x50, 0x24, 0x34, 0x2d, 0x15, 0xb },
{ 0x2a, 0x1f, 0x1d, 0x2b, 0x36, 0x4d, 0x45, 0x56, 0x4e, 0x42, 0x2f, 0x37, 0x30, 0x1f, 0x10, 0x11 },
{ 0x34, 0x18, 0x28, 0x4c, 0x49, 0x3a, 0x53, 0x49, 0x3d, 0x4c, 0x3a, 0x1a, 0x28, 0x13, 0x17, 0xc },
{ 0x44, 0x20, 0x1e, 0x38, 0x37, 0x4f, 0x47, 0x4d, 0x2e, 0x39, 0x37, 0x22, 0x34, 0xc, 0xd, 0x10 },
{ 0x34, 0x18, 0x28, 0x25, 0x29, 0x1d, 0x32, 0x41, 0x36, 0x36, 0x15, 0x17, 0x1c, 0xf, 0xa, 0x8 },
{ 0x43, 0x1f, 0x1b, 0x1a, 0x30, 0x4a, 0x3b, 0x33, 0x25, 0x25, 0x16, 0x1b, 0x12, 0xa, 0x6, 0x1 },
{ 0x2c, 0x23, 0x21, 0x1f, 0x35, 0x31, 0x26, 0x2c, 0x1e, 0x12, 0x1a, 0xe, 0x11, 0x7, 0x1, 0x1 },
{ 0x2b, 0x16, 0x2a, 0x19, 0x17, 0x29, 0x24, 0x2b, 0x14, 0x27, 0x26, 0x9, 0x9, 0x6, 0x4, 0x0 },
{ 0x13, 0xe, 0x10, 0xe, 0x18, 0x11, 0xf, 0x2a, 0x10, 0xb, 0x16, 0x7, 0x5, 0x3, 0x2, 0x1 }
};
static const uint8_t mp3enc_hlen_13[16][16] = {
{ 1, 3, 6, 7, 8, 9, 9, 10, 9, 10, 10, 11, 11, 12, 13, 12 },
{ 4, 4, 6, 7, 7, 8, 9, 9, 8, 9, 10, 10, 11, 11, 12, 12 },
{ 6, 6, 7, 8, 9, 9, 10, 10, 9, 10, 10, 10, 11, 12, 12, 13 },
{ 7, 7, 8, 9, 9, 10, 10, 11, 10, 10, 11, 11, 12, 13, 13, 14 },
{ 8, 8, 9, 9, 10, 10, 11, 11, 10, 11, 11, 12, 12, 13, 13, 14 },
{ 9, 8, 9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 13, 13, 13, 14 },
{ 9, 9, 10, 10, 11, 11, 11, 12, 11, 11, 12, 12, 12, 14, 15, 15 },
{ 10, 9, 10, 10, 11, 11, 11, 12, 12, 13, 13, 12, 13, 14, 14, 14 },
{ 9, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 13, 14, 14, 14, 15 },
{ 10, 9, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 17, 15 },
{ 11, 10, 10, 11, 11, 12, 12, 13, 12, 13, 14, 13, 15, 14, 15, 16 },
{ 11, 10, 11, 11, 12, 11, 12, 13, 13, 14, 13, 14, 15, 15, 15, 16 },
{ 12, 11, 11, 11, 12, 13, 13, 13, 13, 14, 14, 15, 15, 16, 15, 19 },
{ 12, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 16, 15, 17, 18 },
{ 13, 12, 13, 13, 13, 14, 14, 16, 15, 16, 16, 15, 16, 16, 16, 19 },
{ 13, 12, 13, 13, 14, 14, 14, 16, 15, 15, 17, 16, 16, 16, 16, 16 }
};
static const uint16_t mp3enc_hcode_15[16][16] = {
{ 0x7, 0xd, 0x13, 0x1d, 0x34, 0x4d, 0x7d, 0x6d, 0x5a, 0x47, 0x6d, 0x56, 0x76, 0x5b, 0x7b, 0x47 },
{ 0xc, 0x5, 0x11, 0x1c, 0x16, 0x25, 0x20, 0x35, 0x2b, 0x22, 0x35, 0x2a, 0x44, 0x2c, 0x3c, 0x25 },
{ 0x12, 0x10, 0xf, 0x19, 0x2a, 0x23, 0x3c, 0x31, 0x29, 0x43, 0x33, 0x28, 0x1e, 0x27, 0x3a, 0x22 },
{ 0x35, 0x1b, 0x18, 0x2b, 0x28, 0x42, 0x38, 0x5e, 0x4d, 0x3c, 0x2f, 0x25, 0x37, 0x26, 0x35, 0x1e },
{ 0x2f, 0x2e, 0x29, 0x27, 0x43, 0x3a, 0x32, 0x58, 0x49, 0x3a, 0x5a, 0x46, 0x32, 0x22, 0x2f, 0x1c },
{ 0x4c, 0x24, 0x22, 0x3f, 0x39, 0x34, 0x5c, 0x4b, 0x3f, 0x31, 0x52, 0x40, 0x2e, 0x3f, 0x2b, 0x14 },
{ 0x7c, 0x3d, 0x3b, 0x37, 0x5f, 0x5b, 0x4e, 0x42, 0x38, 0x58, 0x3a, 0x34, 0x4a, 0x34, 0x20, 0x11 },
{ 0x6c, 0x33, 0x30, 0x5d, 0x4f, 0x4a, 0x41, 0x7a, 0x5c, 0x4c, 0x39, 0x2b, 0x41, 0x2d, 0x16, 0x1a },
{ 0x59, 0x2a, 0x28, 0x4c, 0x48, 0x3e, 0x37, 0x5b, 0x4d, 0x43, 0x30, 0x46, 0x31, 0x1f, 0x25, 0x15 },
{ 0x7b, 0x46, 0x40, 0x3b, 0x39, 0x30, 0x57, 0x49, 0x42, 0x6a, 0x48, 0x37, 0x27, 0x34, 0x18, 0x10 },
{ 0x6c, 0x34, 0x32, 0x5d, 0x59, 0x4f, 0x47, 0x38, 0x2f, 0x47, 0x39, 0x2a, 0x18, 0x1c, 0x11, 0xa },
{ 0x77, 0x53, 0x4e, 0x48, 0x45, 0x3f, 0x33, 0x2a, 0x43, 0x36, 0x29, 0x19, 0x10, 0x13, 0xc, 0x6 },
{ 0x6b, 0x41, 0x3e, 0x36, 0x31, 0x5a, 0x49, 0x40, 0x30, 0x26, 0x17, 0x1d, 0x16, 0xe, 0xf, 0x8 },
{ 0x51, 0x29, 0x50, 0x4b, 0x42, 0x3e, 0x33, 0x2c, 0x35, 0x27, 0x1b, 0x12, 0xd, 0x8, 0xa, 0x6 },
{ 0x7a, 0x3b, 0x38, 0x32, 0x2e, 0x28, 0x46, 0x15, 0x24, 0x17, 0x3e, 0xb, 0xe, 0x9, 0x2, 0x2 },
{ 0x3f, 0x24, 0x21, 0x1d, 0x1b, 0x26, 0x1e, 0x19, 0x14, 0xf, 0x9, 0xb, 0x7, 0x3, 0x1, 0x0 }
};
static const uint8_t mp3enc_hlen_15[16][16] = {
{ 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 10, 10, 11, 11, 12, 12 },
{ 4, 3, 5, 6, 6, 7, 7, 8, 8, 8, 9, 9, 10, 10, 11, 11 },
{ 5, 5, 5, 6, 7, 7, 8, 8, 8, 9, 9, 9, 9, 10, 11, 11 },
{ 7, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9, 9, 10, 10, 11, 11 },
{ 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11 },
{ 8, 7, 7, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 11, 11, 11 },
{ 9, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 11, 11, 11, 11 },
{ 9, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 12 },
{ 9, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 12, 12 },
{ 10, 9, 9, 9, 9, 9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12 },
{ 10, 9, 9, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12 },
{ 11, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 12, 12, 12 },
{ 11, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 12, 12, 12, 13, 13 },
{ 11, 10, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13, 13 },
{ 12, 11, 11, 11, 11, 11, 12, 11, 12, 12, 13, 12, 13, 13, 12, 13 },
{ 13, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13 }
};
static const uint16_t mp3enc_hcode_16[16][16] = {
{ 0x1, 0x3, 0xf, 0x2d, 0x4b, 0x42, 0x6f, 0x62, 0x55, 0x9a, 0x8b, 0xf3, 0xca, 0x2eb, 0x179, 0xc },
{ 0x5, 0x4, 0xd, 0x15, 0x24, 0x1e, 0x36, 0x30, 0x54, 0x4c, 0x81, 0x78, 0xe0, 0xd3, 0x171, 0xa },
{ 0xe, 0xc, 0x17, 0x27, 0x44, 0x3b, 0x34, 0x5b, 0x51, 0x49, 0x43, 0x76, 0xde, 0xd2, 0x66, 0x7 },
{ 0x2c, 0x14, 0x26, 0x45, 0x41, 0x38, 0x64, 0x58, 0x9f, 0x8d, 0x7d, 0x73, 0xda, 0xd0, 0xbb, 0xb },
{ 0x4a, 0x23, 0x43, 0x40, 0x73, 0x66, 0xb8, 0xa5, 0x9c, 0x83, 0xf7, 0xe3, 0xd8, 0x172, 0x2d6, 0xa },
{ 0x3f, 0x3e, 0x3a, 0x72, 0x65, 0xb9, 0xb2, 0x9d, 0x8f, 0x100, 0xe9, 0xdf, 0x185, 0x17b, 0x2d2, 0x11 },
{ 0x6e, 0x35, 0x67, 0x63, 0xb3, 0xad, 0xa0, 0x94, 0x104, 0xf5, 0xe5, 0x18c, 0x182, 0x2de, 0x166, 0xb },
{ 0x5d, 0x2f, 0x5a, 0x57, 0xa4, 0x109, 0x85, 0x105, 0xf9, 0x1aa, 0xdb, 0x2ea, 0x17d, 0x2d3, 0x2c7, 0x9 },
{ 0xac, 0x53, 0xa1, 0x9e, 0x9b, 0x8e, 0x101, 0xf8, 0x1ab, 0x196, 0x189, 0x2e6, 0x16c, 0x2ca, 0x2c5, 0xd },
{ 0x95, 0x4b, 0x48, 0x8c, 0x108, 0xfd, 0xf4, 0x197, 0x191, 0x18a, 0x2e7, 0x2e0, 0x378, 0x6c7, 0x362, 0xc },
{ 0x8a, 0x44, 0x7f, 0xfc, 0xf6, 0xe8, 0xe4, 0x18d, 0x188, 0x180, 0x2e1, 0x2d1, 0x1bb, 0x373, 0x6c6, 0xa },
{ 0xf2, 0x77, 0x75, 0xd4, 0xe2, 0x190, 0xd9, 0x174, 0x17f, 0x2df, 0x2d0, 0x2c8, 0x2c3, 0x36d, 0x367, 0x7 },
{ 0xe1, 0xc9, 0x6e, 0xc7, 0x18b, 0x184, 0x181, 0x17c, 0x2d7, 0x167, 0x375, 0x2c2, 0x1b8, 0x36c, 0xd82, 0x5 },
{ 0xc3, 0x6b, 0xd1, 0x183, 0x17e, 0x17a, 0x16e, 0x379, 0x2c9, 0x2c6, 0x372, 0xdf, 0x1b5, 0xd83, 0x366, 0x3 },
{ 0x178, 0xcf, 0xce, 0x16d, 0x16a, 0x1bd, 0x2cb, 0x374, 0x2c4, 0x160, 0x1b7, 0x1b4, 0x6c0, 0x361, 0x1b2, 0x1 },
{ 0x11, 0x9, 0x10, 0x1a, 0x9, 0x10, 0xa, 0x8, 0x7, 0xb, 0x4, 0x6, 0x4, 0x2, 0x0, 0x3 }
};
static const uint8_t mp3enc_hlen_16[16][16] = {
{ 1, 3, 6, 8, 9, 9, 10, 10, 10, 11, 11, 12, 12, 14, 13, 9 },
{ 4, 4, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 8 },
{ 6, 6, 7, 8, 9, 9, 9, 10, 10, 10, 10, 11, 12, 12, 11, 8 },
{ 8, 7, 8, 9, 9, 9, 10, 10, 11, 11, 11, 11, 12, 12, 12, 9 },
{ 9, 8, 9, 9, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 14, 9 },
{ 9, 9, 9, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 14, 10 },
{ 10, 9, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 14, 13, 10 },
{ 10, 9, 10, 10, 11, 12, 11, 12, 12, 13, 12, 14, 13, 14, 14, 10 },
{ 11, 10, 11, 11, 11, 11, 12, 12, 13, 13, 13, 14, 13, 14, 14, 11 },
{ 11, 10, 10, 11, 12, 12, 12, 13, 13, 13, 14, 14, 15, 16, 15, 11 },
{ 11, 10, 11, 12, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 16, 11 },
{ 12, 11, 11, 12, 12, 13, 12, 13, 13, 14, 14, 14, 14, 15, 15, 11 },
{ 12, 12, 11, 12, 13, 13, 13, 13, 14, 13, 15, 14, 14, 15, 17, 11 },
{ 12, 11, 12, 13, 13, 13, 13, 15, 14, 14, 15, 13, 14, 17, 15, 11 },
{ 13, 12, 12, 13, 13, 14, 14, 15, 14, 13, 14, 14, 16, 15, 14, 11 },
{ 9, 8, 9, 10, 9, 10, 10, 10, 10, 11, 10, 11, 11, 11, 11, 8 }
};
static const uint16_t mp3enc_hcode_24[16][16] = {
{ 0xf, 0xe, 0x2f, 0x51, 0x93, 0x107, 0xf9, 0x1b3, 0x1ab, 0x14f, 0x29c, 0x28c, 0x288, 0x26c, 0x409, 0x2b },
{ 0xd, 0xc, 0x16, 0x27, 0x48, 0x42, 0x7b, 0x73, 0xd4, 0xc7, 0xb8, 0x15a, 0x142, 0x12c, 0x118, 0x14 },
{ 0x2e, 0x15, 0x29, 0x4b, 0x45, 0x81, 0x79, 0x6f, 0xd0, 0xc5, 0xb7, 0xab, 0x13c, 0x128, 0x116, 0x13 },
{ 0x50, 0x26, 0x4a, 0x46, 0x87, 0x7e, 0x75, 0x6d, 0xcd, 0xbf, 0xb3, 0xa8, 0x138, 0x126, 0x112, 0x11 },
{ 0x92, 0x47, 0x44, 0x86, 0x7f, 0x77, 0x71, 0xd3, 0xc9, 0xbd, 0xaf, 0xa4, 0x133, 0x120, 0x10b, 0xf },
{ 0x106, 0x82, 0x80, 0x7d, 0x76, 0x72, 0xd7, 0xcb, 0xc1, 0xb5, 0x158, 0x13e, 0x12e, 0x11a, 0x108, 0xd },
{ 0xf8, 0x7a, 0x78, 0x74, 0x70, 0xd6, 0xce, 0xc4, 0xba, 0xae, 0x14b, 0x135, 0x124, 0x111, 0x103, 0xb },
{ 0x1b2, 0xd8, 0xdd, 0xdc, 0xd2, 0xca, 0xc3, 0xbb, 0xb1, 0x14d, 0x13a, 0x12b, 0x11c, 0x10a, 0x17e, 0x9 },
{ 0x1aa, 0xd1, 0xcf, 0xcc, 0xc8, 0xc0, 0xb9, 0x161, 0xa9, 0x141, 0x130, 0x11f, 0x10d, 0x203, 0x17a, 0x7 },
{ 0x29d, 0xc6, 0xc2, 0xbe, 0xbc, 0xb4, 0x15b, 0x14c, 0x140, 0x131, 0x122, 0x114, 0x105, 0x17c, 0x174, 0x6 },
{ 0x28d, 0x147, 0xb6, 0xb2, 0x160, 0x155, 0x14a, 0x139, 0x12f, 0x121, 0x115, 0x107, 0x200, 0x176, 0x16f, 0x4 },
{ 0x289, 0x159, 0x154, 0x145, 0x143, 0x13d, 0x134, 0x12a, 0x11e, 0x113, 0x212, 0x201, 0x178, 0x171, 0x16b, 0x7 },
{ 0x26d, 0x13f, 0x13b, 0x137, 0x132, 0x12d, 0x123, 0x11b, 0x10c, 0x209, 0x17f, 0x177, 0x172, 0x16d, 0x168, 0x5 },
{ 0x205, 0x129, 0x127, 0x125, 0x11d, 0x119, 0x110, 0x213, 0x202, 0x17b, 0x175, 0x170, 0x16c, 0x169, 0x166, 0x3 },
{ 0x408, 0x117, 0x21d, 0x10f, 0x21c, 0x106, 0x208, 0x17d, 0x179, 0x173, 0x16e, 0x16a, 0x167, 0x165, 0x164, 0x1 },
{ 0x58, 0x2a, 0x12, 0x10, 0xe, 0xc, 0xa, 0x11, 0x10, 0xb, 0xa, 0x6, 0x4, 0x2, 0x0, 0x3 }
};
static const uint8_t mp3enc_hlen_24[16][16] = {
{ 4, 4, 6, 7, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11, 12, 8 },
{ 4, 4, 5, 6, 7, 7, 8, 8, 9, 9, 9, 10, 10, 10, 10, 7 },
{ 6, 5, 6, 7, 7, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 7 },
{ 7, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 7 },
{ 8, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 7 },
{ 9, 8, 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 7 },
{ 9, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 7 },
{ 10, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 7 },
{ 10, 9, 9, 9, 9, 9, 9, 10, 9, 10, 10, 10, 10, 11, 11, 7 },
{ 11, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 11, 11, 7 },
{ 11, 10, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 7 },
{ 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 8 },
{ 11, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 8 },
{ 11, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 8 },
{ 12, 10, 11, 10, 11, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 8 },
{ 9, 8, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 4 }
};
static const uint8_t mp3enc_count1a_code[16] = { 1, 5, 4, 5, 6, 5, 4, 4, 7, 3, 6, 0, 7, 2, 3, 1 };
static const uint8_t mp3enc_count1a_len[16] = { 1, 4, 4, 5, 4, 6, 5, 6, 4, 5, 5, 6, 5, 6, 6, 6 };
static const uint8_t mp3enc_count1b_code[16] = { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
static const uint8_t mp3enc_count1b_len[16] = { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 };
+591
View File
@@ -0,0 +1,591 @@
#pragma once
// mp3enc.h
// MPEG1 Layer III MP3 encoder, CBR, 32/44.1/48 kHz, mono/stereo.
// MIT license.
//
// Usage:
// mp3enc_t * enc = mp3enc_init(44100, 2, 128);
// while (have_audio) {
// const uint8_t * mp3 = mp3enc_encode(enc, pcm, samples, &size);
// fwrite(mp3, 1, size, fp);
// }
// const uint8_t * mp3 = mp3enc_flush(enc, &size);
// fwrite(mp3, 1, size, fp);
// mp3enc_free(enc);
//
// PCM input: planar float [ch0: N samples] [ch1: N samples]
// Output: raw MP3 frames (no ID3 tags)
//
// MIT license.
// clang-format off
// Order matters: tables.h defines constants used by all other headers.
#include "mp3enc-tables.h"
#include "mp3enc-bits.h"
#include "mp3enc-filter.h"
#include "mp3enc-huff.h"
#include "mp3enc-mdct.h"
#include "mp3enc-psy.h"
#include "mp3enc-quant.h"
// clang-format on
#include <cstdlib>
#include <cstring>
// Encoder state.
struct mp3enc_t {
// Config
int sample_rate;
int channels;
int bitrate_kbps;
int sr_index; // 0=44100, 1=48000, 2=32000
// Frame geometry
int frame_samples; // always 1152 for MPEG1 Layer III
int slots_per_frame; // frame size in bytes (varies with padding)
// Per channel state
mp3enc_filter filter[2]; // analysis filterbank
float sb_prev[2][32][18]; // subband overlap memory
float sb_cur[2][32][18]; // current granule subbands
mp3enc_psy psy; // psychoacoustic model
// Bit reservoir (ISO 11172-3, clause 2.4.2.7).
// Tracks unused bits from previous frames that can be borrowed.
int resv_size; // current reservoir size in bits
int resv_max; // max: 511 bytes * 8 = 4088 bits
// Adaptive lowpass: MDCT line index above which coefficients are zeroed.
// Saves bits at low bitrates by not encoding inaudible HF content.
int lowpass_line;
// PCM input buffer (accumulates until we have 1152 samples)
float * pcm_buf; // interleaved buffer: [ch0_1152][ch1_1152]
int pcm_fill; // samples accumulated per channel
// Output buffer (holds accumulated MP3 frames for one encode call)
uint8_t * out_buf;
int out_capacity;
int out_written;
// Scratch buffer for one frame (max ~1441 bytes at 320kbps/32kHz)
uint8_t frame_buf[2048];
// Main data scratch: written separately from header+sideinfo for reservoir
uint8_t md_scratch[2048];
// Pending frame: we delay output by one frame so we can write the next
// frame's main_data overflow into the current frame's unused tail.
// This is how the bit reservoir works (ISO 11172-3 clause 2.4.2.7).
uint8_t pending_frame[2048];
int pending_bytes; // size of pending frame (0 = no pending frame)
int pending_md_end; // byte offset where main_data ends in pending_frame
// Padding state (for 44100 Hz which needs alternating padding)
int pad_remainder;
};
// Initialize encoder.
static mp3enc_t * mp3enc_init(int sample_rate, int channels, int bitrate_kbps) {
mp3enc_t * enc = (mp3enc_t *) calloc(1, sizeof(mp3enc_t));
if (!enc) {
return nullptr;
}
enc->sample_rate = sample_rate;
enc->channels = channels;
enc->bitrate_kbps = bitrate_kbps;
enc->frame_samples = 1152;
// Determine sample rate index
if (sample_rate == 44100) {
enc->sr_index = 0;
} else if (sample_rate == 48000) {
enc->sr_index = 1;
} else if (sample_rate == 32000) {
enc->sr_index = 2;
} else {
free(enc);
return nullptr;
}
// Init subsystems
for (int ch = 0; ch < channels; ch++) {
enc->filter[ch].init();
}
memset(enc->sb_prev, 0, sizeof(enc->sb_prev));
enc->psy.init();
enc->psy.init_ath(enc->sr_index, mp3enc_sfb_long[enc->sr_index], sample_rate);
// Bit reservoir: max 511 bytes (9 bit field main_data_begin)
enc->resv_size = 0;
enc->resv_max = 511 * 8;
// Adaptive lowpass: cut HF that wastes bits at low bitrates.
// Cutoff per total bitrate in Hz. Higher bitrates preserve more bandwidth.
{
static const struct {
int kbps;
int hz;
} lp_table[] = {
{ 8, 2000 },
{ 16, 3700 },
{ 24, 3900 },
{ 32, 5500 },
{ 40, 7000 },
{ 48, 7500 },
{ 56, 10000 },
{ 64, 11000 },
{ 80, 13500 },
{ 96, 15100 },
{ 112, 15600 },
{ 128, 17000 },
{ 160, 17500 },
{ 192, 18600 },
{ 224, 19400 },
{ 256, 19700 },
{ 320, 20500 }
};
static const int lp_count = (int) (sizeof(lp_table) / sizeof(lp_table[0]));
// Find nearest bitrate in table
int best = 0;
int best_dist = 999;
for (int i = 0; i < lp_count; i++) {
int dist = abs(bitrate_kbps - lp_table[i].kbps);
if (dist < best_dist) {
best_dist = dist;
best = i;
}
}
float cutoff_hz = (float) lp_table[best].hz;
// MDCT line corresponding to cutoff: 576 lines cover 0..samplerate/2
float freq_per_line = (float) sample_rate / (2.0f * 576.0f);
enc->lowpass_line = (int) (cutoff_hz / freq_per_line);
if (enc->lowpass_line > 576) {
enc->lowpass_line = 576;
}
}
// Allocate buffers
enc->pcm_buf = (float *) calloc(1152 * channels, sizeof(float));
enc->pcm_fill = 0;
enc->out_capacity = 2048;
enc->out_buf = (uint8_t *) malloc(enc->out_capacity);
enc->out_written = 0;
enc->pad_remainder = 0;
// No pending frame at start
enc->pending_bytes = 0;
enc->pending_md_end = 0;
return enc;
}
// Free encoder.
static void mp3enc_free(mp3enc_t * enc) {
if (!enc) {
return;
}
free(enc->pcm_buf);
free(enc->out_buf);
free(enc);
}
// Compute padding for this frame (needed at 44100 Hz).
static int mp3enc_get_padding(mp3enc_t * enc) {
int dif = (144 * enc->bitrate_kbps * 1000) % enc->sample_rate;
enc->pad_remainder -= dif;
if (enc->pad_remainder < 0) {
enc->pad_remainder += enc->sample_rate;
return 1;
}
return 0;
}
// Encode one complete frame (1152 samples per channel).
// pcm: planar float [ch0: 1152 samples][ch1: 1152 samples]
// Returns number of bytes written to enc->frame_buf.
static int mp3enc_encode_frame(mp3enc_t * enc, const float * pcm) {
int nch = enc->channels;
int padding = mp3enc_get_padding(enc);
// MS stereo decision is deferred until after MDCT energy analysis.
// mode=1 (joint) allows switching M/S on or off per frame.
// mode=0 (stereo) would force L/R always. mode=3 (mono).
int mode = (nch == 1) ? 3 : 1;
int mode_ext = 0; // set after MDCT energy analysis
// Setup header
mp3enc_header hdr;
hdr.bitrate_kbps = enc->bitrate_kbps;
hdr.samplerate = enc->sample_rate;
hdr.mode = mode;
hdr.mode_ext = mode_ext;
hdr.padding = padding;
int frame_bytes = hdr.frame_bytes();
int side_info_bytes = (nch == 1) ? 17 : 32;
int main_data_bytes = frame_bytes - 4 - side_info_bytes;
int main_data_bits = main_data_bytes * 8;
// SFB tables for this sample rate
const uint8_t * sfb_long = mp3enc_sfb_long[enc->sr_index];
// Process 2 granules (each is 576 samples = 18 subband slots of 32 samples)
mp3enc_side_info si;
memset(&si, 0, sizeof(si));
// Cross-frame bit reservoir (ISO 11172-3 clause 2.4.2.7).
// Unused bytes at the end of the previous frame can be borrowed by this frame.
// The pending_frame holds the previous frame; its unused tail is the reservoir.
int resv_bytes = 0;
if (enc->pending_bytes > 0) {
resv_bytes = enc->pending_bytes - enc->pending_md_end;
if (resv_bytes < 0) {
resv_bytes = 0;
}
if (resv_bytes > 511) {
resv_bytes = 511;
}
}
si.main_data_begin = resv_bytes;
// Total main_data bits: this frame's area + reservoir from previous frame
int total_md_bits = main_data_bits + resv_bytes * 8;
// Phase 1: compute MDCT + psy for ALL granules before bit allocation.
// We need PE from both granules to weight the bit budget.
float mdct_all[2][2][576]; // [granule][channel][576 MDCT lines]
float saved_xmin[2][2][MP3ENC_PSY_SFB_MAX];
float saved_pe[2] = { 0.0f, 0.0f };
// Accumulators for MS stereo decision
float energy_mid = 0.0f;
float energy_side = 0.0f;
for (int gr = 0; gr < 2; gr++) {
int pcm_offset = gr * 576;
// filterbank + MDCT for all channels
for (int ch = 0; ch < nch; ch++) {
const float * ch_pcm = pcm + ch * 1152 + pcm_offset;
float sb_out[32];
for (int slot = 0; slot < 18; slot++) {
enc->filter[ch].process(ch_pcm + slot * 32, sb_out);
for (int sb = 0; sb < 32; sb++) {
enc->sb_cur[ch][sb][slot] = sb_out[sb];
}
// frequency inversion: negate odd subbands at odd time slots
if (slot & 1) {
for (int sb = 1; sb < 32; sb += 2) {
enc->sb_cur[ch][sb][slot] = -enc->sb_cur[ch][sb][slot];
}
}
}
mp3enc_mdct_granule(enc->sb_prev[ch], enc->sb_cur[ch], mdct_all[gr][ch]);
memcpy(enc->sb_prev[ch], enc->sb_cur[ch], sizeof(enc->sb_cur[ch]));
}
// MS stereo energy analysis (before transform, on L/R data).
// Accumulate mid and side energy across both granules to decide
// whether M/S coding is beneficial for this frame.
// M/S wins when L and R are correlated (side energy is small).
if (nch == 2) {
for (int i = 0; i < enc->lowpass_line && i < 576; i++) {
float l = mdct_all[gr][0][i];
float r = mdct_all[gr][1][i];
float m = l + r;
float s = l - r;
energy_mid += m * m;
energy_side += s * s;
}
}
}
// MS stereo decision: use M/S when channels are correlated enough
// that the side channel is cheap to encode. FhG "almost always uses
// ms_stereo" (GPSYCHO docs). We use it unless side energy dominates,
// which means the channels are very different (rare for music).
bool use_ms = false;
if (nch == 2) {
// Use M/S unless side channel has more energy than mid.
// This is generous -- almost always enables M/S (like FhG).
use_ms = (energy_side < energy_mid * 1.2f) || (energy_mid < 1e-20f);
mode_ext = use_ms ? 2 : 0;
hdr.mode_ext = mode_ext;
}
// Now apply M/S transform + lowpass + psy for both granules
for (int gr = 0; gr < 2; gr++) {
// MS stereo transform
if (use_ms) {
static const float ms_scale = 0.7071067811865476f; // 1/sqrt(2)
for (int i = 0; i < 576; i++) {
float l = mdct_all[gr][0][i];
float r = mdct_all[gr][1][i];
mdct_all[gr][0][i] = (l + r) * ms_scale;
mdct_all[gr][1][i] = (l - r) * ms_scale;
}
}
// adaptive lowpass
for (int ch = 0; ch < nch; ch++) {
for (int i = enc->lowpass_line; i < 576; i++) {
mdct_all[gr][ch][i] = 0.0f;
}
}
// psy: compute masking thresholds and perceptual entropy
for (int ch = 0; ch < nch; ch++) {
enc->psy.compute(mdct_all[gr][ch], sfb_long, enc->sr_index, ch);
memcpy(saved_xmin[gr][ch], enc->psy.xmin, sizeof(enc->psy.xmin));
saved_pe[gr] += enc->psy.pe;
}
}
// Phase 2: PE-weighted bit allocation + quantization.
// Give more bits to granules with higher perceptual entropy (more complex
// signal). ISO 11172-3 computes PE but then ignores it for allocation;
// LAME uses it to drive the bit reservoir. We weight the per-granule
// budget proportionally to PE, clamped to avoid starving either granule.
int gr_budget[2];
float pe_sum = saved_pe[0] + saved_pe[1];
if (pe_sum > 1e-6f) {
float frac0 = saved_pe[0] / pe_sum;
gr_budget[0] = (int) ((float) total_md_bits * frac0);
gr_budget[1] = total_md_bits - gr_budget[0];
// clamp: neither granule gets less than 20% or more than 80%
int lo = total_md_bits / 5;
int hi = total_md_bits * 4 / 5;
for (int gr = 0; gr < 2; gr++) {
if (gr_budget[gr] < lo) {
gr_budget[gr] = lo;
}
if (gr_budget[gr] > hi) {
gr_budget[gr] = hi;
}
}
// re-normalize after clamp
int clamped_sum = gr_budget[0] + gr_budget[1];
int bits_to_spread = total_md_bits - clamped_sum;
gr_budget[0] += bits_to_spread / 2;
gr_budget[1] += bits_to_spread - bits_to_spread / 2;
} else {
gr_budget[0] = total_md_bits / 2;
gr_budget[1] = total_md_bits - gr_budget[0];
}
int ix[2][2][576];
int total_bits_used = 0;
int intra_resv = 0;
for (int gr = 0; gr < 2; gr++) {
int max_bits = gr_budget[gr] + intra_resv;
// don't exceed remaining budget
int remaining_bits = total_md_bits - total_bits_used;
if (max_bits > remaining_bits) {
max_bits = remaining_bits;
}
if (max_bits > 4095 * nch) {
max_bits = 4095 * nch;
}
int bits_per_ch = max_bits / nch;
// quantize each channel with psy thresholds
int gr_bits_used = 0;
for (int ch = 0; ch < nch; ch++) {
int bits = mp3enc_outer_loop(mdct_all[gr][ch], ix[gr][ch], si.gr[gr][ch], saved_xmin[gr][ch], bits_per_ch,
sfb_long, enc->sr_index, gr, si.scfsi[ch]);
gr_bits_used += bits;
}
// intra-frame savings: unused bits carry to next granule
intra_resv += gr_budget[gr] - gr_bits_used;
if (intra_resv < 0) {
intra_resv = 0;
}
total_bits_used += gr_bits_used;
}
// Write header + side_info to frame_buf
mp3enc_bs hdr_bs;
hdr_bs.init(enc->frame_buf, sizeof(enc->frame_buf));
hdr.write(hdr_bs);
si.write(hdr_bs, nch);
int hdr_si_bytes = (hdr_bs.total_bits() + 7) / 8;
// Write main_data to md_scratch (separate buffer for reservoir assembly)
mp3enc_bs md_bs;
md_bs.init(enc->md_scratch, sizeof(enc->md_scratch));
for (int gr = 0; gr < 2; gr++) {
for (int ch = 0; ch < nch; ch++) {
const mp3enc_granule_info & gi = si.gr[gr][ch];
// Scalefactors
mp3enc_write_scalefactors(md_bs, gi, gr, nch, si.scfsi[ch]);
// Huffman data: big_values region (3 regions for long blocks)
int prev_end = 0;
for (int r = 0; r < 3; r++) {
int reg_end;
if (r == 0) {
int acc = 0;
for (int s = 0; s <= gi.region0_count; s++) {
acc += sfb_long[s];
}
reg_end = (acc < gi.big_values * 2) ? acc : gi.big_values * 2;
} else if (r == 1) {
int acc = 0;
for (int s = 0; s <= gi.region0_count + gi.region1_count + 1; s++) {
acc += sfb_long[s];
}
reg_end = (acc < gi.big_values * 2) ? acc : gi.big_values * 2;
} else {
reg_end = gi.big_values * 2;
}
int pairs = (reg_end - prev_end) / 2;
for (int p = 0; p < pairs; p++) {
int i = prev_end + p * 2;
mp3enc_write_pair(md_bs, gi.table_select[r], ix[gr][ch][i], ix[gr][ch][i + 1]);
}
prev_end = reg_end;
}
// Count1 region
int c1_start = gi.big_values * 2;
int nz_end = 576 - mp3enc_count_rzero(ix[gr][ch], 576) * 2;
int c1_count = (nz_end - c1_start) / 4;
mp3enc_write_count1(md_bs, ix[gr][ch], c1_start, c1_count, gi.count1table_select);
}
}
int md_bytes = (md_bs.total_bits() + 7) / 8;
// Assemble output: write overflow to pending frame, output it, save current as pending.
//
// The first resv_bytes of main_data go into the previous frame's unused tail.
// The rest goes into the current frame's main data area.
// This is how the decoder's main_data_begin backpointer works.
int output_bytes = 0;
if (enc->pending_bytes > 0) {
// Write main_data overflow into pending frame's unused tail
int overflow = (md_bytes < resv_bytes) ? md_bytes : resv_bytes;
if (overflow > 0) {
memcpy(enc->pending_frame + enc->pending_md_end, enc->md_scratch, overflow);
}
// Grow out_buf if needed
int need = enc->out_written + enc->pending_bytes + frame_bytes;
if (need > enc->out_capacity) {
enc->out_capacity = need * 2;
enc->out_buf = (uint8_t *) realloc(enc->out_buf, enc->out_capacity);
}
// Output the pending frame (now complete with overflow data)
memcpy(enc->out_buf + enc->out_written, enc->pending_frame, enc->pending_bytes);
enc->out_written += enc->pending_bytes;
output_bytes = enc->pending_bytes;
}
// Build current frame: header+sideinfo already in frame_buf, add main_data + padding
int md_in_frame = md_bytes - resv_bytes;
if (md_in_frame < 0) {
md_in_frame = 0;
}
int md_area = frame_bytes - hdr_si_bytes;
// Copy the portion of main_data that goes in this frame
if (md_in_frame > 0) {
memcpy(enc->frame_buf + hdr_si_bytes, enc->md_scratch + resv_bytes, md_in_frame);
}
// Zero-pad the unused tail (this becomes reservoir for the next frame)
if (md_in_frame < md_area) {
memset(enc->frame_buf + hdr_si_bytes + md_in_frame, 0, md_area - md_in_frame);
}
// Save current frame as pending (will be output when next frame is encoded)
memcpy(enc->pending_frame, enc->frame_buf, frame_bytes);
enc->pending_bytes = frame_bytes;
enc->pending_md_end = hdr_si_bytes + md_in_frame;
return output_bytes;
}
// Public API: encode PCM samples.
// audio: planar float [ch0: n_samples][ch1: n_samples]
// n_samples: number of samples per channel
// out_size: receives the total MP3 bytes produced
// Returns pointer to MP3 data (internal buffer, valid until next call).
static const uint8_t * mp3enc_encode(mp3enc_t * enc, const float * audio, int n_samples, int * out_size) {
*out_size = 0;
int nch = enc->channels;
int consumed = 0;
// Reset output write position
enc->out_written = 0;
while (consumed < n_samples) {
// Fill PCM buffer up to 1152 samples per channel
int space = 1152 - enc->pcm_fill;
int avail = n_samples - consumed;
int copy = (avail < space) ? avail : space;
for (int ch = 0; ch < nch; ch++) {
memcpy(enc->pcm_buf + ch * 1152 + enc->pcm_fill, audio + ch * n_samples + consumed, copy * sizeof(float));
}
enc->pcm_fill += copy;
consumed += copy;
// When we have 1152 samples, encode a frame.
// encode_frame handles writing to out_buf (including pending frame output).
if (enc->pcm_fill == 1152) {
mp3enc_encode_frame(enc, enc->pcm_buf);
enc->pcm_fill = 0;
}
}
*out_size = enc->out_written;
return enc->out_buf;
}
// Flush remaining samples (zero pad to 1152, encode last frame).
// Also outputs the final pending frame from the bit reservoir delay.
static const uint8_t * mp3enc_flush(mp3enc_t * enc, int * out_size) {
*out_size = 0;
enc->out_written = 0;
if (enc->pcm_fill > 0) {
// Zero pad to 1152
int nch = enc->channels;
for (int ch = 0; ch < nch; ch++) {
memset(enc->pcm_buf + ch * 1152 + enc->pcm_fill, 0, (1152 - enc->pcm_fill) * sizeof(float));
}
enc->pcm_fill = 1152;
mp3enc_encode_frame(enc, enc->pcm_buf);
enc->pcm_fill = 0;
}
// Output the final pending frame (delayed by one frame for reservoir)
if (enc->pending_bytes > 0) {
int need = enc->out_written + enc->pending_bytes;
if (need > enc->out_capacity) {
enc->out_capacity = need * 2;
enc->out_buf = (uint8_t *) realloc(enc->out_buf, enc->out_capacity);
}
memcpy(enc->out_buf + enc->out_written, enc->pending_frame, enc->pending_bytes);
enc->out_written += enc->pending_bytes;
enc->pending_bytes = 0;
}
*out_size = enc->out_written;
return enc->out_buf;
}
+150
View File
@@ -0,0 +1,150 @@
// Extracted from minimp3.h (CC0, github.com/lieff/minimp3)
// ISO 11172-3 Annex B, Table B.7 Huffman trees
static const int16_t tabs[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
785, 785, 785, 785, 784, 784, 784, 784, 513, 513, 513, 513, 513, 513, 513, 513,
256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
-255, 1313, 1298, 1282, 785, 785, 785, 785, 784, 784, 784, 784, 769, 769, 769, 769,
256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
290, 288, -255, 1313, 1298, 1282, 769, 769, 769, 769, 529, 529, 529, 529, 529, 529,
529, 529, 528, 528, 528, 528, 528, 528, 528, 528, 512, 512, 512, 512, 512, 512,
512, 512, 290, 288, -253, -318, -351, -367, 785, 785, 785, 785, 784, 784, 784, 784,
769, 769, 769, 769, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
256, 256, 256, 256, 819, 818, 547, 547, 275, 275, 275, 275, 561, 560, 515, 546,
289, 274, 288, 258, -254, -287, 1329, 1299, 1314, 1312, 1057, 1057, 1042, 1042, 1026, 1026,
784, 784, 784, 784, 529, 529, 529, 529, 529, 529, 529, 529, 769, 769, 769, 769,
768, 768, 768, 768, 563, 560, 306, 306, 291, 259, -252, -413, -477, -542, 1298, -575,
1041, 1041, 784, 784, 784, 784, 769, 769, 769, 769, 256, 256, 256, 256, 256, 256,
256, 256, 256, 256, 256, 256, 256, 256, 256, 256, -383, -399, 1107, 1092, 1106, 1061,
849, 849, 789, 789, 1104, 1091, 773, 773, 1076, 1075, 341, 340, 325, 309, 834, 804,
577, 577, 532, 532, 516, 516, 832, 818, 803, 816, 561, 561, 531, 531, 515, 546,
289, 289, 288, 258, -252, -429, -493, -559, 1057, 1057, 1042, 1042, 529, 529, 529, 529,
529, 529, 529, 529, 784, 784, 784, 784, 769, 769, 769, 769, 512, 512, 512, 512,
512, 512, 512, 512, -382, 1077, -415, 1106, 1061, 1104, 849, 849, 789, 789, 1091, 1076,
1029, 1075, 834, 834, 597, 581, 340, 340, 339, 324, 804, 833, 532, 532, 832, 772,
818, 803, 817, 787, 816, 771, 290, 290, 290, 290, 288, 258, -253, -349, -414, -447,
-463, 1329, 1299, -479, 1314, 1312, 1057, 1057, 1042, 1042, 1026, 1026, 785, 785, 785, 785,
784, 784, 784, 784, 769, 769, 769, 769, 768, 768, 768, 768, -319, 851, 821, -335,
836, 850, 805, 849, 341, 340, 325, 336, 533, 533, 579, 579, 564, 564, 773, 832,
578, 548, 563, 516, 321, 276, 306, 291, 304, 259, -251, -572, -733, -830, -863, -879,
1041, 1041, 784, 784, 784, 784, 769, 769, 769, 769, 256, 256, 256, 256, 256, 256,
256, 256, 256, 256, 256, 256, 256, 256, 256, 256, -511, -527, -543, 1396, 1351, 1381,
1366, 1395, 1335, 1380, -559, 1334, 1138, 1138, 1063, 1063, 1350, 1392, 1031, 1031, 1062, 1062,
1364, 1363, 1120, 1120, 1333, 1348, 881, 881, 881, 881, 375, 374, 359, 373, 343, 358,
341, 325, 791, 791, 1123, 1122, -703, 1105, 1045, -719, 865, 865, 790, 790, 774, 774,
1104, 1029, 338, 293, 323, 308, -799, -815, 833, 788, 772, 818, 803, 816, 322, 292,
307, 320, 561, 531, 515, 546, 289, 274, 288, 258, -251, -525, -605, -685, -765, -831,
-846, 1298, 1057, 1057, 1312, 1282, 785, 785, 785, 785, 784, 784, 784, 784, 769, 769,
769, 769, 512, 512, 512, 512, 512, 512, 512, 512, 1399, 1398, 1383, 1367, 1382, 1396,
1351, -511, 1381, 1366, 1139, 1139, 1079, 1079, 1124, 1124, 1364, 1349, 1363, 1333, 882, 882,
882, 882, 807, 807, 807, 807, 1094, 1094, 1136, 1136, 373, 341, 535, 535, 881, 775,
867, 822, 774, -591, 324, 338, -671, 849, 550, 550, 866, 864, 609, 609, 293, 336,
534, 534, 789, 835, 773, -751, 834, 804, 308, 307, 833, 788, 832, 772, 562, 562,
547, 547, 305, 275, 560, 515, 290, 290, -252, -397, -477, -557, -622, -653, -719, -735,
-750, 1329, 1299, 1314, 1057, 1057, 1042, 1042, 1312, 1282, 1024, 1024, 785, 785, 785, 785,
784, 784, 784, 784, 769, 769, 769, 769, -383, 1127, 1141, 1111, 1126, 1140, 1095, 1110,
869, 869, 883, 883, 1079, 1109, 882, 882, 375, 374, 807, 868, 838, 881, 791, -463,
867, 822, 368, 263, 852, 837, 836, -543, 610, 610, 550, 550, 352, 336, 534, 534,
865, 774, 851, 821, 850, 805, 593, 533, 579, 564, 773, 832, 578, 578, 548, 548,
577, 577, 307, 276, 306, 291, 516, 560, 259, 259, -250, -2107, -2507, -2764, -2909, -2974,
-3007, -3023, 1041, 1041, 1040, 1040, 769, 769, 769, 769, 256, 256, 256, 256, 256, 256,
256, 256, 256, 256, 256, 256, 256, 256, 256, 256, -767, -1052, -1213, -1277, -1358, -1405,
-1469, -1535, -1550, -1582, -1614, -1647, -1662, -1694, -1726, -1759, -1774, -1807, -1822, -1854, -1886, 1565,
-1919, -1935, -1951, -1967, 1731, 1730, 1580, 1717, -1983, 1729, 1564, -1999, 1548, -2015, -2031, 1715,
1595, -2047, 1714, -2063, 1610, -2079, 1609, -2095, 1323, 1323, 1457, 1457, 1307, 1307, 1712, 1547,
1641, 1700, 1699, 1594, 1685, 1625, 1442, 1442, 1322, 1322, -780, -973, -910, 1279, 1278, 1277,
1262, 1276, 1261, 1275, 1215, 1260, 1229, -959, 974, 974, 989, 989, -943, 735, 478, 478,
495, 463, 506, 414, -1039, 1003, 958, 1017, 927, 942, 987, 957, 431, 476, 1272, 1167,
1228, -1183, 1256, -1199, 895, 895, 941, 941, 1242, 1227, 1212, 1135, 1014, 1014, 490, 489,
503, 487, 910, 1013, 985, 925, 863, 894, 970, 955, 1012, 847, -1343, 831, 755, 755,
984, 909, 428, 366, 754, 559, -1391, 752, 486, 457, 924, 997, 698, 698, 983, 893,
740, 740, 908, 877, 739, 739, 667, 667, 953, 938, 497, 287, 271, 271, 683, 606,
590, 712, 726, 574, 302, 302, 738, 736, 481, 286, 526, 725, 605, 711, 636, 724,
696, 651, 589, 681, 666, 710, 364, 467, 573, 695, 466, 466, 301, 465, 379, 379,
709, 604, 665, 679, 316, 316, 634, 633, 436, 436, 464, 269, 424, 394, 452, 332,
438, 363, 347, 408, 393, 448, 331, 422, 362, 407, 392, 421, 346, 406, 391, 376,
375, 359, 1441, 1306, -2367, 1290, -2383, 1337, -2399, -2415, 1426, 1321, -2431, 1411, 1336, -2447,
-2463, -2479, 1169, 1169, 1049, 1049, 1424, 1289, 1412, 1352, 1319, -2495, 1154, 1154, 1064, 1064,
1153, 1153, 416, 390, 360, 404, 403, 389, 344, 374, 373, 343, 358, 372, 327, 357,
342, 311, 356, 326, 1395, 1394, 1137, 1137, 1047, 1047, 1365, 1392, 1287, 1379, 1334, 1364,
1349, 1378, 1318, 1363, 792, 792, 792, 792, 1152, 1152, 1032, 1032, 1121, 1121, 1046, 1046,
1120, 1120, 1030, 1030, -2895, 1106, 1061, 1104, 849, 849, 789, 789, 1091, 1076, 1029, 1090,
1060, 1075, 833, 833, 309, 324, 532, 532, 832, 772, 818, 803, 561, 561, 531, 560,
515, 546, 289, 274, 288, 258, -250, -1179, -1579, -1836, -1996, -2124, -2253, -2333, -2413, -2477,
-2542, -2574, -2607, -2622, -2655, 1314, 1313, 1298, 1312, 1282, 785, 785, 785, 785, 1040, 1040,
1025, 1025, 768, 768, 768, 768, -766, -798, -830, -862, -895, -911, -927, -943, -959, -975,
-991, -1007, -1023, -1039, -1055, -1070, 1724, 1647, -1103, -1119, 1631, 1767, 1662, 1738, 1708, 1723,
-1135, 1780, 1615, 1779, 1599, 1677, 1646, 1778, 1583, -1151, 1777, 1567, 1737, 1692, 1765, 1722,
1707, 1630, 1751, 1661, 1764, 1614, 1736, 1676, 1763, 1750, 1645, 1598, 1721, 1691, 1762, 1706,
1582, 1761, 1566, -1167, 1749, 1629, 767, 766, 751, 765, 494, 494, 735, 764, 719, 749,
734, 763, 447, 447, 748, 718, 477, 506, 431, 491, 446, 476, 461, 505, 415, 430,
475, 445, 504, 399, 460, 489, 414, 503, 383, 474, 429, 459, 502, 502, 746, 752,
488, 398, 501, 473, 413, 472, 486, 271, 480, 270, -1439, -1455, 1357, -1471, -1487, -1503,
1341, 1325, -1519, 1489, 1463, 1403, 1309, -1535, 1372, 1448, 1418, 1476, 1356, 1462, 1387, -1551,
1475, 1340, 1447, 1402, 1386, -1567, 1068, 1068, 1474, 1461, 455, 380, 468, 440, 395, 425,
410, 454, 364, 467, 466, 464, 453, 269, 409, 448, 268, 432, 1371, 1473, 1432, 1417,
1308, 1460, 1355, 1446, 1459, 1431, 1083, 1083, 1401, 1416, 1458, 1445, 1067, 1067, 1370, 1457,
1051, 1051, 1291, 1430, 1385, 1444, 1354, 1415, 1400, 1443, 1082, 1082, 1173, 1113, 1186, 1066,
1185, 1050, -1967, 1158, 1128, 1172, 1097, 1171, 1081, -1983, 1157, 1112, 416, 266, 375, 400,
1170, 1142, 1127, 1065, 793, 793, 1169, 1033, 1156, 1096, 1141, 1111, 1155, 1080, 1126, 1140,
898, 898, 808, 808, 897, 897, 792, 792, 1095, 1152, 1032, 1125, 1110, 1139, 1079, 1124,
882, 807, 838, 881, 853, 791, -2319, 867, 368, 263, 822, 852, 837, 866, 806, 865,
-2399, 851, 352, 262, 534, 534, 821, 836, 594, 594, 549, 549, 593, 593, 533, 533,
848, 773, 579, 579, 564, 578, 548, 563, 276, 276, 577, 576, 306, 291, 516, 560,
305, 305, 275, 259, -251, -892, -2058, -2620, -2828, -2957, -3023, -3039, 1041, 1041, 1040, 1040,
769, 769, 769, 769, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
256, 256, 256, 256, -511, -527, -543, -559, 1530, -575, -591, 1528, 1527, 1407, 1526, 1391,
1023, 1023, 1023, 1023, 1525, 1375, 1268, 1268, 1103, 1103, 1087, 1087, 1039, 1039, 1523, -604,
815, 815, 815, 815, 510, 495, 509, 479, 508, 463, 507, 447, 431, 505, 415, 399,
-734, -782, 1262, -815, 1259, 1244, -831, 1258, 1228, -847, -863, 1196, -879, 1253, 987, 987,
748, -767, 493, 493, 462, 477, 414, 414, 686, 669, 478, 446, 461, 445, 474, 429,
487, 458, 412, 471, 1266, 1264, 1009, 1009, 799, 799, -1019, -1276, -1452, -1581, -1677, -1757,
-1821, -1886, -1933, -1997, 1257, 1257, 1483, 1468, 1512, 1422, 1497, 1406, 1467, 1496, 1421, 1510,
1134, 1134, 1225, 1225, 1466, 1451, 1374, 1405, 1252, 1252, 1358, 1480, 1164, 1164, 1251, 1251,
1238, 1238, 1389, 1465, -1407, 1054, 1101, -1423, 1207, -1439, 830, 830, 1248, 1038, 1237, 1117,
1223, 1148, 1236, 1208, 411, 426, 395, 410, 379, 269, 1193, 1222, 1132, 1235, 1221, 1116,
976, 976, 1192, 1162, 1177, 1220, 1131, 1191, 963, 963, -1647, 961, 780, -1663, 558, 558,
994, 993, 437, 408, 393, 407, 829, 978, 813, 797, 947, -1743, 721, 721, 377, 392,
844, 950, 828, 890, 706, 706, 812, 859, 796, 960, 948, 843, 934, 874, 571, 571,
-1919, 690, 555, 689, 421, 346, 539, 539, 944, 779, 918, 873, 932, 842, 903, 888,
570, 570, 931, 917, 674, 674, -2575, 1562, -2591, 1609, -2607, 1654, 1322, 1322, 1441, 1441,
1696, 1546, 1683, 1593, 1669, 1624, 1426, 1426, 1321, 1321, 1639, 1680, 1425, 1425, 1305, 1305,
1545, 1668, 1608, 1623, 1667, 1592, 1638, 1666, 1320, 1320, 1652, 1607, 1409, 1409, 1304, 1304,
1288, 1288, 1664, 1637, 1395, 1395, 1335, 1335, 1622, 1636, 1394, 1394, 1319, 1319, 1606, 1621,
1392, 1392, 1137, 1137, 1137, 1137, 345, 390, 360, 375, 404, 373, 1047, -2751, -2767, -2783,
1062, 1121, 1046, -2799, 1077, -2815, 1106, 1061, 789, 789, 1105, 1104, 263, 355, 310, 340,
325, 354, 352, 262, 339, 324, 1091, 1076, 1029, 1090, 1060, 1075, 833, 833, 788, 788,
1088, 1028, 818, 818, 803, 803, 561, 561, 531, 531, 816, 771, 546, 546, 289, 274,
288, 258, -253, -317, -381, -446, -478, -509, 1279, 1279, -811, -1179, -1451, -1756, -1900, -2028,
-2189, -2253, -2333, -2414, -2445, -2511, -2526, 1313, 1298, -2559, 1041, 1041, 1040, 1040, 1025, 1025,
1024, 1024, 1022, 1007, 1021, 991, 1020, 975, 1019, 959, 687, 687, 1018, 1017, 671, 671,
655, 655, 1016, 1015, 639, 639, 758, 758, 623, 623, 757, 607, 756, 591, 755, 575,
754, 559, 543, 543, 1009, 783, -575, -621, -685, -749, 496, -590, 750, 749, 734, 748,
974, 989, 1003, 958, 988, 973, 1002, 942, 987, 957, 972, 1001, 926, 986, 941, 971,
956, 1000, 910, 985, 925, 999, 894, 970, -1071, -1087, -1102, 1390, -1135, 1436, 1509, 1451,
1374, -1151, 1405, 1358, 1480, 1420, -1167, 1507, 1494, 1389, 1342, 1465, 1435, 1450, 1326, 1505,
1310, 1493, 1373, 1479, 1404, 1492, 1464, 1419, 428, 443, 472, 397, 736, 526, 464, 464,
486, 457, 442, 471, 484, 482, 1357, 1449, 1434, 1478, 1388, 1491, 1341, 1490, 1325, 1489,
1463, 1403, 1309, 1477, 1372, 1448, 1418, 1433, 1476, 1356, 1462, 1387, -1439, 1475, 1340, 1447,
1402, 1474, 1324, 1461, 1371, 1473, 269, 448, 1432, 1417, 1308, 1460, -1711, 1459, -1727, 1441,
1099, 1099, 1446, 1386, 1431, 1401, -1743, 1289, 1083, 1083, 1160, 1160, 1458, 1445, 1067, 1067,
1370, 1457, 1307, 1430, 1129, 1129, 1098, 1098, 268, 432, 267, 416, 266, 400, -1887, 1144,
1187, 1082, 1173, 1113, 1186, 1066, 1050, 1158, 1128, 1143, 1172, 1097, 1171, 1081, 420, 391,
1157, 1112, 1170, 1142, 1127, 1065, 1169, 1049, 1156, 1096, 1141, 1111, 1155, 1080, 1126, 1154,
1064, 1153, 1140, 1095, 1048, -2159, 1125, 1110, 1137, -2175, 823, 823, 1139, 1138, 807, 807,
384, 264, 368, 263, 868, 838, 853, 791, 867, 822, 852, 837, 866, 806, 865, 790,
-2319, 851, 821, 836, 352, 262, 850, 805, 849, -2399, 533, 533, 835, 820, 336, 261,
578, 548, 563, 577, 532, 532, 832, 772, 562, 562, 547, 547, 305, 275, 560, 515,
290, 290, 288, 258
};
static const uint8_t tab32[] = { 130, 162, 193, 209, 44, 28, 76, 140, 9, 9, 9, 9, 9, 9,
9, 9, 190, 254, 222, 238, 126, 94, 157, 157, 109, 61, 173, 205 };
static const uint8_t tab33[] = { 252, 236, 220, 204, 188, 172, 156, 140, 124, 108, 92, 76, 60, 44, 28, 12 };
static const int16_t tabindex[2 * 16] = { 0, 32, 64, 98, 0, 132, 180, 218, 292, 364, 426,
538, 648, 746, 0, 1126, 1460, 1460, 1460, 1460, 1460, 1460,
1460, 1460, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842 };
static const uint8_t g_linbits[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 2, 3, 4, 6, 8, 10, 13, 4, 5, 6, 7, 8, 9, 11, 13 };