ref: 7b0cb4ba0d2b5117d8ed4dbe0ab49c21090c8854
parent: 98acefdc4abedeee79b26a482d99625048a37ed1
author: Jean-Marc Valin <[email protected]>
date: Wed Sep 10 20:20:08 EDT 2008
One-at-a-time allocator now uses direct feedback from ec_*_tell().
--- a/libcelt/bands.c
+++ b/libcelt/bands.c
@@ -41,6 +41,7 @@
#include "stack_alloc.h"
#include "os_support.h"
#include "mathops.h"
+#include "rate.h"
const celt_word16_t sqrtC_1[2] = {QCONST16(1.f, 14), QCONST16(1.414214f, 14)};
@@ -329,9 +330,9 @@
/* Quantisation of the residual */
-void quant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, celt_mask_t *W, const celt_ener_t *bandE, const int *stereo_mode, int *pulses, int shortBlocks, ec_enc *enc)
+void quant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, celt_mask_t *W, const celt_ener_t *bandE, const int *stereo_mode, int *pulses, int shortBlocks, int total_bits, ec_enc *enc)
{
- int i, j;
+ int i, j, remaining_bits, balance;
const celt_int16_t * restrict eBands = m->eBands;
celt_norm_t * restrict norm;
VARDECL(celt_norm_t, _norm);
@@ -343,6 +344,7 @@
ALLOC(_norm, C*eBands[m->nbEBands+1], celt_norm_t);
norm = _norm;
+ balance = 0;
/*printf("bits left: %d\n", bits);
for (i=0;i<m->nbEBands;i++)
printf ("(%d %d) ", pulses[i], ebits[i]);
@@ -350,9 +352,32 @@
/*printf ("%d %d\n", ec_enc_tell(enc, 0), compute_allocation(m, m->nbPulses));*/
for (i=0;i<m->nbEBands;i++)
{
+ int tell;
int q;
celt_word16_t n;
- q = pulses[i];
+
+ int curr_balance, curr_bits;
+
+ tell = ec_enc_tell(enc, 4);
+ if (i != 0)
+ balance -= tell;
+ remaining_bits = (total_bits<<BITRES)-tell-1;
+ curr_balance = (m->nbEBands-i);
+ if (curr_balance > 3)
+ curr_balance = 3;
+ curr_balance = balance / curr_balance;
+ q = bits2pulses(m, m->bits[i], pulses[i]+curr_balance);
+ curr_bits = m->bits[i][q];
+ remaining_bits -= curr_bits;
+ if (remaining_bits < 0)
+ {
+ q--;
+ remaining_bits += curr_bits;
+ curr_bits = m->bits[i][q];
+ remaining_bits -= curr_bits;
+ }
+ balance += pulses[i] + tell;
+
n = SHL16(celt_sqrt(C*(eBands[i+1]-eBands[i])),11);
/* If pitch isn't available, use intra-frame prediction */
@@ -389,9 +414,9 @@
}
/* Decoding of the residual */
-void unquant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, const celt_ener_t *bandE, const int *stereo_mode, int *pulses, int shortBlocks, ec_dec *dec)
+void unquant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, const celt_ener_t *bandE, const int *stereo_mode, int *pulses, int shortBlocks, int total_bits, ec_dec *dec)
{
- int i, j;
+ int i, j, remaining_bits, balance;
const celt_int16_t * restrict eBands = m->eBands;
celt_norm_t * restrict norm;
VARDECL(celt_norm_t, _norm);
@@ -403,11 +428,35 @@
ALLOC(_norm, C*eBands[m->nbEBands+1], celt_norm_t);
norm = _norm;
+ balance = 0;
for (i=0;i<m->nbEBands;i++)
{
+ int tell;
int q;
celt_word16_t n;
- q = pulses[i];
+
+ int curr_balance, curr_bits;
+
+ tell = ec_dec_tell(dec, 4);
+ if (i != 0)
+ balance -= tell;
+ remaining_bits = (total_bits<<BITRES)-tell-1;
+ curr_balance = (m->nbEBands-i);
+ if (curr_balance > 3)
+ curr_balance = 3;
+ curr_balance = balance / curr_balance;
+ q = bits2pulses(m, m->bits[i], pulses[i]+curr_balance);
+ curr_bits = m->bits[i][q];
+ remaining_bits -= curr_bits;
+ if (remaining_bits < 0)
+ {
+ q--;
+ remaining_bits += curr_bits;
+ curr_bits = m->bits[i][q];
+ remaining_bits -= curr_bits;
+ }
+ balance += pulses[i] + tell;
+
n = SHL16(celt_sqrt(C*(eBands[i+1]-eBands[i])),11);
/* If pitch isn't available, use intra-frame prediction */
--- a/libcelt/bands.h
+++ b/libcelt/bands.h
@@ -86,7 +86,7 @@
* @param total_bits Total number of bits that can be used for the frame (including the ones already spent)
* @param enc Entropy encoder
*/
-void quant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, celt_mask_t *W, const celt_ener_t *bandE, const int *stereo_mode, int *pulses, int time_domain, ec_enc *enc);
+void quant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, celt_mask_t *W, const celt_ener_t *bandE, const int *stereo_mode, int *pulses, int time_domain, int total_bits, ec_enc *enc);
/** Decoding of the residual spectrum
* @param m Mode data
@@ -95,7 +95,7 @@
* @param total_bits Total number of bits that can be used for the frame (including the ones already spent)
* @param dec Entropy decoder
*/
-void unquant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, const celt_ener_t *bandE, const int *stereo_mode, int *pulses, int time_domain, ec_dec *dec);
+void unquant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, const celt_ener_t *bandE, const int *stereo_mode, int *pulses, int time_domain, int total_bits, ec_dec *dec);
void stereo_decision(const CELTMode *m, celt_norm_t * restrict X, int *stereo_mode, int len);
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -597,7 +597,7 @@
/*for (i=0;i<B*N;i++) printf("%f ",P[i]);printf("\n");*/
/* Residual quantisation */
- quant_bands(st->mode, X, P, NULL, bandE, stereo_mode, pulses, shortBlocks, &st->enc);
+ quant_bands(st->mode, X, P, NULL, bandE, stereo_mode, pulses, shortBlocks, nbCompressedBytes*8, &st->enc);
if (st->pitch_enabled)
{
@@ -625,6 +625,7 @@
}
#endif
}
+ /*fprintf (stderr, "remaining bits after encode = %d\n", nbCompressedBytes*8-ec_enc_tell(&st->enc, 0));*/
/*if (ec_enc_tell(&st->enc, 0) < nbCompressedBytes*8 - 7)
celt_warning_int ("many unused bits: ", nbCompressedBytes*8-ec_enc_tell(&st->enc, 0));*/
/*printf ("%d\n", ec_enc_tell(&st->enc, 0)-8*nbCompressedBytes);*/
@@ -974,7 +975,7 @@
pitch_quant_bands(st->mode, P, gains);
/* Decode fixed codebook and merge with pitch */
- unquant_bands(st->mode, X, P, bandE, stereo_mode, pulses, shortBlocks, &dec);
+ unquant_bands(st->mode, X, P, bandE, stereo_mode, pulses, shortBlocks, len*8, &dec);
if (C==2)
{
--- a/libcelt/rate.c
+++ b/libcelt/rate.c
@@ -42,9 +42,6 @@
#include "entcode.h"
#include "rate.h"
-#define BITRES 4
-#define BITROUND 8
-#define BITOVERFLOW 30000
#ifndef STATIC_MODES
@@ -93,31 +90,8 @@
#endif /* !STATIC_MODES */
-static inline int bits2pulses(const CELTMode *m, const celt_int16_t *cache, int bits)
-{
- int i;
- int lo, hi;
- lo = 0;
- hi = MAX_PULSES-1;
-
- /* Instead of using the "bisection condition" we use a fixed number of
- iterations because it should be faster */
- /*while (hi-lo != 1)*/
- for (i=0;i<LOG_MAX_PULSES;i++)
- {
- int mid = (lo+hi)>>1;
- /* OPT: Make sure this is implemented with a conditional move */
- if (cache[mid] >= bits)
- hi = mid;
- else
- lo = mid;
- }
- if (bits-cache[lo] <= cache[hi]-bits)
- return lo;
- else
- return hi;
-}
+
static int interp_bits2pulses(const CELTMode *m, const celt_int16_t * const *cache, int *bits1, int *bits2, int *ebits1, int *ebits2, int total, int *pulses, int *bits, int *ebits, int len)
{
int esum, psum;
@@ -238,6 +212,7 @@
if (bits2[j] < 0)
bits2[j] = 0;
}
+#if 0
remaining_bits = interp_bits2pulses(m, cache, bits1, bits2, ebits1, ebits2, total, pulses, bits, ebits, len);
{
int balance = 0;
@@ -260,8 +235,13 @@
}
balance += bits[i] - curr_bits;
pulses[i] = P;
+ printf ("%d ", P);
}
+ printf ("\n");
}
+#else
+ remaining_bits = interp_bits2pulses(m, cache, bits1, bits2, ebits1, ebits2, total, bits, pulses, ebits, len);
+#endif
RESTORE_STACK;
}
--- a/libcelt/rate.h
+++ b/libcelt/rate.h
@@ -35,6 +35,35 @@
#define MAX_PULSES 128
#define LOG_MAX_PULSES 7
+#define BITRES 4
+#define BITROUND 8
+#define BITOVERFLOW 30000
+
+static inline int bits2pulses(const CELTMode *m, const celt_int16_t *cache, int bits)
+{
+ int i;
+ int lo, hi;
+ lo = 0;
+ hi = MAX_PULSES-1;
+
+ /* Instead of using the "bisection condition" we use a fixed number of
+ iterations because it should be faster */
+ /*while (hi-lo != 1)*/
+ for (i=0;i<LOG_MAX_PULSES;i++)
+ {
+ int mid = (lo+hi)>>1;
+ /* OPT: Make sure this is implemented with a conditional move */
+ if (cache[mid] >= bits)
+ hi = mid;
+ else
+ lo = mid;
+ }
+ if (bits-cache[lo] <= cache[hi]-bits)
+ return lo;
+ else
+ return hi;
+}
+
/** Computes a cache of the pulses->bits mapping in each band */
celt_int16_t **compute_alloc_cache(CELTMode *m, int C);
--- a/libcelt/testcelt.c
+++ b/libcelt/testcelt.c
@@ -139,6 +139,7 @@
else if (errors%2 == 1)
data[rand()%8] ^= 1<<rand()%8;
#endif
+#if 1 /* Set to zero to use the encoder's output instead */
/* This is to simulate packet loss */
if (argc==9 && rand()%1000<atoi(argv[7]))
/*if (errors && (errors%2==0))*/
@@ -145,6 +146,10 @@
celt_decode(dec, NULL, len, out);
else
celt_decode(dec, data, len, out);
+#else
+ for (i=0;i<frame_size*channels;i++)
+ out[i] = in[i];
+#endif
#if !(defined (FIXED_POINT) && defined(STATIC_MODES))
for (i=0;i<frame_size*channels;i++)
{