shithub: opus

Download patch

ref: 3ab03e05561f81f0eacac3ee724baac33b89683b
parent: 91904a4c91eb19abcebe843045f4599ee67adbee
author: Jean-Marc Valin <[email protected]>
date: Fri Sep 6 12:00:39 EDT 2013

First pass at making the analysis code run with FIXED_POINT

Code is still float, but at least tonality esitmation seems to work.
Speech/music analysis is still disabled.

--- a/Makefile.am
+++ b/Makefile.am
@@ -20,8 +20,9 @@
 SILK_SOURCES += $(SILK_SOURCES_FIXED)
 else
 SILK_SOURCES += $(SILK_SOURCES_FLOAT)
-OPUS_SOURCES += $(OPUS_SOURCES_FLOAT)
 endif
+
+OPUS_SOURCES += $(OPUS_SOURCES_FLOAT)
 
 if CPU_ARM
 CELT_SOURCES += $(CELT_SOURCES_ARM)
--- a/celt/arch.h
+++ b/celt/arch.h
@@ -185,6 +185,7 @@
 #define MAC16_32_Q15(c,a,b)     ((c)+(a)*(b))
 
 #define MULT16_16_Q11_32(a,b)     ((a)*(b))
+#define MULT16_16_Q11(a,b)     ((a)*(b))
 #define MULT16_16_Q13(a,b)     ((a)*(b))
 #define MULT16_16_Q14(a,b)     ((a)*(b))
 #define MULT16_16_Q15(a,b)     ((a)*(b))
--- a/celt/celt.h
+++ b/celt/celt.h
@@ -52,11 +52,11 @@
 
 typedef struct {
    int valid;
-   opus_val16 tonality;
-   opus_val16 tonality_slope;
-   opus_val16 noisiness;
-   opus_val16 activity;
-   opus_val16 music_prob;
+   float tonality;
+   float tonality_slope;
+   float noisiness;
+   float activity;
+   float music_prob;
    int        bandwidth;
 }AnalysisInfo;
 
--- a/celt/celt_encoder.c
+++ b/celt/celt_encoder.c
@@ -819,7 +819,7 @@
    trim -= MAX16(-QCONST16(2.f, 8), MIN16(QCONST16(2.f, 8), SHR16(diff+QCONST16(1.f, DB_SHIFT),DB_SHIFT-8)/6 ));
    trim -= SHR16(surround_trim, DB_SHIFT-8);
    trim -= 2*SHR16(tf_estimate, 14-8);
-#ifndef FIXED_POINT
+#ifndef DISABLE_FLOAT_API
    if (analysis->valid)
    {
       trim -= MAX16(-QCONST16(2.f, 8), MIN16(QCONST16(2.f, 8), 2*(analysis->tonality_slope+.05f)));
@@ -1142,7 +1142,7 @@
    target = base_target;
 
    /*printf("%f %f %f %f %d %d ", st->analysis.activity, st->analysis.tonality, tf_estimate, st->stereo_saving, tot_boost, coded_bands);*/
-#ifndef FIXED_POINT
+#ifndef DISABLE_FLOAT_API
    if (analysis->valid && analysis->activity<.4)
       target -= (opus_int32)((coded_bins<<BITRES)*(.4f-analysis->activity));
 #endif
@@ -1167,7 +1167,7 @@
                     QCONST16(0.02f,14) : QCONST16(0.04f,14);
    target += (opus_int32)SHL32(MULT16_32_Q15(tf_estimate-tf_calibration, target),1);
 
-#ifndef FIXED_POINT
+#ifndef DISABLE_FLOAT_API
    /* Apply tonality boost */
    if (analysis->valid && !lfe)
    {
@@ -1872,7 +1872,7 @@
    anti_collapse_rsv = isTransient&&LM>=2&&bits>=((LM+2)<<BITRES) ? (1<<BITRES) : 0;
    bits -= anti_collapse_rsv;
    signalBandwidth = st->end-1;
-#ifndef FIXED_POINT
+#ifndef DISABLE_FLOAT_API
    if (st->analysis.valid)
    {
       int min_bandwidth;
--- a/celt/fixed_generic.h
+++ b/celt/fixed_generic.h
@@ -116,6 +116,7 @@
 #define MAC16_32_Q15(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15)))
 
 #define MULT16_16_Q11_32(a,b) (SHR(MULT16_16((a),(b)),11))
+#define MULT16_16_Q11(a,b) (SHR(MULT16_16((a),(b)),11))
 #define MULT16_16_Q13(a,b) (SHR(MULT16_16((a),(b)),13))
 #define MULT16_16_Q14(a,b) (SHR(MULT16_16((a),(b)),14))
 #define MULT16_16_Q15(a,b) (SHR(MULT16_16((a),(b)),15))
--- a/src/analysis.c
+++ b/src/analysis.c
@@ -253,10 +253,10 @@
     for (i=0;i<N2;i++)
     {
        float w = analysis_window[i];
-       in[i].r = MULT16_16(w, tonal->inmem[i]);
-       in[i].i = MULT16_16(w, tonal->inmem[N2+i]);
-       in[N-i-1].r = MULT16_16(w, tonal->inmem[N-i-1]);
-       in[N-i-1].i = MULT16_16(w, tonal->inmem[N+N2-i-1]);
+       in[i].r = w*tonal->inmem[i];
+       in[i].i = w*tonal->inmem[N2+i];
+       in[N-i-1].r = w*tonal->inmem[N-i-1];
+       in[N-i-1].i = w*tonal->inmem[N+N2-i-1];
     }
     OPUS_MOVE(tonal->inmem, tonal->inmem+ANALYSIS_BUF_SIZE-240, 240);
     remaining = len - (ANALYSIS_BUF_SIZE-tonal->mem_fill);
@@ -325,8 +325,8 @@
        float stationarity;
        for (i=tbands[b];i<tbands[b+1];i++)
        {
-          float binE = out[i].r*out[i].r + out[N-i].r*out[N-i].r
-                     + out[i].i*out[i].i + out[N-i].i*out[N-i].i;
+          float binE = out[i].r*(float)out[i].r + out[N-i].r*(float)out[N-i].r
+                     + out[i].i*(float)out[i].i + out[N-i].i*(float)out[N-i].i;
           E += binE;
           tE += binE*tonality[i];
           nE += binE*2.f*(.5f-noisiness[i]);
@@ -334,7 +334,7 @@
        tonal->E[tonal->E_count][b] = E;
        frame_noisiness += nE/(1e-15f+E);
 
-       frame_loudness += celt_sqrt(E+1e-10f);
+       frame_loudness += sqrt(E+1e-10f);
        logE[b] = (float)log(E+1e-10f);
        tonal->lowE[b] = MIN32(logE[b], tonal->lowE[b]+.01f);
        tonal->highE[b] = MAX32(logE[b], tonal->highE[b]-.1f);
@@ -348,11 +348,11 @@
        L1=L2=0;
        for (i=0;i<NB_FRAMES;i++)
        {
-          L1 += celt_sqrt(tonal->E[i][b]);
+          L1 += sqrt(tonal->E[i][b]);
           L2 += tonal->E[i][b];
        }
 
-       stationarity = MIN16(0.99f,L1/celt_sqrt(EPSILON+NB_FRAMES*L2));
+       stationarity = MIN16(0.99f,L1/sqrt(EPSILON+NB_FRAMES*L2));
        stationarity *= stationarity;
        stationarity *= stationarity;
        frame_stationarity += stationarity;
@@ -379,6 +379,9 @@
     bandwidth = 0;
     maxE = 0;
     noise_floor = 5.7e-4f/(1<<(IMAX(0,lsb_depth-8)));
+#ifdef FIXED_POINT
+    noise_floor *= 1<<(15+SIG_SHIFT);
+#endif
     noise_floor *= noise_floor;
     for (b=0;b<NB_TOT_BANDS;b++)
     {
@@ -389,8 +392,8 @@
        band_end = extra_bands[b+1];
        for (i=band_start;i<band_end;i++)
        {
-          float binE = out[i].r*out[i].r + out[N-i].r*out[N-i].r
-                     + out[i].i*out[i].i + out[N-i].i*out[N-i].i;
+          float binE = out[i].r*(float)out[i].r + out[N-i].r*(float)out[N-i].r
+                     + out[i].i*(float)out[i].i + out[N-i].i*(float)out[N-i].i;
           E += binE;
        }
        maxE = MAX32(maxE, E);
@@ -469,7 +472,7 @@
        tonal->mem[i] = BFCC[i];
     }
     for (i=0;i<9;i++)
-       features[11+i] = celt_sqrt(tonal->std[i]);
+       features[11+i] = sqrt(tonal->std[i]);
     features[20] = info->tonality;
     features[21] = info->activity;
     features[22] = frame_stationarity;
--- a/src/analysis.h
+++ b/src/analysis.h
@@ -42,7 +42,7 @@
    float angle[240];
    float d_angle[240];
    float d2_angle[240];
-   float inmem[ANALYSIS_BUF_SIZE];
+   opus_val32 inmem[ANALYSIS_BUF_SIZE];
    int   mem_fill;                      /* number of usable samples in the buffer */
    float prev_band_tonality[NB_TBANDS];
    float prev_tonality;
--- a/src/mlp.c
+++ b/src/mlp.c
@@ -43,9 +43,9 @@
 	/*double x, y;*/
 	opus_val16 dy, yy; /* Q14 */
 	/*x = 1.9073e-06*_x;*/
-	if (_x>=QCONST32(10,19))
+	if (_x>=QCONST32(8,19))
 		return QCONST32(1.,14);
-	if (_x<=-QCONST32(10,19))
+	if (_x<=-QCONST32(8,19))
 		return -QCONST32(1.,14);
 	xx = EXTRACT16(SHR32(_x, 8));
 	/*i = lrint(25*x);*/
--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -98,7 +98,7 @@
     int          energy_masking;
     StereoWidthState width_mem;
     opus_val16   delay_buffer[MAX_ENCODER_BUFFER*2];
-#ifndef FIXED_POINT
+#ifndef DISABLE_FLOAT_API
     TonalityAnalysisState analysis;
     int          detected_bandwidth;
     int          analysis_offset;
@@ -551,7 +551,7 @@
     return st->user_bitrate_bps;
 }
 
-#ifndef FIXED_POINT
+#ifndef DISABLE_FLOAT_API
 /* Don't use more than 60 ms for the frame size analysis */
 #define MAX_DYNAMIC_FRAMESIZE 24
 /* Estimates how much the bitrate will be boosted based on the sub-frame energy */
@@ -697,10 +697,10 @@
    int bestLM=0;
    int subframe;
    int pos;
-   VARDECL(opus_val16, sub);
+   VARDECL(opus_val32, sub);
 
    subframe = Fs/400;
-   ALLOC(sub, subframe, opus_val16);
+   ALLOC(sub, subframe, opus_val32);
    e[0]=mem[0];
    e_1[0]=1.f/(EPSILON+mem[0]);
    if (buffering)
@@ -759,17 +759,17 @@
 #endif
 
 #ifndef DISABLE_FLOAT_API
-void downmix_float(const void *_x, float *sub, int subframe, int offset, int c1, int c2, int C)
+void downmix_float(const void *_x, opus_val32 *sub, int subframe, int offset, int c1, int c2, int C)
 {
    const float *x;
    int j;
    x = (const float *)_x;
    for (j=0;j<subframe;j++)
-      sub[j] = x[(j+offset)*C+c1];
+      sub[j] = SCALEIN(x[(j+offset)*C+c1]);
    if (c2>-1)
    {
       for (j=0;j<subframe;j++)
-         sub[j] += x[(j+offset)*C+c2];
+         sub[j] += SCALEIN(x[(j+offset)*C+c2]);
    } else if (c2==-2)
    {
       int c;
@@ -776,13 +776,24 @@
       for (c=1;c<C;c++)
       {
          for (j=0;j<subframe;j++)
-            sub[j] += x[(j+offset)*C+c];
+            sub[j] += SCALEIN(x[(j+offset)*C+c]);
       }
    }
+#ifdef FIXED_POINT
+   {
+      opus_val32 scale =(1<<SIG_SHIFT);
+      if (C==-2)
+         scale /= C;
+      else
+         scale /= 2;
+      for (j=0;j<subframe;j++)
+         sub[j] *= scale;
+   }
+#endif
 }
 #endif
 
-void downmix_int(const void *_x, float *sub, int subframe, int offset, int c1, int c2, int C)
+void downmix_int(const void *_x, opus_val32 *sub, int subframe, int offset, int c1, int c2, int C)
 {
    const opus_int16 *x;
    int j;
@@ -802,8 +813,20 @@
             sub[j] += x[(j+offset)*C+c];
       }
    }
+#ifdef FIXED_POINT
+   {
+      opus_val32 scale =(1<<SIG_SHIFT);
+      if (C==-2)
+         scale /= C;
+      else
+         scale /= 2;
+      for (j=0;j<subframe;j++)
+         sub[j] *= scale;
+   }
+#else
    for (j=0;j<subframe;j++)
       sub[j] *= (1.f/32768);
+#endif
 }
 
 opus_int32 frame_size_select(opus_int32 frame_size, int variable_duration, opus_int32 Fs)
@@ -964,7 +987,7 @@
 
     analysis_info.valid = 0;
     celt_encoder_ctl(celt_enc, CELT_GET_MODE(&celt_mode));
-#ifndef FIXED_POINT
+#ifndef DISABLE_FLOAT_API
     if (st->silk_mode.complexity >= 7 && st->Fs==48000)
     {
        frame_size = run_analysis(&st->analysis, celt_mode, pcm, analysis_pcm,
@@ -982,7 +1005,7 @@
 
     st->voice_ratio = -1;
 
-#ifndef FIXED_POINT
+#ifndef DISABLE_FLOAT_API
     st->detected_bandwidth = 0;
     if (analysis_info.valid)
     {
@@ -1624,7 +1647,7 @@
             if (st->use_vbr)
             {
                 opus_int32 bonus=0;
-#ifndef FIXED_POINT
+#ifndef DISABLE_FLOAT_API
                 if (st->variable_duration==OPUS_FRAMESIZE_VARIABLE && frame_size != st->Fs/50)
                 {
                    bonus = (60*st->stream_channels+40)*(st->Fs/frame_size-50);
@@ -1726,7 +1749,7 @@
        ec_enc_shrink(&enc, nb_compr_bytes);
     }
 
-#ifndef FIXED_POINT
+#ifndef DISABLE_FLOAT_API
     if (redundancy || st->mode != MODE_SILK_ONLY)
        celt_encoder_ctl(celt_enc, CELT_SET_ANALYSIS(&analysis_info));
 #endif
--- a/src/opus_private.h
+++ b/src/opus_private.h
@@ -82,9 +82,9 @@
 #define OPUS_SET_FORCE_MODE_REQUEST    11002
 #define OPUS_SET_FORCE_MODE(x) OPUS_SET_FORCE_MODE_REQUEST, __opus_check_int(x)
 
-typedef void (*downmix_func)(const void *, float *, int, int, int, int, int);
-void downmix_float(const void *_x, float *sub, int subframe, int offset, int c1, int c2, int C);
-void downmix_int(const void *_x, float *sub, int subframe, int offset, int c1, int c2, int C);
+typedef void (*downmix_func)(const void *, opus_val32 *, int, int, int, int, int);
+void downmix_float(const void *_x, opus_val32 *sub, int subframe, int offset, int c1, int c2, int C);
+void downmix_int(const void *_x, opus_val32 *sub, int subframe, int offset, int c1, int c2, int C);
 
 int optimize_framesize(const opus_val16 *x, int len, int C, opus_int32 Fs,
                 int bitrate, opus_val16 tonality, opus_val32 *mem, int buffering,