diff --git a/libcelt/bands.c b/libcelt/bands.c index 4aafdc2d..ccf191fa 100644 --- a/libcelt/bands.c +++ b/libcelt/bands.c @@ -216,7 +216,7 @@ void denormalise_bands(const CELTMode *m, const celt_norm_t * restrict X, celt_s } } -int compute_new_pitch(const CELTMode *m, const celt_sig_t *X, const celt_sig_t *P, int *gain_id) +int compute_new_pitch(const CELTMode *m, const celt_sig_t *X, const celt_sig_t *P, int norm_rate, int *gain_id) { int j ; celt_word16_t g; @@ -248,22 +248,31 @@ int compute_new_pitch(const CELTMode *m, const celt_sig_t *X, const celt_sig_t * #ifdef FIXED_POINT { celt_word32_t num, den; + celt_word16_t fact; + fact = MULT16_16(QCONST16(.04, 14), norm_rate); + if (fact < QCONST16(1., 14)) + fact = QCONST16(1., 14); num = Sxy; den = EPSILON+Sxx+MULT16_32_Q15(QCONST16(.03,15),Syy); shift = celt_ilog2(Sxy)-16; if (shift < 0) shift = 0; g = DIV32(SHL32(SHR32(num,shift),14),SHR32(den,shift)); - if (Sxy < SHR32(MULT16_16(celt_sqrt(EPSILON+Sxx),celt_sqrt(EPSILON+Syy)),1)) + if (Sxy < MULT16_32_Q15(fact, MULT16_16(celt_sqrt(EPSILON+Sxx),celt_sqrt(EPSILON+Syy)))) g = 0; /* This MUST round down */ *gain_id = EXTRACT16(SHR32(MULT16_16(20,(g-QCONST16(.5,14))),14)); } #else - g = Sxy/(.1+Sxx+.03*Syy); - if (Sxy < .5*celt_sqrt(.1+Sxx*Syy)) - g = 0; - *gain_id = floor(20*(g-.5)); + { + float fact = .04*norm_rate; + if (fact < 1) + fact = 1; + g = Sxy/(.1+Sxx+.03*Syy); + if (Sxy < .5*fact*celt_sqrt(1+Sxx*Syy)) + g = 0; + *gain_id = floor(20*(g-.5)); + } #endif if (*gain_id < 0) { diff --git a/libcelt/bands.h b/libcelt/bands.h index d47ecbd9..6012be1c 100644 --- a/libcelt/bands.h +++ b/libcelt/bands.h @@ -64,7 +64,7 @@ void renormalise_bands(const CELTMode *m, celt_norm_t * restrict X); */ 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, int *gain_id); +int compute_new_pitch(const CELTMode *m, const celt_sig_t *X, const celt_sig_t *P, int norm_rate, int *gain_id); void apply_new_pitch(const CELTMode *m, celt_sig_t *X, const celt_sig_t *P, int gain_id, int pred); diff --git a/libcelt/celt.c b/libcelt/celt.c index 50dad62a..6dc3a345 100644 --- a/libcelt/celt.c +++ b/libcelt/celt.c @@ -523,6 +523,7 @@ int celt_encode_float(CELTEncoder * restrict st, const celt_sig_t * pcm, celt_si int mdct_weight_shift = 0; int mdct_weight_pos=0; int gain_id=0; + int norm_rate; SAVE_STACK; if (check_encoder(st) != CELT_OK) @@ -659,15 +660,13 @@ int celt_encode_float(CELTEncoder * restrict st, const celt_sig_t * pcm, celt_si #endif } - compute_band_energies(st->mode, freq, bandE); - for (i=0;imode->nbEBands*C;i++) - bandLogE[i] = amp2Log(bandE[i]); - + norm_rate = (nbCompressedBytes-5)*8*(celt_uint32_t)st->mode->Fs/(C*N)>>10; /* Pitch analysis: we do it early to save on the peak stack space */ /* Don't use pitch if there isn't enough data available yet, or if we're using shortBlocks */ has_pitch = st->pitch_enabled && st->pitch_permitted && (N <= 512) - && (st->pitch_available >= MAX_PERIOD) && (!shortBlocks); + && (st->pitch_available >= MAX_PERIOD) && (!shortBlocks) + && norm_rate < 50; if (has_pitch) { 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); @@ -682,8 +681,9 @@ int celt_encode_float(CELTEncoder * restrict st, const celt_sig_t * pcm, celt_si 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, &gain_id); + has_pitch = compute_new_pitch(st->mode, freq, pitch_freq, norm_rate, &gain_id); } if (has_pitch)