shithub: mp3dec

Download patch

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