ref: 4ce9205f3832f136fc86ee3cd367bcc91359c424
parent: e488a1077bb9f0e8563cad4380bea0d9b4fa8495
author: Jean-Marc Valin <[email protected]>
date: Wed Apr 23 09:42:10 EDT 2008
Optimisation: caching the divisions used in the Laplace encoder.
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -301,7 +301,7 @@
/* Compute MDCTs of the pitch part */
compute_mdcts(st->mode, st->mode->window, st->out_mem+pitch_index*C, freq);
- quant_energy(st->mode, bandE, st->oldBandE, nbCompressedBytes*8/3, &st->enc);
+ quant_energy(st->mode, bandE, st->oldBandE, nbCompressedBytes*8/3, st->mode->prob, &st->enc);
if (C==2)
{
@@ -573,7 +573,7 @@
ec_dec_init(&dec,&buf);
/* Get band energies */
- unquant_energy(st->mode, bandE, st->oldBandE, len*8/3, &dec);
+ unquant_energy(st->mode, bandE, st->oldBandE, len*8/3, st->mode->prob, &dec);
/* Get the pitch gains */
has_pitch = unquant_pitch(gains, st->mode->nbPBands, &dec);
--- a/libcelt/dump_modes.c
+++ b/libcelt/dump_modes.c
@@ -159,6 +159,7 @@
fprintf(file, "{%d, 0, 0},\t/* mdct */\n", 2*mode->mdctSize);
fprintf(file, "window%d,\t/* window */\n", mode->overlap);
fprintf(file, "{psy_decayR_%d},\t/* psy */\n", mode->Fs);
+ fprintf(file, "0,\t/* prob */\n");
fprintf(file, "0x%x,\t/* marker */\n", 0xa110ca7e);
fprintf(file, "};\n");
}
--- a/libcelt/laplace.c
+++ b/libcelt/laplace.c
@@ -35,15 +35,15 @@
#include "laplace.h"
-static int ec_laplace_get_start_freq(int decay)
+int ec_laplace_get_start_freq(int decay)
{
return (((ec_uint32)32767)*(16384-decay))/(16384+decay);
}
-void ec_laplace_encode(ec_enc *enc, int value, int decay)
+void ec_laplace_encode_start(ec_enc *enc, int value, int decay, int fs)
{
int i;
- int fl, fs, ft;
+ int fl, ft;
int s = 0;
if (value < 0)
{
@@ -51,7 +51,6 @@
value = -value;
}
ft = 32767;
- fs = ec_laplace_get_start_freq(decay);
fl = -fs;
for (i=0;i<value;i++)
{
@@ -76,13 +75,19 @@
ec_encode(enc, fl, fl+fs, ft);
}
-int ec_laplace_decode(ec_dec *dec, int decay)
+void ec_laplace_encode(ec_enc *enc, int value, int decay)
{
+ int fs = ec_laplace_get_start_freq(decay);
+ ec_laplace_encode_start(enc, value, decay, fs);
+}
+
+
+int ec_laplace_decode_start(ec_dec *dec, int decay, int fs)
+{
int val=0;
- int fl, fh, fs, ft, fm;
+ int fl, fh, ft, fm;
fl = 0;
ft = 32767;
- fs = ec_laplace_get_start_freq(decay);
fh = fs;
fm = ec_decode(dec, ft);
/*DEBUG*/
@@ -113,4 +118,8 @@
return val;
}
-
+int ec_laplace_decode(ec_dec *dec, int decay)
+{
+ int fs = ec_laplace_get_start_freq(decay);
+ return ec_laplace_decode_start(dec, decay, fs);
+}
--- a/libcelt/laplace.h
+++ b/libcelt/laplace.h
@@ -32,6 +32,8 @@
#include "entenc.h"
#include "entdec.h"
+int ec_laplace_get_start_freq(int decay);
+
/** Encode a value that is assumed to be the realisation of a
Laplace-distributed random process
@param enc Entropy encoder state
@@ -40,6 +42,8 @@
*/
void ec_laplace_encode(ec_enc *enc, int value, int decay);
+void ec_laplace_encode_start(ec_enc *enc, int value, int decay, int fs);
+
/** Decode a value that is assumed to be the realisation of a
Laplace-distributed random process
@param dec Entropy decoder state
@@ -47,3 +51,5 @@
@return Value decoded
*/
int ec_laplace_decode(ec_dec *dec, int decay);
+
+int ec_laplace_decode_start(ec_dec *dec, int decay, int fs);
--- a/libcelt/modes.c
+++ b/libcelt/modes.c
@@ -38,6 +38,7 @@
#include "rate.h"
#include "os_support.h"
#include "stack_alloc.h"
+#include "quant_bands.h"
#ifdef STATIC_MODES
#include "static_modes.c"
@@ -319,6 +320,7 @@
mode->marker_end = MODEVALID;
#endif /* !STATIC_MODES */
mdct_init(&mode->mdct, 2*mode->mdctSize);
+ mode->prob = quant_prob_alloc(mode);
if (error)
*error = CELT_OK;
return mode;
@@ -353,6 +355,7 @@
#endif
#endif
mdct_clear(&mode->mdct);
+ quant_prob_free(mode->prob);
celt_free((CELTMode *)mode);
}
--- a/libcelt/modes.h
+++ b/libcelt/modes.h
@@ -93,6 +93,8 @@
struct PsyDecay psy;
+ int *prob;
+
celt_uint32_t marker_end;
};
--- a/libcelt/pitch.c
+++ b/libcelt/pitch.c
@@ -115,6 +115,7 @@
#endif
celt_word16_t * restrict X, * restrict Y;
celt_word16_t * restrict Xptr, * restrict Yptr;
+ const celt_sig_t * restrict yptr;
int n2;
int L2;
const int C = CHANNELS(m);
@@ -164,11 +165,19 @@
/* Deferred allocation to reduce peak stack usage */
ALLOC(_Y, lag, celt_word16_t);
Y = _Y;
- CELT_MEMSET(Y,0,lag);
- /* Sum all channels of the past audio and copy into Y in bit-reverse order */
- for (c=0;c<C;c++)
+ yptr = &y[0];
+ /* Copy first channel of the past audio into Y in bit-reverse order */
+ for (i=0;i<n2;i++)
{
- const celt_sig_t * restrict yptr = &y[c];
+ Y[2*BITREV(fft,i)] = SHR32(*yptr,INPUT_SHIFT);
+ yptr += C;
+ Y[2*BITREV(fft,i)+1] = SHR32(*yptr,INPUT_SHIFT);
+ yptr += C;
+ }
+ /* Add remaining channels into Y in bit-reverse order */
+ for (c=1;c<C;c++)
+ {
+ yptr = &y[c];
for (i=0;i<n2;i++)
{
Y[2*BITREV(fft,i)] += SHR32(*yptr,INPUT_SHIFT);
--- a/libcelt/quant_bands.c
+++ b/libcelt/quant_bands.c
@@ -129,9 +129,27 @@
static const celt_word16_t base_resolution = QCONST16(6.f,8);
-static void quant_energy_mono(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, unsigned budget, ec_enc *enc)
+int *quant_prob_alloc(const CELTMode *m)
{
int i;
+ int *prob;
+ prob = celt_alloc(2*m->nbEBands*sizeof(int));
+ for (i=0;i<m->nbEBands;i++)
+ {
+ prob[2*i] = 6000-i*200;
+ prob[2*i+1] = ec_laplace_get_start_freq(prob[2*i]);
+ }
+ return prob;
+}
+
+void quant_prob_free(int *freq)
+{
+ celt_free(freq);
+}
+
+static void quant_energy_mono(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, unsigned budget, int *prob, ec_enc *enc)
+{
+ int i;
unsigned bits;
celt_word16_t prev = 0;
celt_word16_t coef = m->ePredCoef;
@@ -163,7 +181,7 @@
if (ec_enc_tell(enc, 0) - bits > budget)
qi = -1;
else
- ec_laplace_encode(enc, qi, 6000-i*200);
+ ec_laplace_encode_start(enc, qi, prob[2*i], prob[2*i+1]);
q = qi*base_resolution;
error[i] = f - SHL16(qi,8);
@@ -202,7 +220,7 @@
RESTORE_STACK;
}
-static void unquant_energy_mono(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, unsigned budget, ec_dec *dec)
+static void unquant_energy_mono(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, unsigned budget, int *prob, ec_dec *dec)
{
int i;
unsigned bits;
@@ -222,7 +240,7 @@
if (ec_dec_tell(dec, 0) - bits > budget)
qi = -1;
else
- qi = ec_laplace_decode(dec, 6000-i*200);
+ qi = ec_laplace_decode_start(dec, prob[2*i], prob[2*i+1]);
q = qi*base_resolution;
oldEBands[i] = mean+MULT16_16_Q15(coef,oldEBands[i])+prev+q;
@@ -249,7 +267,7 @@
-void quant_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int budget, ec_enc *enc)
+void quant_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int budget, int *prob, ec_enc *enc)
{
int C;
SAVE_STACK;
@@ -257,7 +275,7 @@
C = m->nbChannels;
if (C==1)
- quant_energy_mono(m, eBands, oldEBands, budget, enc);
+ quant_energy_mono(m, eBands, oldEBands, budget, prob, enc);
else
#if 1
{
@@ -269,7 +287,7 @@
int i;
for (i=0;i<m->nbEBands;i++)
E[i] = eBands[C*i+c];
- quant_energy_mono(m, E, oldEBands+c*m->nbEBands, budget/C, enc);
+ quant_energy_mono(m, E, oldEBands+c*m->nbEBands, budget/C, prob, enc);
for (i=0;i<m->nbEBands;i++)
eBands[C*i+c] = E[i];
}
@@ -311,7 +329,7 @@
-void unquant_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int budget, ec_dec *dec)
+void unquant_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int budget, int *prob, ec_dec *dec)
{
int C;
SAVE_STACK;
@@ -318,7 +336,7 @@
C = m->nbChannels;
if (C==1)
- unquant_energy_mono(m, eBands, oldEBands, budget, dec);
+ unquant_energy_mono(m, eBands, oldEBands, budget, prob, dec);
else {
int c;
VARDECL(celt_ener_t, E);
@@ -326,7 +344,7 @@
for (c=0;c<C;c++)
{
int i;
- unquant_energy_mono(m, E, oldEBands+c*m->nbEBands, budget/C, dec);
+ unquant_energy_mono(m, E, oldEBands+c*m->nbEBands, budget/C, prob, dec);
for (i=0;i<m->nbEBands;i++)
eBands[C*i+c] = E[i];
}
--- a/libcelt/quant_bands.h
+++ b/libcelt/quant_bands.h
@@ -37,8 +37,11 @@
#include "entenc.h"
#include "entdec.h"
-void quant_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int budget, ec_enc *enc);
+int *quant_prob_alloc(const CELTMode *m);
+void quant_prob_free(int *freq);
-void unquant_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int budget, ec_dec *dec);
+void quant_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int budget, int *prob, ec_enc *enc);
+
+void unquant_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int budget, int *prob, ec_dec *dec);
#endif /* QUANT_BANDS */