ref: 26c9e1452ae9941e49791dc3acf5dd8d487e876f
parent: 0d227d86e5ae13900d2de570205b77d3097fbc11
author: Jean-Marc Valin <[email protected]>
date: Mon Dec 31 16:27:54 EST 2007
Comments/cleanup, no code change
--- a/libcelt/bands.c
+++ b/libcelt/bands.c
@@ -36,7 +36,8 @@
#include "cwrs.h"
/* Applies a series of rotations so that pulses are spread like a two-sided
-exponential */
+exponential. The effect of this is to reduce the tonal noise created by the
+sparse spectrum resulting from the pulse codebook */
static void exp_rotation(float *X, int len, float theta, int dir, int stride, int iter)
{
int i, k;
@@ -87,7 +88,7 @@
}
}
-/* Compute the energy in each of the bands */
+/* Compute the amplitude (sqrt energy) in each of the bands */
void compute_band_energies(const CELTMode *m, float *X, float *bank)
{
int i, B;
@@ -197,6 +198,7 @@
P[i] = 0;
}
+/* Quantisation of the residual */
void quant_bands(const CELTMode *m, float *X, float *P, float *W, ec_enc *enc)
{
int i, j, B;
@@ -234,6 +236,7 @@
X[i] = 0;
}
+/* Decoding of the residual */
void unquant_bands(const CELTMode *m, float *X, float *P, ec_dec *dec)
{
int i, j, B;
--- a/libcelt/bands.h
+++ b/libcelt/bands.h
@@ -37,18 +37,54 @@
#include "entenc.h"
#include "entdec.h"
+/** Compute the amplitude (sqrt energy) in each of the bands
+ * @param m Mode data
+ * @param X Spectrum
+ * @param bands Square root of the energy for each band (returned)
+ */
void compute_band_energies(const CELTMode *m, float *X, float *bands);
+/** Normalise each band of X such that the energy in each band is
+ equal to 1
+ * @param m Mode data
+ * @param X Spectrum (returned normalised)
+ * @param bands Square root of the energy for each band
+ */
void normalise_bands(const CELTMode *m, float *X, float *bands);
+/** Denormalise each band of X to restore full amplitude
+ * @param m Mode data
+ * @param X Spectrum (returned de-normalised)
+ * @param bands Square root of the energy for each band
+ */
void denormalise_bands(const CELTMode *m, float *X, float *bands);
+/** Compute the pitch predictor gain for each pitch band
+ * @param m Mode data
+ * @param X Spectrum to predict
+ * @param P Pitch vector (normalised)
+ * @param gains Gain computed for each pitch band (returned)
+ * @param bank Square root of the energy for each band
+ */
void compute_pitch_gain(const CELTMode *m, float *X, float *P, float *gains, float *bank);
void pitch_quant_bands(const CELTMode *m, float *X, float *P, float *gains);
+/** Quantisation/encoding of the residual spectrum
+ * @param m Mode data
+ * @param X Residual (normalised)
+ * @param P Pitch vector (normalised)
+ * @param W Perceptual weighting
+ * @param enc Entropy encoder
+ */
void quant_bands(const CELTMode *m, float *X, float *P, float *W, ec_enc *enc);
+/** Decoding of the residual spectrum
+ * @param m Mode data
+ * @param X Residual (normalised)
+ * @param P Pitch vector (normalised)
+ * @param dec Entropy decoder
+*/
void unquant_bands(const CELTMode *m, float *X, float *P, ec_dec *dec);
#endif /* BANDS_H */
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -282,6 +282,7 @@
haar1(P, B*N*C, 1);
}
+ /* Get a tiny bit more frequency resolution and prevent unstable energy when quantising */
time_dct(X, N, B, C);
time_dct(P, N, B, C);
@@ -289,18 +290,16 @@
compute_band_energies(st->mode, X, bandE);
normalise_bands(st->mode, X, bandE);
//for (i=0;i<st->mode->nbEBands;i++)printf("%f ", bandE[i]);printf("\n");
-
+
+ /* Normalise the pitch vector as well (discard the energies) */
{
float bandEp[st->mode->nbEBands];
compute_band_energies(st->mode, P, bandEp);
normalise_bands(st->mode, P, bandEp);
}
-
- //band_rotation(st->mode, X, -1);
- //band_rotation(st->mode, P, -1);
-
+
quant_energy(st->mode, bandE, st->oldBandE, &st->enc);
-
+
/* Pitch prediction */
compute_pitch_gain(st->mode, X, P, gains, bandE);
quant_pitch(gains, st->mode->nbPBands, &st->enc);
@@ -307,7 +306,7 @@
pitch_quant_bands(st->mode, X, P, gains);
//for (i=0;i<B*N;i++) printf("%f ",P[i]);printf("\n");
- /* Subtract the pitch prediction from the signal to encode */
+ /* Compute residual that we're going to encode */
for (i=0;i<B*C*N;i++)
X[i] -= P[i];
@@ -317,19 +316,7 @@
printf ("%f\n", sum);*/
/* Residual quantisation */
quant_bands(st->mode, X, P, mask, &st->enc);
-
- if (0) {//This is just for debugging
- ec_enc_done(&st->enc);
- ec_dec dec;
- ec_byte_readinit(&st->buf,ec_byte_get_buffer(&st->buf),ec_byte_bytes(&st->buf));
- ec_dec_init(&dec,&st->buf);
- unquant_bands(st->mode, X, P, &dec);
- //printf ("\n");
- }
-
- //band_rotation(st->mode, X, 1);
-
/* Synthesis */
denormalise_bands(st->mode, X, bandE);
@@ -336,11 +323,11 @@
time_idct(X, N, B, C);
if (C==2)
haar1(X, B*N*C, 1);
-
+
CELT_MOVE(st->out_mem, st->out_mem+C*B*N, C*(MAX_PERIOD-B*N));
- /* Compute inverse MDCTs */
- compute_inv_mdcts(&st->mdct_lookup, st->window, X, st->out_mem, st->mdct_overlap, N, B, C);
+ compute_inv_mdcts(&st->mdct_lookup, st->window, X, st->out_mem, st->mdct_overlap, N, B, C);
+ /* De-emphasis and put everything back at the right place in the synthesis history */
for (c=0;c<C;c++)
{
for (i=0;i<B;i++)
@@ -532,7 +519,6 @@
compute_band_energies(st->mode, P, bandEp);
normalise_bands(st->mode, P, bandEp);
}
- //band_rotation(st->mode, P, -1);
/* Get the pitch gains */
unquant_pitch(gains, st->mode->nbPBands, &dec);
@@ -543,8 +529,6 @@
/* Decode fixed codebook and merge with pitch */
unquant_bands(st->mode, X, P, &dec);
- //band_rotation(st->mode, X, 1);
-
/* Synthesis */
denormalise_bands(st->mode, X, bandE);
--- a/libcelt/vq.h
+++ b/libcelt/vq.h
@@ -36,13 +36,41 @@
#include "entdec.h"
-/* Algebraic pulse-based quantiser. The signal x is replaced by the sum of the pitch
- a combination of pulses such that its norm is still equal to 1. The only difference with
- the quantiser above is that the search is more complete. */
+/** Algebraic pulse-based quantiser. The signal x is replaced by the sum of the
+ * pitch a combination of pulses such that its norm is still equal to 1. The
+ * only difference with the quantiser above is that the search is more complete.
+ * @param x Residual signal to quantise/encode (returns quantised version)
+ * @param W Perceptual weight
+ * @param N Number of samples to encode
+ * @param K Number of pulses to use
+ * @param p Pitch vector (it is assumed that p+x is a unit vector)
+ * @param alpha compression factor in the pitch direction (magic!)
+ * @param enc Entropy encoder state
+*/
void alg_quant(float *x, float *W, int N, int K, float *p, float alpha, ec_enc *enc);
+/** Algebraic pulse decoder
+ * @param x Decoded normalised spectrum (returned)
+ * @param N Number of samples to decode
+ * @param K Number of pulses to use
+ * @param p Pitch vector (automatically added to x)
+ * @param alpha compression factor in the pitch direction (magic!)
+ * @param dec Entropy decoder state
+ */
void alg_unquant(float *x, int N, int K, float *p, float alpha, ec_dec *dec);
+/** Intra-frame predictor that matches a section of the current frame (at lower
+ * frequencies) to encode the current band.
+ * @param x Residual signal to quantise/encode (returns quantised version)
+ * @param W Perceptual weight
+ * @param N Number of samples to encode
+ * @param K Number of pulses to use
+ * @param Y Lower frequency spectrum to use, normalised to the same standard deviation
+ * @param p Pitch vector (it is assumed that p+x is a unit vector)
+ * @param B Stride (number of channels multiplied by the number of MDCTs per frame)
+ * @param N0 Number of valid offsets
+ * @param enc Entropy encoder state
+ */
void intra_prediction(float *x, float *W, int N, int K, float *Y, float *P, int B, int N0, ec_enc *enc);
void intra_unquant(float *x, int N, int K, float *Y, float *P, int B, int N0, ec_dec *dec);