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);