shithub: opus

Download patch

ref: ab220aa212ed9c37a7dd6850660db346b07821dd
parent: 4c77ea96d0d873a0240a24dea1af57f3107a1094
author: Jean-Marc Valin <[email protected]>
date: Tue Sep 15 18:38:40 EDT 2009

denorm pitch works in fixed-point (though there's still some floats left)

--- a/libcelt/bands.c
+++ b/libcelt/bands.c
@@ -216,54 +216,60 @@
    }
 }
 
-int compute_new_pitch(const CELTMode *m, const celt_sig_t *X, const celt_sig_t *P, celt_pgain_t *gain, int *gain_id)
+int compute_new_pitch(const CELTMode *m, const celt_sig_t *X, const celt_sig_t *P, int *gain_id)
 {
    int j ;
-   int gain_sum = 0;
    float g;
-   const celt_int16_t *pBands = m->pBands;
    const int C = CHANNELS(m);
-   celt_word32_t Sxy=0, Sxx=0, Syy=0;
+   float Sxy=0, Sxx=0, Syy=0;
    int len = 20*C;
    
    for (j=0;j<len;j++)
    {
       float gg = 1-1.*j/len;
-            //printf ("%f ", gg);
+#ifdef FIXED_POINT
+      Sxy += X[j] * gg*P[j];
+      Sxx += gg*P[j]* gg*P[j];
+      Syy += X[j] *1.*X[j];
+#else
       Sxy = MAC16_16(Sxy, X[j], gg*P[j]);
       Sxx = MAC16_16(Sxx, gg*P[j], gg*P[j]);
       Syy = MAC16_16(Syy, X[j], X[j]);
+#endif
    }
-   g = Sxy/(.1+Sxx+.03*Syy);
+   g = QCONST16(1.,14)*Sxy/(.1+Sxx+.03*Syy);
    if (Sxy/sqrt(.1+Sxx*Syy) < .5)
       g = 0;
+#ifdef FIXED_POINT
+   /* This MUST round down */
+   *gain_id = EXTRACT16(SHR32(MULT16_16(20,(g-QCONST16(.5,14))),14));
+#else
    *gain_id = floor(20*(g-.5));
+#endif
    if (*gain_id < 0)
    {
       *gain_id = 0;
-      *gain = 0;
       return 0;
    } else {
       if (*gain_id > 15)
          *gain_id = 15;
-      *gain = .5 + .05**gain_id;
-      //printf ("%f\n", *gain);
-      //printf ("%f %f %f\n", Sxy, Sxx, Syy);
       return 1;
    }
 }
 
-void apply_new_pitch(const CELTMode *m, celt_sig_t *X, const celt_sig_t *P, celt_pgain_t gain)
+void apply_new_pitch(const CELTMode *m, celt_sig_t *X, const celt_sig_t *P, int gain_id, int pred)
 {
-   int j ;
-   float g;
+   int j;
+   celt_word16_t gain;
    const int C = CHANNELS(m);
    int len = 20*C;
-   
+   gain = ADD16(QCONST16(.5,14), MULT16_16_16(QCONST16(.05,14),gain_id));
+   if (pred)
+      gain = -gain;
    for (j=0;j<len;j++)
    {
-      float gg = 1-1.*j/len;
-      X[j] += gain*gg*P[j];
+      celt_word16_t gg = SUB16(gain, DIV32_16(MULT16_16(gain,j),len));
+      X[j] += SHL(MULT16_32_Q15(gg,P[j]),1);
    }
 }
 
--- a/libcelt/bands.h
+++ b/libcelt/bands.h
@@ -64,8 +64,9 @@
  */
 void denormalise_bands(const CELTMode *m, const celt_norm_t * restrict X, celt_sig_t * restrict freq, const celt_ener_t *bands);
 
-int compute_new_pitch(const CELTMode *m, const celt_sig_t *X, const celt_sig_t *P, celt_pgain_t *gain, int *gain_id);
-void apply_new_pitch(const CELTMode *m, celt_sig_t *X, const celt_sig_t *P, celt_pgain_t gain);
+int compute_new_pitch(const CELTMode *m, const celt_sig_t *X, const celt_sig_t *P, int *gain_id);
+
+void apply_new_pitch(const CELTMode *m, celt_sig_t *X, const celt_sig_t *P, int gain_id, int pred);
 
 /** Compute the pitch predictor gain for each pitch band
  * @param m Mode data 
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -504,6 +504,7 @@
    ec_enc         enc;
    VARDECL(celt_sig_t, in);
    VARDECL(celt_sig_t, freq);
+   VARDECL(celt_sig_t, pitch_freq);
    VARDECL(celt_norm_t, X);
    VARDECL(celt_norm_t, P);
    VARDECL(celt_ener_t, bandE);
@@ -521,6 +522,7 @@
    const int C = CHANNELS(st->mode);
    int mdct_weight_shift = 0;
    int mdct_weight_pos=0;
+   int gain_id=0;
    SAVE_STACK;
 
    if (check_encoder(st) != CELT_OK)
@@ -671,8 +673,6 @@
       find_spectral_pitch(st->mode, st->mode->fft, &st->mode->psy, in, st->out_mem, st->mode->window, NULL, 2*N-2*N4, MAX_PERIOD-(2*N-2*N4), &pitch_index);
    }
 
-   float pgain;
-   int gain_id;
    /* Deferred allocation after find_spectral_pitch() to reduce 
       the peak memory usage */
    ALLOC(X, C*N, celt_norm_t);         /**< Interleaved normalised MDCTs */
@@ -679,15 +679,15 @@
    ALLOC(P, C*N, celt_norm_t);         /**< Interleaved normalised pitch MDCTs*/
    ALLOC(gains,st->mode->nbPBands, celt_pgain_t);
 
-   float pitch_freq[N];
+   ALLOC(pitch_freq, C*N, celt_sig_t); /**< Interleaved signal MDCTs */
    if (has_pitch)
    {
       compute_mdcts(st->mode, 0, st->out_mem+pitch_index*C, pitch_freq);
-      has_pitch = compute_new_pitch(st->mode, freq, pitch_freq, &pgain, &gain_id);
+      has_pitch = compute_new_pitch(st->mode, freq, pitch_freq, &gain_id);
    }
    
    if (has_pitch)
-      apply_new_pitch(st->mode, freq, pitch_freq, -pgain);
+      apply_new_pitch(st->mode, freq, pitch_freq, gain_id, 1);
 
    compute_band_energies(st->mode, freq, bandE);
    for (i=0;i<st->mode->nbEBands*C;i++)
@@ -806,7 +806,7 @@
 #endif
       }
       if (has_pitch)
-         apply_new_pitch(st->mode, freq, pitch_freq, pgain);
+         apply_new_pitch(st->mode, freq, pitch_freq, gain_id, 0);
       
       compute_inv_mdcts(st->mode, shortBlocks, freq, transient_time, transient_shift, st->out_mem);
       /* De-emphasis and put everything back at the right place 
@@ -1207,6 +1207,7 @@
    ec_dec dec;
    ec_byte_buffer buf;
    VARDECL(celt_sig_t, freq);
+   VARDECL(celt_sig_t, pitch_freq);
    VARDECL(celt_norm_t, X);
    VARDECL(celt_norm_t, P);
    VARDECL(celt_ener_t, bandE);
@@ -1223,6 +1224,7 @@
    int mdct_weight_shift=0;
    const int C = CHANNELS(st->mode);
    int mdct_weight_pos=0;
+   int gain_id=0;
    SAVE_STACK;
 
    if (check_decoder(st) != CELT_OK)
@@ -1278,7 +1280,6 @@
       transient_shift = 0;
    }
    
-   int gain_id;
    if (has_pitch)
    {
       pitch_index = ec_dec_uint(&dec, MAX_PERIOD-(2*N-2*N4));
@@ -1307,7 +1308,7 @@
    
    unquant_fine_energy(st->mode, bandE, st->oldBandE, fine_quant, &dec);
 
-   float pitch_freq[N];
+   ALLOC(pitch_freq, C*N, celt_sig_t); /**< Interleaved signal MDCTs */
    if (has_pitch) 
    {
       /* Pitch MDCT */
@@ -1342,7 +1343,7 @@
    }
    
    if (has_pitch)
-      apply_new_pitch(st->mode, freq, pitch_freq, .5+.05*gain_id);
+      apply_new_pitch(st->mode, freq, pitch_freq, gain_id, 0);
 
    /* Compute inverse MDCTs */
    compute_inv_mdcts(st->mode, shortBlocks, freq, transient_time, transient_shift, st->out_mem);