ref: d23c60584d6385df973b631a2e923b94831d4c2b
parent: 5f7e25a9bad219f817a61e2160a6207d41b038c4
author: lieff <[email protected]>
date: Mon Feb 12 07:44:07 EST 2018
reduce code size, add MINIMP3_NONSTANDARD_BUT_LOGICAL, more robust L3_ldexp_q2
--- a/README.md
+++ b/README.md
@@ -69,6 +69,7 @@
```
//#define MINIMP3_ONLY_MP3
//#define MINIMP3_ONLY_SIMD
+//#define MINIMP3_NONSTANDARD_BUT_LOGICAL
#define MINIMP3_IMPLEMENTATION
#include "minimp3.h"
...
@@ -80,6 +81,7 @@
You can ``#include`` ``minimp3.h`` in as many files as you like.
Also you can use ``MINIMP3_ONLY_MP3`` define to strip MP1/MP2 decoding code.
MINIMP3_ONLY_SIMD define controls generic (non SSE/NEON) code generation (always enabled on x64/arm64 targets).
+MINIMP3_NONSTANDARD_BUT_LOGICAL define saves some code bytes, and enforces non-stadnard but logical behaviour of mono-stereo transition (rare case).
Then. we decode the input stream frame-by-frame:
--- a/minimp3.h
+++ b/minimp3.h
@@ -247,11 +247,8 @@
uint32_t next, cache = 0, s = bs->pos & 7;
int shl = n + s;
const uint8_t *p = bs->buf + (bs->pos >> 3);
- if (bs->pos + n > bs->limit)
- {
- bs->pos = bs->limit;
+ if ((bs->pos += n) > bs->limit)
return 0;
- }
next = *p++ & (255 >> s);
while ((shl -= 8) > 0)
{
@@ -258,7 +255,6 @@
cache |= next << shl;
next = *p++;
}
- bs->pos += n;
return cache | (next >> -shl);
}
@@ -315,7 +311,7 @@
}
#ifndef MINIMP3_ONLY_MP3
-static const L12_subband_alloc_t * L12_subband_alloc_table(const uint8_t *hdr, L12_scale_info *sci)
+static const L12_subband_alloc_t *L12_subband_alloc_table(const uint8_t *hdr, L12_scale_info *sci)
{
const L12_subband_alloc_t *alloc;
int mode = HDR_GET_STEREO_MODE(hdr);
@@ -643,10 +639,16 @@
scf[0] = scf[1] = scf[2] = 0;
}
-static float L3_ldexp_q2(int e)
+static float L3_ldexp_q2(float y, int exp_q2)
{
static const float g_expfrac[4] = { 9.31322575e-10f,7.83145814e-10f,6.58544508e-10f,5.53767716e-10f };
- return g_expfrac[e & 3]*(1 << 30 >> (e >> 2));
+ int e;
+ do
+ {
+ e = MINIMP3_MIN(30*4, exp_q2);
+ y *= g_expfrac[e & 3]*(1 << 30 >> (e >> 2));
+ } while ((exp_q2 -= e) > 0);
+ return y;
}
static void L3_decode_scalefactors(const uint8_t *hdr, uint8_t *ist_pos, bs_t *bs, const L3_gr_info_t *gr, float *scf, int ch)
@@ -694,8 +696,7 @@
iscf[gr->n_long_sfb + i + 1] += gr->subblock_gain[1] << sh;
iscf[gr->n_long_sfb + i + 2] += gr->subblock_gain[2] << sh;
}
- }
- else if (gr->preflag)
+ } else if (gr->preflag)
{
static const uint8_t g_preamp[10] = { 1,1,1,1,2,2,3,3,3,2 };
for (i = 0; i < 10; i++)
@@ -705,21 +706,10 @@
}
gain_exp = gr->global_gain + BITS_DEQUANTIZER_OUT*4 - 210 - (HDR_IS_MS_STEREO(hdr) ? 2 : 0);
- gain = 1 << (MAX_SCFI/4);
-
- while (gain_exp < MAX_SCFI)
- {
- int dexp = MINIMP3_MIN(30*4, MAX_SCFI - gain_exp);
- gain *= L3_ldexp_q2(dexp);
- gain_exp += dexp;
- }
-
+ gain = L3_ldexp_q2(1 << (MAX_SCFI/4), MAX_SCFI - gain_exp);
for (i = 0; i < (int)(gr->n_long_sfb + gr->n_short_sfb); i++)
{
- if (((iscf[i] << scf_shift) >> 2) >= 31)
- scf[i] = gain*L3_ldexp_q2((iscf[i] << scf_shift) - 30*4) * /*L3_ldexp_q2(30*4)*/ 9.313226e-10f;
- else
- scf[i] = gain*L3_ldexp_q2(iscf[i] << scf_shift);
+ scf[i] = L3_ldexp_q2(gain, iscf[i] << scf_shift);
}
}
@@ -927,7 +917,7 @@
} else
{
kl = 1;
- kr = L3_ldexp_q2((ipos + 1) >> 1 << mpeg2_sh);
+ kr = L3_ldexp_q2(1, (ipos + 1) >> 1 << mpeg2_sh);
if (ipos & 1)
{
kl = kr;
@@ -1572,7 +1562,7 @@
{
mp3d_synth(grbuf + i, pcm + 32*nch*i, nch, lins + i*64);
}
-
+#ifndef MINIMP3_NONSTANDARD_BUT_LOGICAL
if (nch == 1)
{
for (i = 0; i < 15*64; i += 2)
@@ -1580,6 +1570,7 @@
qmf_state[i] = lins[nbands*64 + i];
}
} else
+#endif
{
memcpy(qmf_state, lins + nbands*64, sizeof(float)*15*64);
}
--- a/minimp3_test.c
+++ b/minimp3_test.c
@@ -1,5 +1,6 @@
/*#define MINIMP3_ONLY_MP3*/
/*#define MINIMP3_ONLY_SIMD*/
+/*#define MINIMP3_NONSTANDARD_BUT_LOGICAL*/
#define MINIMP3_IMPLEMENTATION
#include "minimp3.h"
#include <stdio.h>
binary files a/vectors/l2-nonstandard-test32-size.pcm b/vectors/l2-nonstandard-test32-size.pcm differ