diff --git a/libcelt/bands.c b/libcelt/bands.c index 1429ea29e096a14793f8662339450dbf66d83fe5..05a375e8f8e96932492067353613b5403ba8c27d 100644 --- a/libcelt/bands.c +++ b/libcelt/bands.c @@ -290,7 +290,7 @@ void pitch_quant_bands(const CELTMode *m, celt_norm_t * restrict P, const celt_p } /* Quantisation of the residual */ -void quant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, celt_mask_t *W, int total_bits, ec_enc *enc) +void quant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, celt_mask_t *W, const int *stereo_mode, int total_bits, ec_enc *enc) { int i, j, bits; const celt_int16_t * restrict eBands = m->eBands; @@ -310,7 +310,7 @@ void quant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, ce 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(m, offsets, bits, pulses); + compute_allocation(m, offsets, stereo_mode, bits, pulses); /*printf("bits left: %d\n", bits); for (i=0;i<m->nbEBands;i++) @@ -353,7 +353,7 @@ void quant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, ce } /* Decoding of the residual */ -void unquant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, int total_bits, ec_dec *dec) +void unquant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, const int *stereo_mode, int total_bits, ec_dec *dec) { int i, j, bits; const celt_int16_t * restrict eBands = m->eBands; @@ -373,7 +373,7 @@ void unquant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, 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(m, offsets, bits, pulses); + compute_allocation(m, offsets, stereo_mode, bits, pulses); for (i=0;i<m->nbEBands;i++) { @@ -414,11 +414,11 @@ void stereo_decision(const CELTMode *m, celt_norm_t * restrict X, int *stereo_mo for (i=0;i<len-5;i++) stereo_mode[i] = 0; for (;i<len;i++) - stereo_mode[i] = 1; + stereo_mode[i] = 0; } -void stereo_mix(const CELTMode *m, celt_norm_t *X, const celt_ener_t *bank, int dir) +void stereo_mix(const CELTMode *m, celt_norm_t *X, const celt_ener_t *bank, const int *stereo_mode, int dir) { int i; const celt_int16_t *eBands = m->eBands; diff --git a/libcelt/bands.h b/libcelt/bands.h index df7251d713c2bc723b957fb620006de13fad4b0e..b5a620fce204081bfe8c4cbf95ca97b3c2607735 100644 --- a/libcelt/bands.h +++ b/libcelt/bands.h @@ -86,7 +86,7 @@ void pitch_quant_bands(const CELTMode *m, celt_norm_t * restrict P, const celt_p * @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, int total_bits, ec_enc *enc); +void quant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, celt_mask_t *W, const int *stereo_mode, int total_bits, ec_enc *enc); /** Decoding of the residual spectrum * @param m Mode data @@ -95,10 +95,10 @@ void quant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, ce * @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, int total_bits, ec_dec *dec); +void unquant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, const int *stereo_mode, int total_bits, ec_dec *dec); void stereo_decision(const CELTMode *m, celt_norm_t * restrict X, int *stereo_mode, int len); -void stereo_mix(const CELTMode *m, celt_norm_t *X, const celt_ener_t *bank, int dir); +void stereo_mix(const CELTMode *m, celt_norm_t *X, const celt_ener_t *bank, const int *stereo_mode, int dir); #endif /* BANDS_H */ diff --git a/libcelt/celt.c b/libcelt/celt.c index fddd416771e6820b56cc8d673f5a746540260e94..962db5f3ccc8a0cc3801e53fa205c2f0ddaa1d5c 100644 --- a/libcelt/celt.c +++ b/libcelt/celt.c @@ -223,6 +223,7 @@ int EXPORT celt_encode(CELTEncoder * restrict st, celt_int16_t * restrict pcm, u VARDECL(celt_norm_t, P); VARDECL(celt_ener_t, bandE); VARDECL(celt_pgain_t, gains); + VARDECL(int, stereo_mode); const int C = CHANNELS(st->mode); SAVE_STACK; @@ -323,10 +324,12 @@ int EXPORT celt_encode(CELTEncoder * restrict st, celt_int16_t * restrict pcm, u } quant_energy(st->mode, bandE, st->oldBandE, 20+nbCompressedBytes*8/5, st->mode->prob, &st->enc); + ALLOC(stereo_mode, st->mode->nbEBands, int); if (C==2) { - stereo_mix(st->mode, X, bandE, 1); - stereo_mix(st->mode, P, bandE, 1); + stereo_decision(st->mode, X, stereo_mode, st->mode->nbEBands); + stereo_mix(st->mode, X, bandE, stereo_mode, 1); + stereo_mix(st->mode, P, bandE, stereo_mode, 1); } pitch_quant_bands(st->mode, P, gains); @@ -337,11 +340,11 @@ int EXPORT celt_encode(CELTEncoder * restrict st, celt_int16_t * restrict pcm, u X[i] -= P[i]; /* Residual quantisation */ - quant_bands(st->mode, X, P, NULL, nbCompressedBytes*8, &st->enc); + quant_bands(st->mode, X, P, NULL, stereo_mode, nbCompressedBytes*8, &st->enc); if (C==2) { - stereo_mix(st->mode, X, bandE, -1); + stereo_mix(st->mode, X, bandE, stereo_mode, -1); renormalise_bands(st->mode, X); } /* Synthesis */ @@ -545,6 +548,7 @@ int EXPORT celt_decode(CELTDecoder * restrict st, unsigned char *data, int len, VARDECL(celt_norm_t, P); VARDECL(celt_ener_t, bandE); VARDECL(celt_pgain_t, gains); + VARDECL(int, stereo_mode); const int C = CHANNELS(st->mode); SAVE_STACK; @@ -601,18 +605,21 @@ int EXPORT celt_decode(CELTDecoder * restrict st, unsigned char *data, int len, normalise_bands(st->mode, freq, P, bandEp); } + ALLOC(stereo_mode, st->mode->nbEBands, int); if (C==2) - stereo_mix(st->mode, P, bandE, 1); - + { + stereo_decision(st->mode, X, stereo_mode, st->mode->nbEBands); + stereo_mix(st->mode, P, bandE, stereo_mode, 1); + } /* Apply pitch gains */ pitch_quant_bands(st->mode, P, gains); /* Decode fixed codebook and merge with pitch */ - unquant_bands(st->mode, X, P, len*8, &dec); + unquant_bands(st->mode, X, P, stereo_mode, len*8, &dec); if (C==2) { - stereo_mix(st->mode, X, bandE, -1); + stereo_mix(st->mode, X, bandE, stereo_mode, -1); renormalise_bands(st->mode, X); } /* Synthesis */ diff --git a/libcelt/rate.c b/libcelt/rate.c index 66b21a20d6bd0611c9581021ba578c6660ac6d17..09a623214b3b6ba6beb747e3ffb361bd9b844b24 100644 --- a/libcelt/rate.c +++ b/libcelt/rate.c @@ -155,7 +155,7 @@ celt_int16_t **compute_alloc_cache(CELTMode *m, int C) #endif /* !STATIC_MODES */ -static inline int bits2pulses(const CELTMode *m, int band, int bits) +static inline int bits2pulses(const CELTMode *m, const celt_int16_t *cache, int bits) { int i; int lo, hi; @@ -169,32 +169,32 @@ static inline int bits2pulses(const CELTMode *m, int band, int bits) { int mid = (lo+hi)>>1; /* OPT: Make sure this is implemented with a conditional move */ - if (m->bits[band][mid] >= bits) + if (cache[mid] >= bits) hi = mid; else lo = mid; } - if (bits-m->bits[band][lo] <= m->bits[band][hi]-bits) + if (bits-cache[lo] <= cache[hi]-bits) return lo; else return hi; } -static int vec_bits2pulses(const CELTMode *m, int *bits, int *pulses, int len) +static int vec_bits2pulses(const CELTMode *m, const celt_int16_t * const *cache, int *bits, int *pulses, int len) { int i; int sum=0; for (i=0;i<len;i++) { - pulses[i] = bits2pulses(m, i, bits[i]); - sum += m->bits[i][pulses[i]]; + pulses[i] = bits2pulses(m, cache[i], bits[i]); + sum += cache[i][pulses[i]]; } /*printf ("sum = %d\n", sum);*/ return sum; } -static int interp_bits2pulses(const CELTMode *m, int *bits1, int *bits2, int total, int *pulses, int len) +static int interp_bits2pulses(const CELTMode *m, const celt_int16_t * const *cache, int *bits1, int *bits2, int total, int *pulses, int len) { int lo, hi, out; int j; @@ -208,7 +208,7 @@ static int interp_bits2pulses(const CELTMode *m, int *bits1, int *bits2, int tot int mid = (lo+hi)>>1; for (j=0;j<len;j++) bits[j] = ((1<<BITRES)-mid)*bits1[j] + mid*bits2[j]; - if (vec_bits2pulses(m, bits, pulses, len) > total<<BITRES) + if (vec_bits2pulses(m, cache, bits, pulses, len) > total<<BITRES) hi = mid; else lo = mid; @@ -216,16 +216,16 @@ static int interp_bits2pulses(const CELTMode *m, int *bits1, int *bits2, int tot /*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(m, bits, pulses, len); + out = vec_bits2pulses(m, cache, 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 */ for (j=0;j<len;j++) { - if (m->bits[j][pulses[j]] < bits[j] && pulses[j]<MAX_PULSES-1) + if (cache[j][pulses[j]] < bits[j] && pulses[j]<MAX_PULSES-1) { - if (out+m->bits[j][pulses[j]+1]-m->bits[j][pulses[j]] <= total<<BITRES) + if (out+cache[j][pulses[j]+1]-cache[j][pulses[j]] <= total<<BITRES) { - out = out+m->bits[j][pulses[j]+1]-m->bits[j][pulses[j]]; + out = out+cache[j][pulses[j]+1]-cache[j][pulses[j]]; pulses[j] += 1; } } @@ -237,9 +237,9 @@ static int interp_bits2pulses(const CELTMode *m, int *bits1, int *bits2, int tot { if (pulses[j]<MAX_PULSES-1) { - if (out+m->bits[j][pulses[j]+1]-m->bits[j][pulses[j]] <= total<<BITRES) + if (out+cache[j][pulses[j]+1]-cache[j][pulses[j]] <= total<<BITRES) { - out = out+m->bits[j][pulses[j]+1]-m->bits[j][pulses[j]]; + out = out+cache[j][pulses[j]+1]-cache[j][pulses[j]]; pulses[j] += 1; incremented = 1; } @@ -252,16 +252,31 @@ static int interp_bits2pulses(const CELTMode *m, int *bits1, int *bits2, int tot return (out+BITROUND) >> BITRES; } -int compute_allocation(const CELTMode *m, int *offsets, int total, int *pulses) +int compute_allocation(const CELTMode *m, int *offsets, const int *stereo_mode, int total, int *pulses) { - int lo, hi, len, ret; + int lo, hi, len, ret, i; VARDECL(int, bits1); VARDECL(int, bits2); + VARDECL(const celt_int16_t*, cache); SAVE_STACK; len = m->nbEBands; ALLOC(bits1, len, int); ALLOC(bits2, len, int); + ALLOC(cache, len, const celt_int16_t*); + + if (m->nbChannels==2) + { + for (i=0;i<len;i++) + { + if (stereo_mode[i]==0) + cache[i] = m->bits[i]; + } + } else { + for (i=0;i<len;i++) + cache[i] = m->bits[i]; + } + lo = 0; hi = m->nbAllocVectors - 1; while (hi-lo != 1) @@ -276,7 +291,7 @@ int compute_allocation(const CELTMode *m, int *offsets, int total, int *pulses) /*printf ("%d ", bits[j]);*/ } /*printf ("\n");*/ - if (vec_bits2pulses(m, bits1, pulses, len) > total<<BITRES) + if (vec_bits2pulses(m, cache, bits1, pulses, len) > total<<BITRES) hi = mid; else lo = mid; @@ -293,7 +308,7 @@ int compute_allocation(const CELTMode *m, int *offsets, int total, int *pulses) if (bits2[j] < 0) bits2[j] = 0; } - ret = interp_bits2pulses(m, bits1, bits2, total, pulses, len); + ret = interp_bits2pulses(m, cache, bits1, bits2, total, pulses, len); RESTORE_STACK; return ret; } diff --git a/libcelt/rate.h b/libcelt/rate.h index b0cd4cb1a64c18a57d15c68553c4ddd603761144..0edafeb28f7156216a7f7bd39f5697bcf3d931c3 100644 --- a/libcelt/rate.h +++ b/libcelt/rate.h @@ -47,7 +47,7 @@ celt_int16_t **compute_alloc_cache(CELTMode *m, int C); @param pulses Number of pulses per band (returned) @return Total number of bits allocated */ -int compute_allocation(const CELTMode *m, int *offsets, int total, int *pulses); +int compute_allocation(const CELTMode *m, int *offsets, const int *stereo_mode, int total, int *pulses); #endif