Commit 25358cd4 authored by Jean-Marc Valin's avatar Jean-Marc Valin
Browse files

Merged the rate allocation atruct directly into the mode struct.

parent 224d2dab
......@@ -206,7 +206,7 @@ void pitch_quant_bands(const CELTMode *m, float *X, float *P, float *gains)
/* Quantisation of the residual */
void quant_bands(const CELTMode *m, float *X, float *P, float *W, struct alloc_data *alloc, int total_bits, ec_enc *enc)
void quant_bands(const CELTMode *m, float *X, float *P, float *W, int total_bits, ec_enc *enc)
{
int i, j, B, bits;
const int *eBands = m->eBands;
......@@ -220,7 +220,7 @@ void quant_bands(const CELTMode *m, float *X, float *P, float *W, struct alloc_d
offsets[i] = 0;
/* Use a single-bit margin to guard against overrunning (make sure it's enough) */
bits = total_bits - ec_enc_tell(enc, 0) - 1;
compute_allocation(alloc, offsets, bits, pulses);
compute_allocation(m, offsets, bits, pulses);
/*printf("bits left: %d\n", bits);
for (i=0;i<m->nbEBands;i++)
......@@ -267,7 +267,7 @@ void quant_bands(const CELTMode *m, float *X, float *P, float *W, struct alloc_d
}
/* Decoding of the residual */
void unquant_bands(const CELTMode *m, float *X, float *P, struct alloc_data *alloc, int total_bits, ec_dec *dec)
void unquant_bands(const CELTMode *m, float *X, float *P, int total_bits, ec_dec *dec)
{
int i, j, B, bits;
const int *eBands = m->eBands;
......@@ -281,7 +281,7 @@ void unquant_bands(const CELTMode *m, float *X, float *P, struct alloc_data *all
offsets[i] = 0;
/* Use a single-bit margin to guard against overrunning (make sure it's enough) */
bits = total_bits - ec_dec_tell(dec, 0) - 1;
compute_allocation(alloc, offsets, bits, pulses);
compute_allocation(m, offsets, bits, pulses);
for (i=0;i<m->nbEBands;i++)
{
......
......@@ -80,7 +80,7 @@ void pitch_quant_bands(const CELTMode *m, float *X, float *P, float *gains);
* @param W Perceptual weighting
* @param enc Entropy encoder
*/
void quant_bands(const CELTMode *m, float *X, float *P, float *W, struct alloc_data *alloc, int total_bits, ec_enc *enc);
void quant_bands(const CELTMode *m, float *X, float *P, float *W, int total_bits, ec_enc *enc);
/** Decoding of the residual spectrum
* @param m Mode data
......@@ -88,7 +88,7 @@ void quant_bands(const CELTMode *m, float *X, float *P, float *W, struct alloc_d
* @param P Pitch vector (normalised)
* @param dec Entropy decoder
*/
void unquant_bands(const CELTMode *m, float *X, float *P, struct alloc_data *alloc, int total_bits, ec_dec *dec);
void unquant_bands(const CELTMode *m, float *X, float *P, int total_bits, ec_dec *dec);
void stereo_mix(const CELTMode *m, float *X, float *bank, int dir);
......
......@@ -72,8 +72,6 @@ struct CELTEncoder {
float *out_mem;
float *oldBandE;
struct alloc_data alloc;
};
......@@ -118,7 +116,6 @@ CELTEncoder *celt_encoder_new(const CELTMode *mode)
st->preemph_memE = celt_alloc(C*sizeof(float));;
st->preemph_memD = celt_alloc(C*sizeof(float));;
alloc_init(&st->alloc, st->mode);
return st;
}
......@@ -145,8 +142,6 @@ void celt_encoder_destroy(CELTEncoder *st)
celt_free(st->preemph_memE);
celt_free(st->preemph_memD);
alloc_clear(&st->alloc);
celt_free(st);
}
......@@ -331,7 +326,7 @@ int celt_encode(CELTEncoder *st, celt_int16_t *pcm, unsigned char *compressed, i
sum += X[i]*X[i];
printf ("%f\n", sum);*/
/* Residual quantisation */
quant_bands(st->mode, X, P, mask, &st->alloc, nbCompressedBytes*8, &st->enc);
quant_bands(st->mode, X, P, mask, nbCompressedBytes*8, &st->enc);
if (C==2)
stereo_mix(st->mode, X, bandE, -1);
......@@ -427,8 +422,6 @@ struct CELTDecoder {
float *oldBandE;
int last_pitch_index;
struct alloc_data alloc;
};
CELTDecoder *celt_decoder_new(const CELTMode *mode)
......@@ -467,8 +460,6 @@ CELTDecoder *celt_decoder_new(const CELTMode *mode)
st->preemph_memD = celt_alloc(C*sizeof(float));;
st->last_pitch_index = 0;
alloc_init(&st->alloc, st->mode);
return st;
}
......@@ -490,8 +481,6 @@ void celt_decoder_destroy(CELTDecoder *st)
celt_free(st->preemph_memD);
alloc_clear(&st->alloc);
celt_free(st);
}
......@@ -587,7 +576,7 @@ int celt_decode(CELTDecoder *st, unsigned char *data, int len, celt_int16_t *pcm
pitch_quant_bands(st->mode, X, P, gains);
/* Decode fixed codebook and merge with pitch */
unquant_bands(st->mode, X, P, &st->alloc, len*8, &dec);
unquant_bands(st->mode, X, P, len*8, &dec);
if (C==2)
stereo_mix(st->mode, X, bandE, -1);
......
......@@ -57,7 +57,7 @@ int celt_mode_info(const CELTMode *mode, int request, celt_int32_t *value)
/* Defining 25 critical bands for the full 0-20 kHz audio bandwidth
Taken from http://ccrma.stanford.edu/~jos/bbt/Bark_Frequency_Scale.html */
#define BARK_BANDS 25
const celt_int16_t bark_freq[BARK_BANDS+1] = {
static const celt_int16_t bark_freq[BARK_BANDS+1] = {
0, 100, 200, 300, 400,
510, 630, 770, 920, 1080,
1270, 1480, 1720, 2000, 2320,
......@@ -65,12 +65,12 @@ const celt_int16_t bark_freq[BARK_BANDS+1] = {
6400, 7700, 9500, 12000, 15500,
20000};
const celt_int16_t pitch_freq[PBANDS+1] ={0, 345, 689, 1034, 1378, 2067, 3273, 5340, 6374};
static const celt_int16_t pitch_freq[PBANDS+1] ={0, 345, 689, 1034, 1378, 2067, 3273, 5340, 6374};
/* This allocation table is per critical band. When creating a mode, the bits get added together
into the codec bands, which are sometimes larger than one critical band at low frequency */
#define BITALLOC_SIZE 10
int band_allocation[BARK_BANDS*BITALLOC_SIZE] =
static const int band_allocation[BARK_BANDS*BITALLOC_SIZE] =
{ 2, 2, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0,
2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 3, 2, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0,
......@@ -199,6 +199,8 @@ static void compute_allocation_table(CELTMode *mode, int res)
mode->allocVectors = allocVectors;
}
CELTMode *celt_mode_create(int Fs, int channels, int frame_size, int lookahead, int *error)
{
int res;
......@@ -246,15 +248,29 @@ CELTMode *celt_mode_create(int Fs, int channels, int frame_size, int lookahead,
mode->ePredCoef = .8;
compute_allocation_table(mode, res);
compute_alloc_cache(mode);
//printf ("%d bands\n", mode->nbEBands);
return mode;
}
void celt_mode_destroy(CELTMode *mode)
{
int i;
const int *prevPtr = NULL;
celt_free((int*)mode->eBands);
celt_free((int*)mode->pBands);
celt_free((int*)mode->allocVectors);
for (i=0;i<mode->nbEBands;i++)
{
if (mode->bits[i] != prevPtr)
{
prevPtr = mode->bits[i];
celt_free((int*)mode->bits[i]);
}
}
celt_free((int**)mode->bits);
celt_free((CELTMode *)mode);
}
......@@ -52,6 +52,9 @@ struct CELTMode {
int nbAllocVectors;
const int *allocVectors;
const int * const *bits;
};
#endif
......@@ -44,7 +44,7 @@
#define MAX_PULSES 64
int log2_frac(ec_uint32 val, int frac)
static int log2_frac(ec_uint32 val, int frac)
{
int i;
/* EC_ILOG() actually returns log2()+1, go figure */
......@@ -68,7 +68,7 @@ int log2_frac(ec_uint32 val, int frac)
return L;
}
int log2_frac64(ec_uint64 val, int frac)
static int log2_frac64(ec_uint64 val, int frac)
{
int i;
/* EC_ILOG64() actually returns log2()+1, go figure */
......@@ -92,43 +92,40 @@ int log2_frac64(ec_uint64 val, int frac)
return L;
}
void alloc_init(struct alloc_data *alloc, const CELTMode *m)
void compute_alloc_cache(CELTMode *m)
{
int i, prevN, BC;
int **bits;
const int *eBands = m->eBands;
alloc->mode = m;
alloc->len = m->nbEBands;
alloc->bands = m->eBands;
alloc->bits = celt_alloc(m->nbEBands*sizeof(int*));
bits = celt_alloc(m->nbEBands*sizeof(int*));
BC = m->nbMdctBlocks*m->nbChannels;
prevN = -1;
for (i=0;i<alloc->len;i++)
for (i=0;i<m->nbEBands;i++)
{
int N = BC*(eBands[i+1]-eBands[i]);
if (N == prevN && eBands[i] < m->pitchEnd)
{
alloc->bits[i] = alloc->bits[i-1];
bits[i] = bits[i-1];
} else {
int j;
/* FIXME: We could save memory here */
alloc->bits[i] = celt_alloc(MAX_PULSES*sizeof(int));
bits[i] = celt_alloc(MAX_PULSES*sizeof(int));
for (j=0;j<MAX_PULSES;j++)
{
int done = 0;
int pulses = j;
/* For bands where there's no pitch, id 1 corresponds to intra prediction
with no pulse. id 2 means intra prediction with one pulse, and so on.*/
with no pulse. id 2 means intra prediction with one pulse, and so on.*/
if (eBands[i] >= m->pitchEnd)
pulses -= 1;
if (pulses < 0)
alloc->bits[i][j] = 0;
bits[i][j] = 0;
else {
alloc->bits[i][j] = log2_frac64(ncwrs64(N, pulses),BITRES);
bits[i][j] = log2_frac64(ncwrs64(N, pulses),BITRES);
/* FIXME: Could there be a better test for the max number of pulses that fit in 64 bits? */
if (alloc->bits[i][j] > (60<<BITRES))
if (bits[i][j] > (60<<BITRES))
done = 1;
/* Add the intra-frame prediction bits */
if (eBands[i] >= m->pitchEnd)
......@@ -136,35 +133,22 @@ void alloc_init(struct alloc_data *alloc, const CELTMode *m)
int max_pos = 2*eBands[i]-eBands[i+1];
if (max_pos > 32)
max_pos = 32;
alloc->bits[i][j] += (1<<BITRES) + log2_frac(max_pos,BITRES);
bits[i][j] += (1<<BITRES) + log2_frac(max_pos,BITRES);
}
}
if (done)
break;
}
for (;j<MAX_PULSES;j++)
alloc->bits[i][j] = BITOVERFLOW;
bits[i][j] = BITOVERFLOW;
prevN = N;
}
}
m->bits = (const int * const *)bits;
}
void alloc_clear(struct alloc_data *alloc)
{
int i;
int *prevPtr = NULL;
for (i=0;i<alloc->len;i++)
{
if (alloc->bits[i] != prevPtr)
{
prevPtr = alloc->bits[i];
celt_free(alloc->bits[i]);
}
}
celt_free(alloc->bits);
}
int bits2pulses(const struct alloc_data *alloc, int band, int bits)
int bits2pulses(const CELTMode *m, int band, int bits)
{
int lo, hi;
lo = 0;
......@@ -173,38 +157,38 @@ int bits2pulses(const struct alloc_data *alloc, int band, int bits)
while (hi-lo != 1)
{
int mid = (lo+hi)>>1;
if (alloc->bits[band][mid] >= bits)
if (m->bits[band][mid] >= bits)
hi = mid;
else
lo = mid;
}
if (bits-alloc->bits[band][lo] <= alloc->bits[band][hi]-bits)
if (bits-m->bits[band][lo] <= m->bits[band][hi]-bits)
return lo;
else
return hi;
}
int vec_bits2pulses(const struct alloc_data *alloc, const int *bands, int *bits, int *pulses, int len)
int vec_bits2pulses(const CELTMode *m, const int *bands, int *bits, int *pulses, int len)
{
int i, BC;
int sum=0;
BC = alloc->mode->nbMdctBlocks*alloc->mode->nbChannels;
BC = m->nbMdctBlocks*m->nbChannels;
for (i=0;i<len;i++)
{
pulses[i] = bits2pulses(alloc, i, bits[i]);
sum += alloc->bits[i][pulses[i]];
pulses[i] = bits2pulses(m, i, bits[i]);
sum += m->bits[i][pulses[i]];
}
//printf ("sum = %d\n", sum);
return sum;
}
int interp_bits2pulses(const struct alloc_data *alloc, int *bits1, int *bits2, int total, int *pulses, int len)
int interp_bits2pulses(const CELTMode *m, int *bits1, int *bits2, int total, int *pulses, int len)
{
int lo, hi, out;
int j;
int bits[len];
const int *bands = alloc->bands;
const int *bands = m->eBands;
lo = 0;
hi = 1<<BITRES;
while (hi-lo != 1)
......@@ -212,7 +196,7 @@ int interp_bits2pulses(const struct alloc_data *alloc, int *bits1, int *bits2, i
int mid = (lo+hi)>>1;
for (j=0;j<len;j++)
bits[j] = ((1<<BITRES)-mid)*bits1[j] + mid*bits2[j];
if (vec_bits2pulses(alloc, bands, bits, pulses, len) > total<<BITRES)
if (vec_bits2pulses(m, bands, bits, pulses, len) > total<<BITRES)
hi = mid;
else
lo = mid;
......@@ -220,7 +204,7 @@ int interp_bits2pulses(const struct alloc_data *alloc, int *bits1, int *bits2, i
//printf ("interp bisection gave %d\n", lo);
for (j=0;j<len;j++)
bits[j] = ((1<<BITRES)-lo)*bits1[j] + lo*bits2[j];
out = vec_bits2pulses(alloc, bands, bits, pulses, len);
out = vec_bits2pulses(m, bands, bits, pulses, len);
/* Do some refinement to use up all bits. In the first pass, we can only add pulses to
bands that are under their allocated budget. In the second pass, anything goes */
int firstpass = 1;
......@@ -229,11 +213,11 @@ int interp_bits2pulses(const struct alloc_data *alloc, int *bits1, int *bits2, i
int incremented = 0;
for (j=0;j<len;j++)
{
if ((!firstpass || alloc->bits[j][pulses[j]] < bits[j]) && pulses[j]<MAX_PULSES-1)
if ((!firstpass || m->bits[j][pulses[j]] < bits[j]) && pulses[j]<MAX_PULSES-1)
{
if (out+alloc->bits[j][pulses[j]+1]-alloc->bits[j][pulses[j]] <= total<<BITRES)
if (out+m->bits[j][pulses[j]+1]-m->bits[j][pulses[j]] <= total<<BITRES)
{
out = out+alloc->bits[j][pulses[j]+1]-alloc->bits[j][pulses[j]];
out = out+m->bits[j][pulses[j]+1]-m->bits[j][pulses[j]];
pulses[j] += 1;
incremented = 1;
//printf ("INCREMENT %d\n", j);
......@@ -251,12 +235,10 @@ int interp_bits2pulses(const struct alloc_data *alloc, int *bits1, int *bits2, i
return (out+BITROUND) >> BITRES;
}
int compute_allocation(const struct alloc_data *alloc, int *offsets, int total, int *pulses)
int compute_allocation(const CELTMode *m, int *offsets, int total, int *pulses)
{
int lo, hi, len;
const CELTMode *m;
m = alloc->mode;
len = m->nbEBands;
lo = 0;
hi = m->nbAllocVectors - 1;
......@@ -274,7 +256,7 @@ int compute_allocation(const struct alloc_data *alloc, int *offsets, int total,
//printf ("%d ", bits[j]);
}
//printf ("\n");
if (vec_bits2pulses(alloc, alloc->bands, bits, pulses, len) > total<<BITRES)
if (vec_bits2pulses(m, m->eBands, bits, pulses, len) > total<<BITRES)
hi = mid;
else
lo = mid;
......@@ -293,7 +275,7 @@ int compute_allocation(const struct alloc_data *alloc, int *offsets, int total,
if (bits2[j] < 0)
bits2[j] = 0;
}
return interp_bits2pulses(alloc, bits1, bits2, total, pulses, len);
return interp_bits2pulses(m, bits1, bits2, total, pulses, len);
}
}
......
......@@ -32,18 +32,9 @@
#ifndef RATE_H
#define RATE_H
struct alloc_data {
const CELTMode *mode;
int len;
const int *bands;
int **bits;
};
void alloc_init(struct alloc_data *alloc, const CELTMode *m);
void compute_alloc_cache(CELTMode *m);
void alloc_clear(struct alloc_data *alloc);
int compute_allocation(const struct alloc_data *alloc, int *offsets, int total, int *pulses);
int compute_allocation(const CELTMode *m, int *offsets, int total, int *pulses);
#endif
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment