Chris@69: /* Copyright (c) 2007-2008 CSIRO Chris@69: Copyright (c) 2007-2009 Xiph.Org Foundation Chris@69: Copyright (c) 2008-2009 Gregory Maxwell Chris@69: Written by Jean-Marc Valin and Gregory Maxwell */ Chris@69: /* Chris@69: Redistribution and use in source and binary forms, with or without Chris@69: modification, are permitted provided that the following conditions Chris@69: are met: Chris@69: Chris@69: - Redistributions of source code must retain the above copyright Chris@69: notice, this list of conditions and the following disclaimer. Chris@69: Chris@69: - Redistributions in binary form must reproduce the above copyright Chris@69: notice, this list of conditions and the following disclaimer in the Chris@69: documentation and/or other materials provided with the distribution. Chris@69: Chris@69: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS Chris@69: ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT Chris@69: LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR Chris@69: A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER Chris@69: OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, Chris@69: EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, Chris@69: PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR Chris@69: PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF Chris@69: LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING Chris@69: NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS Chris@69: SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Chris@69: */ Chris@69: Chris@69: #ifdef HAVE_CONFIG_H Chris@69: #include "config.h" Chris@69: #endif Chris@69: Chris@69: #include Chris@69: #include "bands.h" Chris@69: #include "modes.h" Chris@69: #include "vq.h" Chris@69: #include "cwrs.h" Chris@69: #include "stack_alloc.h" Chris@69: #include "os_support.h" Chris@69: #include "mathops.h" Chris@69: #include "rate.h" Chris@69: #include "quant_bands.h" Chris@69: #include "pitch.h" Chris@69: Chris@69: int hysteresis_decision(opus_val16 val, const opus_val16 *thresholds, const opus_val16 *hysteresis, int N, int prev) Chris@69: { Chris@69: int i; Chris@69: for (i=0;iprev && val < thresholds[prev]+hysteresis[prev]) Chris@69: i=prev; Chris@69: if (i thresholds[prev-1]-hysteresis[prev-1]) Chris@69: i=prev; Chris@69: return i; Chris@69: } Chris@69: Chris@69: opus_uint32 celt_lcg_rand(opus_uint32 seed) Chris@69: { Chris@69: return 1664525 * seed + 1013904223; Chris@69: } Chris@69: Chris@69: /* This is a cos() approximation designed to be bit-exact on any platform. Bit exactness Chris@69: with this approximation is important because it has an impact on the bit allocation */ Chris@69: opus_int16 bitexact_cos(opus_int16 x) Chris@69: { Chris@69: opus_int32 tmp; Chris@69: opus_int16 x2; Chris@69: tmp = (4096+((opus_int32)(x)*(x)))>>13; Chris@69: celt_sig_assert(tmp<=32767); Chris@69: x2 = tmp; Chris@69: x2 = (32767-x2) + FRAC_MUL16(x2, (-7651 + FRAC_MUL16(x2, (8277 + FRAC_MUL16(-626, x2))))); Chris@69: celt_sig_assert(x2<=32766); Chris@69: return 1+x2; Chris@69: } Chris@69: Chris@69: int bitexact_log2tan(int isin,int icos) Chris@69: { Chris@69: int lc; Chris@69: int ls; Chris@69: lc=EC_ILOG(icos); Chris@69: ls=EC_ILOG(isin); Chris@69: icos<<=15-lc; Chris@69: isin<<=15-ls; Chris@69: return (ls-lc)*(1<<11) Chris@69: +FRAC_MUL16(isin, FRAC_MUL16(isin, -2597) + 7932) Chris@69: -FRAC_MUL16(icos, FRAC_MUL16(icos, -2597) + 7932); Chris@69: } Chris@69: Chris@69: #ifdef FIXED_POINT Chris@69: /* Compute the amplitude (sqrt energy) in each of the bands */ Chris@69: void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int LM, int arch) Chris@69: { Chris@69: int i, c, N; Chris@69: const opus_int16 *eBands = m->eBands; Chris@69: (void)arch; Chris@69: N = m->shortMdctSize< 0) Chris@69: { Chris@69: int shift = celt_ilog2(maxval) - 14 + (((m->logN[i]>>BITRES)+LM+1)>>1); Chris@69: j=eBands[i]<0) Chris@69: { Chris@69: do { Chris@69: sum = MAC16_16(sum, EXTRACT16(SHR32(X[j+c*N],shift)), Chris@69: EXTRACT16(SHR32(X[j+c*N],shift))); Chris@69: } while (++jnbEBands] = EPSILON+VSHR32(EXTEND32(celt_sqrt(sum)),-shift); Chris@69: } else { Chris@69: bandE[i+c*m->nbEBands] = EPSILON; Chris@69: } Chris@69: /*printf ("%f ", bandE[i+c*m->nbEBands]);*/ Chris@69: } Chris@69: } while (++ceBands; Chris@69: N = M*m->shortMdctSize; Chris@69: c=0; do { Chris@69: i=0; do { Chris@69: opus_val16 g; Chris@69: int j,shift; Chris@69: opus_val16 E; Chris@69: shift = celt_zlog2(bandE[i+c*m->nbEBands])-13; Chris@69: E = VSHR32(bandE[i+c*m->nbEBands], shift); Chris@69: g = EXTRACT16(celt_rcp(SHL32(E,3))); Chris@69: j=M*eBands[i]; do { Chris@69: X[j+c*N] = MULT16_16_Q15(VSHR32(freq[j+c*N],shift-1),g); Chris@69: } while (++jeBands; Chris@69: N = m->shortMdctSize<nbEBands] = celt_sqrt(sum); Chris@69: /*printf ("%f ", bandE[i+c*m->nbEBands]);*/ Chris@69: } Chris@69: } while (++ceBands; Chris@69: N = M*m->shortMdctSize; Chris@69: c=0; do { Chris@69: for (i=0;inbEBands]); Chris@69: for (j=M*eBands[i];jeBands; Chris@69: N = M*m->shortMdctSize; Chris@69: bound = M*eBands[end]; Chris@69: if (downsample!=1) Chris@69: bound = IMIN(bound, N/downsample); Chris@69: if (silence) Chris@69: { Chris@69: bound = 0; Chris@69: start = end = 0; Chris@69: } Chris@69: f = freq; Chris@69: x = X+M*eBands[start]; Chris@69: for (i=0;i>DB_SHIFT); Chris@69: if (shift>31) Chris@69: { Chris@69: shift=0; Chris@69: g=0; Chris@69: } else { Chris@69: /* Handle the fractional part. */ Chris@69: g = celt_exp2_frac(lg&((1< 16384 we'd be likely to overflow, so we're Chris@69: capping the gain here, which is equivalent to a cap of 18 on lg. Chris@69: This shouldn't trigger unless the bitstream is already corrupted. */ Chris@69: if (shift <= -2) Chris@69: { Chris@69: g = 16384; Chris@69: shift = -2; Chris@69: } Chris@69: do { Chris@69: *f++ = SHL32(MULT16_16(*x++, g), -shift); Chris@69: } while (++jeBands[i+1]-m->eBands[i]; Chris@69: /* depth in 1/8 bits */ Chris@69: celt_sig_assert(pulses[i]>=0); Chris@69: depth = celt_udiv(1+pulses[i], (m->eBands[i+1]-m->eBands[i]))>>LM; Chris@69: Chris@69: #ifdef FIXED_POINT Chris@69: thresh32 = SHR32(celt_exp2(-SHL16(depth, 10-BITRES)),1); Chris@69: thresh = MULT16_32_Q15(QCONST16(0.5f, 15), MIN32(32767,thresh32)); Chris@69: { Chris@69: opus_val32 t; Chris@69: t = N0<>1; Chris@69: t = SHL32(t, (7-shift)<<1); Chris@69: sqrt_1 = celt_rsqrt_norm(t); Chris@69: } Chris@69: #else Chris@69: thresh = .5f*celt_exp2(-.125f*depth); Chris@69: sqrt_1 = celt_rsqrt(N0<nbEBands+i]; Chris@69: prev2 = prev2logE[c*m->nbEBands+i]; Chris@69: if (C==1) Chris@69: { Chris@69: prev1 = MAX16(prev1,prev1logE[m->nbEBands+i]); Chris@69: prev2 = MAX16(prev2,prev2logE[m->nbEBands+i]); Chris@69: } Chris@69: Ediff = EXTEND32(logE[c*m->nbEBands+i])-EXTEND32(MIN16(prev1,prev2)); Chris@69: Ediff = MAX32(0, Ediff); Chris@69: Chris@69: #ifdef FIXED_POINT Chris@69: if (Ediff < 16384) Chris@69: { Chris@69: opus_val32 r32 = SHR32(celt_exp2(-EXTRACT16(Ediff)),1); Chris@69: r = 2*MIN16(16383,r32); Chris@69: } else { Chris@69: r = 0; Chris@69: } Chris@69: if (LM==3) Chris@69: r = MULT16_16_Q14(23170, MIN32(23169, r)); Chris@69: r = SHR16(MIN16(thresh, r),1); Chris@69: r = SHR32(MULT16_16_Q15(sqrt_1, r),shift); Chris@69: #else Chris@69: /* r needs to be multiplied by 2 or 2*sqrt(2) depending on LM because Chris@69: short blocks don't have the same energy as long */ Chris@69: r = 2.f*celt_exp2(-Ediff); Chris@69: if (LM==3) Chris@69: r *= 1.41421356f; Chris@69: r = MIN16(thresh, r); Chris@69: r = r*sqrt_1; Chris@69: #endif Chris@69: X = X_+c*size+(m->eBands[i]<nbEBands]))-13; Chris@69: #endif Chris@69: left = VSHR32(bandE[i],shift); Chris@69: right = VSHR32(bandE[i+m->nbEBands],shift); Chris@69: norm = EPSILON + celt_sqrt(EPSILON+MULT16_16(left,left)+MULT16_16(right,right)); Chris@69: a1 = DIV32_16(SHL32(EXTEND32(left),14),norm); Chris@69: a2 = DIV32_16(SHL32(EXTEND32(right),14),norm); Chris@69: for (j=0;j>1; Chris@69: kr = celt_ilog2(Er)>>1; Chris@69: #endif Chris@69: t = VSHR32(El, (kl-7)<<1); Chris@69: lgain = celt_rsqrt_norm(t); Chris@69: t = VSHR32(Er, (kr-7)<<1); Chris@69: rgain = celt_rsqrt_norm(t); Chris@69: Chris@69: #ifdef FIXED_POINT Chris@69: if (kl < 7) Chris@69: kl = 7; Chris@69: if (kr < 7) Chris@69: kr = 7; Chris@69: #endif Chris@69: Chris@69: for (j=0;jeBands; Chris@69: int decision; Chris@69: int hf_sum=0; Chris@69: Chris@69: celt_assert(end>0); Chris@69: Chris@69: N0 = M*m->shortMdctSize; Chris@69: Chris@69: if (M*(eBands[end]-eBands[end-1]) <= 8) Chris@69: return SPREAD_NONE; Chris@69: c=0; do { Chris@69: for (i=0;im->nbEBands-4) Chris@69: hf_sum += celt_udiv(32*(tcount[1]+tcount[0]), N); Chris@69: tmp = (2*tcount[2] >= N) + (2*tcount[1] >= N) + (2*tcount[0] >= N); Chris@69: sum += tmp*spread_weight[i]; Chris@69: nbBands+=spread_weight[i]; Chris@69: } Chris@69: } while (++cnbEBands+end)); Chris@69: *hf_average = (*hf_average+hf_sum)>>1; Chris@69: hf_sum = *hf_average; Chris@69: if (*tapset_decision==2) Chris@69: hf_sum += 4; Chris@69: else if (*tapset_decision==0) Chris@69: hf_sum -= 4; Chris@69: if (hf_sum > 22) Chris@69: *tapset_decision=2; Chris@69: else if (hf_sum > 18) Chris@69: *tapset_decision=1; Chris@69: else Chris@69: *tapset_decision=0; Chris@69: } Chris@69: /*printf("%d %d %d\n", hf_sum, *hf_average, *tapset_decision);*/ Chris@69: celt_assert(nbBands>0); /* end has to be non-zero */ Chris@69: celt_assert(sum>=0); Chris@69: sum = celt_udiv((opus_int32)sum<<8, nbBands); Chris@69: /* Recursive averaging */ Chris@69: sum = (sum+*average)>>1; Chris@69: *average = sum; Chris@69: /* Hysteresis */ Chris@69: sum = (3*sum + (((3-last_decision)<<7) + 64) + 2)>>2; Chris@69: if (sum < 80) Chris@69: { Chris@69: decision = SPREAD_AGGRESSIVE; Chris@69: } else if (sum < 256) Chris@69: { Chris@69: decision = SPREAD_NORMAL; Chris@69: } else if (sum < 384) Chris@69: { Chris@69: decision = SPREAD_LIGHT; Chris@69: } else { Chris@69: decision = SPREAD_NONE; Chris@69: } Chris@69: #ifdef FUZZING Chris@69: decision = rand()&0x3; Chris@69: *tapset_decision=rand()%3; Chris@69: #endif Chris@69: return decision; Chris@69: } Chris@69: Chris@69: /* Indexing table for converting from natural Hadamard to ordery Hadamard Chris@69: This is essentially a bit-reversed Gray, on top of which we've added Chris@69: an inversion of the order because we want the DC at the end rather than Chris@69: the beginning. The lines are for N=2, 4, 8, 16 */ Chris@69: static const int ordery_table[] = { Chris@69: 1, 0, Chris@69: 3, 0, 2, 1, Chris@69: 7, 0, 4, 3, 6, 1, 5, 2, Chris@69: 15, 0, 8, 7, 12, 3, 11, 4, 14, 1, 9, 6, 13, 2, 10, 5, Chris@69: }; Chris@69: Chris@69: static void deinterleave_hadamard(celt_norm *X, int N0, int stride, int hadamard) Chris@69: { Chris@69: int i,j; Chris@69: VARDECL(celt_norm, tmp); Chris@69: int N; Chris@69: SAVE_STACK; Chris@69: N = N0*stride; Chris@69: ALLOC(tmp, N, celt_norm); Chris@69: celt_assert(stride>0); Chris@69: if (hadamard) Chris@69: { Chris@69: const int *ordery = ordery_table+stride-2; Chris@69: for (i=0;i>= 1; Chris@69: for (i=0;i>1)) { Chris@69: qn = 1; Chris@69: } else { Chris@69: qn = exp2_table8[qb&0x7]>>(14-(qb>>BITRES)); Chris@69: qn = (qn+1)>>1<<1; Chris@69: } Chris@69: celt_assert(qn <= 256); Chris@69: return qn; Chris@69: } Chris@69: Chris@69: struct band_ctx { Chris@69: int encode; Chris@69: int resynth; Chris@69: const CELTMode *m; Chris@69: int i; Chris@69: int intensity; Chris@69: int spread; Chris@69: int tf_change; Chris@69: ec_ctx *ec; Chris@69: opus_int32 remaining_bits; Chris@69: const celt_ener *bandE; Chris@69: opus_uint32 seed; Chris@69: int arch; Chris@69: int theta_round; Chris@69: int disable_inv; Chris@69: int avoid_split_noise; Chris@69: }; Chris@69: Chris@69: struct split_ctx { Chris@69: int inv; Chris@69: int imid; Chris@69: int iside; Chris@69: int delta; Chris@69: int itheta; Chris@69: int qalloc; Chris@69: }; Chris@69: Chris@69: static void compute_theta(struct band_ctx *ctx, struct split_ctx *sctx, Chris@69: celt_norm *X, celt_norm *Y, int N, int *b, int B, int B0, Chris@69: int LM, Chris@69: int stereo, int *fill) Chris@69: { Chris@69: int qn; Chris@69: int itheta=0; Chris@69: int delta; Chris@69: int imid, iside; Chris@69: int qalloc; Chris@69: int pulse_cap; Chris@69: int offset; Chris@69: opus_int32 tell; Chris@69: int inv=0; Chris@69: int encode; Chris@69: const CELTMode *m; Chris@69: int i; Chris@69: int intensity; Chris@69: ec_ctx *ec; Chris@69: const celt_ener *bandE; Chris@69: Chris@69: encode = ctx->encode; Chris@69: m = ctx->m; Chris@69: i = ctx->i; Chris@69: intensity = ctx->intensity; Chris@69: ec = ctx->ec; Chris@69: bandE = ctx->bandE; Chris@69: Chris@69: /* Decide on the resolution to give to the split parameter theta */ Chris@69: pulse_cap = m->logN[i]+LM*(1<>1) - (stereo&&N==2 ? QTHETA_OFFSET_TWOPHASE : QTHETA_OFFSET); Chris@69: qn = compute_qn(N, *b, offset, pulse_cap, stereo); Chris@69: if (stereo && i>=intensity) Chris@69: qn = 1; Chris@69: if (encode) Chris@69: { Chris@69: /* theta is the atan() of the ratio between the (normalized) Chris@69: side and mid. With just that parameter, we can re-scale both Chris@69: mid and side because we know that 1) they have unit norm and Chris@69: 2) they are orthogonal. */ Chris@69: itheta = stereo_itheta(X, Y, stereo, N, ctx->arch); Chris@69: } Chris@69: tell = ec_tell_frac(ec); Chris@69: if (qn!=1) Chris@69: { Chris@69: if (encode) Chris@69: { Chris@69: if (!stereo || ctx->theta_round == 0) Chris@69: { Chris@69: itheta = (itheta*(opus_int32)qn+8192)>>14; Chris@69: if (!stereo && ctx->avoid_split_noise && itheta > 0 && itheta < qn) Chris@69: { Chris@69: /* Check if the selected value of theta will cause the bit allocation Chris@69: to inject noise on one side. If so, make sure the energy of that side Chris@69: is zero. */ Chris@69: int unquantized = celt_udiv((opus_int32)itheta*16384, qn); Chris@69: imid = bitexact_cos((opus_int16)unquantized); Chris@69: iside = bitexact_cos((opus_int16)(16384-unquantized)); Chris@69: delta = FRAC_MUL16((N-1)<<7,bitexact_log2tan(iside,imid)); Chris@69: if (delta > *b) Chris@69: itheta = qn; Chris@69: else if (delta < -*b) Chris@69: itheta = 0; Chris@69: } Chris@69: } else { Chris@69: int down; Chris@69: /* Bias quantization towards itheta=0 and itheta=16384. */ Chris@69: int bias = itheta > 8192 ? 32767/qn : -32767/qn; Chris@69: down = IMIN(qn-1, IMAX(0, (itheta*(opus_int32)qn + bias)>>14)); Chris@69: if (ctx->theta_round < 0) Chris@69: itheta = down; Chris@69: else Chris@69: itheta = down+1; Chris@69: } Chris@69: } Chris@69: /* Entropy coding of the angle. We use a uniform pdf for the Chris@69: time split, a step for stereo, and a triangular one for the rest. */ Chris@69: if (stereo && N>2) Chris@69: { Chris@69: int p0 = 3; Chris@69: int x = itheta; Chris@69: int x0 = qn/2; Chris@69: int ft = p0*(x0+1) + x0; Chris@69: /* Use a probability of p0 up to itheta=8192 and then use 1 after */ Chris@69: if (encode) Chris@69: { Chris@69: ec_encode(ec,x<=x0?p0*x:(x-1-x0)+(x0+1)*p0,x<=x0?p0*(x+1):(x-x0)+(x0+1)*p0,ft); Chris@69: } else { Chris@69: int fs; Chris@69: fs=ec_decode(ec,ft); Chris@69: if (fs<(x0+1)*p0) Chris@69: x=fs/p0; Chris@69: else Chris@69: x=x0+1+(fs-(x0+1)*p0); Chris@69: ec_dec_update(ec,x<=x0?p0*x:(x-1-x0)+(x0+1)*p0,x<=x0?p0*(x+1):(x-x0)+(x0+1)*p0,ft); Chris@69: itheta = x; Chris@69: } Chris@69: } else if (B0>1 || stereo) { Chris@69: /* Uniform pdf */ Chris@69: if (encode) Chris@69: ec_enc_uint(ec, itheta, qn+1); Chris@69: else Chris@69: itheta = ec_dec_uint(ec, qn+1); Chris@69: } else { Chris@69: int fs=1, ft; Chris@69: ft = ((qn>>1)+1)*((qn>>1)+1); Chris@69: if (encode) Chris@69: { Chris@69: int fl; Chris@69: Chris@69: fs = itheta <= (qn>>1) ? itheta + 1 : qn + 1 - itheta; Chris@69: fl = itheta <= (qn>>1) ? itheta*(itheta + 1)>>1 : Chris@69: ft - ((qn + 1 - itheta)*(qn + 2 - itheta)>>1); Chris@69: Chris@69: ec_encode(ec, fl, fl+fs, ft); Chris@69: } else { Chris@69: /* Triangular pdf */ Chris@69: int fl=0; Chris@69: int fm; Chris@69: fm = ec_decode(ec, ft); Chris@69: Chris@69: if (fm < ((qn>>1)*((qn>>1) + 1)>>1)) Chris@69: { Chris@69: itheta = (isqrt32(8*(opus_uint32)fm + 1) - 1)>>1; Chris@69: fs = itheta + 1; Chris@69: fl = itheta*(itheta + 1)>>1; Chris@69: } Chris@69: else Chris@69: { Chris@69: itheta = (2*(qn + 1) Chris@69: - isqrt32(8*(opus_uint32)(ft - fm - 1) + 1))>>1; Chris@69: fs = qn + 1 - itheta; Chris@69: fl = ft - ((qn + 1 - itheta)*(qn + 2 - itheta)>>1); Chris@69: } Chris@69: Chris@69: ec_dec_update(ec, fl, fl+fs, ft); Chris@69: } Chris@69: } Chris@69: celt_assert(itheta>=0); Chris@69: itheta = celt_udiv((opus_int32)itheta*16384, qn); Chris@69: if (encode && stereo) Chris@69: { Chris@69: if (itheta==0) Chris@69: intensity_stereo(m, X, Y, bandE, i, N); Chris@69: else Chris@69: stereo_split(X, Y, N); Chris@69: } Chris@69: /* NOTE: Renormalising X and Y *may* help fixed-point a bit at very high rate. Chris@69: Let's do that at higher complexity */ Chris@69: } else if (stereo) { Chris@69: if (encode) Chris@69: { Chris@69: inv = itheta > 8192 && !ctx->disable_inv; Chris@69: if (inv) Chris@69: { Chris@69: int j; Chris@69: for (j=0;j2<remaining_bits > 2<disable_inv) Chris@69: inv = 0; Chris@69: itheta = 0; Chris@69: } Chris@69: qalloc = ec_tell_frac(ec) - tell; Chris@69: *b -= qalloc; Chris@69: Chris@69: if (itheta == 0) Chris@69: { Chris@69: imid = 32767; Chris@69: iside = 0; Chris@69: *fill &= (1<inv = inv; Chris@69: sctx->imid = imid; Chris@69: sctx->iside = iside; Chris@69: sctx->delta = delta; Chris@69: sctx->itheta = itheta; Chris@69: sctx->qalloc = qalloc; Chris@69: } Chris@69: static unsigned quant_band_n1(struct band_ctx *ctx, celt_norm *X, celt_norm *Y, int b, Chris@69: celt_norm *lowband_out) Chris@69: { Chris@69: int c; Chris@69: int stereo; Chris@69: celt_norm *x = X; Chris@69: int encode; Chris@69: ec_ctx *ec; Chris@69: Chris@69: encode = ctx->encode; Chris@69: ec = ctx->ec; Chris@69: Chris@69: stereo = Y != NULL; Chris@69: c=0; do { Chris@69: int sign=0; Chris@69: if (ctx->remaining_bits>=1<remaining_bits -= 1<resynth) Chris@69: x[0] = sign ? -NORM_SCALING : NORM_SCALING; Chris@69: x = Y; Chris@69: } while (++c<1+stereo); Chris@69: if (lowband_out) Chris@69: lowband_out[0] = SHR16(X[0],4); Chris@69: return 1; Chris@69: } Chris@69: Chris@69: /* This function is responsible for encoding and decoding a mono partition. Chris@69: It can split the band in two and transmit the energy difference with Chris@69: the two half-bands. It can be called recursively so bands can end up being Chris@69: split in 8 parts. */ Chris@69: static unsigned quant_partition(struct band_ctx *ctx, celt_norm *X, Chris@69: int N, int b, int B, celt_norm *lowband, Chris@69: int LM, Chris@69: opus_val16 gain, int fill) Chris@69: { Chris@69: const unsigned char *cache; Chris@69: int q; Chris@69: int curr_bits; Chris@69: int imid=0, iside=0; Chris@69: int B0=B; Chris@69: opus_val16 mid=0, side=0; Chris@69: unsigned cm=0; Chris@69: celt_norm *Y=NULL; Chris@69: int encode; Chris@69: const CELTMode *m; Chris@69: int i; Chris@69: int spread; Chris@69: ec_ctx *ec; Chris@69: Chris@69: encode = ctx->encode; Chris@69: m = ctx->m; Chris@69: i = ctx->i; Chris@69: spread = ctx->spread; Chris@69: ec = ctx->ec; Chris@69: Chris@69: /* If we need 1.5 more bit than we can produce, split the band in two. */ Chris@69: cache = m->cache.bits + m->cache.index[(LM+1)*m->nbEBands+i]; Chris@69: if (LM != -1 && b > cache[cache[0]]+12 && N>2) Chris@69: { Chris@69: int mbits, sbits, delta; Chris@69: int itheta; Chris@69: int qalloc; Chris@69: struct split_ctx sctx; Chris@69: celt_norm *next_lowband2=NULL; Chris@69: opus_int32 rebalance; Chris@69: Chris@69: N >>= 1; Chris@69: Y = X+N; Chris@69: LM -= 1; Chris@69: if (B==1) Chris@69: fill = (fill&1)|(fill<<1); Chris@69: B = (B+1)>>1; Chris@69: Chris@69: compute_theta(ctx, &sctx, X, Y, N, &b, B, B0, LM, 0, &fill); Chris@69: imid = sctx.imid; Chris@69: iside = sctx.iside; Chris@69: delta = sctx.delta; Chris@69: itheta = sctx.itheta; Chris@69: qalloc = sctx.qalloc; Chris@69: #ifdef FIXED_POINT Chris@69: mid = imid; Chris@69: side = iside; Chris@69: #else Chris@69: mid = (1.f/32768)*imid; Chris@69: side = (1.f/32768)*iside; Chris@69: #endif Chris@69: Chris@69: /* Give more bits to low-energy MDCTs than they would otherwise deserve */ Chris@69: if (B0>1 && (itheta&0x3fff)) Chris@69: { Chris@69: if (itheta > 8192) Chris@69: /* Rough approximation for pre-echo masking */ Chris@69: delta -= delta>>(4-LM); Chris@69: else Chris@69: /* Corresponds to a forward-masking slope of 1.5 dB per 10 ms */ Chris@69: delta = IMIN(0, delta + (N<>(5-LM))); Chris@69: } Chris@69: mbits = IMAX(0, IMIN(b, (b-delta)/2)); Chris@69: sbits = b-mbits; Chris@69: ctx->remaining_bits -= qalloc; Chris@69: Chris@69: if (lowband) Chris@69: next_lowband2 = lowband+N; /* >32-bit split case */ Chris@69: Chris@69: rebalance = ctx->remaining_bits; Chris@69: if (mbits >= sbits) Chris@69: { Chris@69: cm = quant_partition(ctx, X, N, mbits, B, lowband, LM, Chris@69: MULT16_16_P15(gain,mid), fill); Chris@69: rebalance = mbits - (rebalance-ctx->remaining_bits); Chris@69: if (rebalance > 3<>B)<<(B0>>1); Chris@69: } else { Chris@69: cm = quant_partition(ctx, Y, N, sbits, B, next_lowband2, LM, Chris@69: MULT16_16_P15(gain,side), fill>>B)<<(B0>>1); Chris@69: rebalance = sbits - (rebalance-ctx->remaining_bits); Chris@69: if (rebalance > 3<remaining_bits -= curr_bits; Chris@69: Chris@69: /* Ensures we can never bust the budget */ Chris@69: while (ctx->remaining_bits < 0 && q > 0) Chris@69: { Chris@69: ctx->remaining_bits += curr_bits; Chris@69: q--; Chris@69: curr_bits = pulses2bits(m, i, LM, q); Chris@69: ctx->remaining_bits -= curr_bits; Chris@69: } Chris@69: Chris@69: if (q!=0) Chris@69: { Chris@69: int K = get_pulses(q); Chris@69: Chris@69: /* Finally do the actual quantization */ Chris@69: if (encode) Chris@69: { Chris@69: cm = alg_quant(X, N, K, spread, B, ec, gain, ctx->resynth, ctx->arch); Chris@69: } else { Chris@69: cm = alg_unquant(X, N, K, spread, B, ec, gain); Chris@69: } Chris@69: } else { Chris@69: /* If there's no pulse, fill the band anyway */ Chris@69: int j; Chris@69: if (ctx->resynth) Chris@69: { Chris@69: unsigned cm_mask; Chris@69: /* B can be as large as 16, so this shift might overflow an int on a Chris@69: 16-bit platform; use a long to get defined behavior.*/ Chris@69: cm_mask = (unsigned)(1UL<seed = celt_lcg_rand(ctx->seed); Chris@69: X[j] = (celt_norm)((opus_int32)ctx->seed>>20); Chris@69: } Chris@69: cm = cm_mask; Chris@69: } else { Chris@69: /* Folded spectrum */ Chris@69: for (j=0;jseed = celt_lcg_rand(ctx->seed); Chris@69: /* About 48 dB below the "normal" folding level */ Chris@69: tmp = QCONST16(1.0f/256, 10); Chris@69: tmp = (ctx->seed)&0x8000 ? tmp : -tmp; Chris@69: X[j] = lowband[j]+tmp; Chris@69: } Chris@69: cm = fill; Chris@69: } Chris@69: renormalise_vector(X, N, gain, ctx->arch); Chris@69: } Chris@69: } Chris@69: } Chris@69: } Chris@69: Chris@69: return cm; Chris@69: } Chris@69: Chris@69: Chris@69: /* This function is responsible for encoding and decoding a band for the mono case. */ Chris@69: static unsigned quant_band(struct band_ctx *ctx, celt_norm *X, Chris@69: int N, int b, int B, celt_norm *lowband, Chris@69: int LM, celt_norm *lowband_out, Chris@69: opus_val16 gain, celt_norm *lowband_scratch, int fill) Chris@69: { Chris@69: int N0=N; Chris@69: int N_B=N; Chris@69: int N_B0; Chris@69: int B0=B; Chris@69: int time_divide=0; Chris@69: int recombine=0; Chris@69: int longBlocks; Chris@69: unsigned cm=0; Chris@69: int k; Chris@69: int encode; Chris@69: int tf_change; Chris@69: Chris@69: encode = ctx->encode; Chris@69: tf_change = ctx->tf_change; Chris@69: Chris@69: longBlocks = B0==1; Chris@69: Chris@69: N_B = celt_udiv(N_B, B); Chris@69: Chris@69: /* Special case for one sample */ Chris@69: if (N==1) Chris@69: { Chris@69: return quant_band_n1(ctx, X, NULL, b, lowband_out); Chris@69: } Chris@69: Chris@69: if (tf_change>0) Chris@69: recombine = tf_change; Chris@69: /* Band recombining to increase frequency resolution */ Chris@69: Chris@69: if (lowband_scratch && lowband && (recombine || ((N_B&1) == 0 && tf_change<0) || B0>1)) Chris@69: { Chris@69: OPUS_COPY(lowband_scratch, lowband, N); Chris@69: lowband = lowband_scratch; Chris@69: } Chris@69: Chris@69: for (k=0;k>k, 1<>k, 1<>4]<<2; Chris@69: } Chris@69: B>>=recombine; Chris@69: N_B<<=recombine; Chris@69: Chris@69: /* Increasing the time resolution */ Chris@69: while ((N_B&1) == 0 && tf_change<0) Chris@69: { Chris@69: if (encode) Chris@69: haar1(X, N_B, B); Chris@69: if (lowband) Chris@69: haar1(lowband, N_B, B); Chris@69: fill |= fill<>= 1; Chris@69: time_divide++; Chris@69: tf_change++; Chris@69: } Chris@69: B0=B; Chris@69: N_B0 = N_B; Chris@69: Chris@69: /* Reorganize the samples in time order instead of frequency order */ Chris@69: if (B0>1) Chris@69: { Chris@69: if (encode) Chris@69: deinterleave_hadamard(X, N_B>>recombine, B0<>recombine, B0<resynth) Chris@69: { Chris@69: /* Undo the sample reorganization going from time order to frequency order */ Chris@69: if (B0>1) Chris@69: interleave_hadamard(X, N_B>>recombine, B0<>= 1; Chris@69: N_B <<= 1; Chris@69: cm |= cm>>B; Chris@69: haar1(X, N_B, B); Chris@69: } Chris@69: Chris@69: for (k=0;k>k, 1<encode; Chris@69: ec = ctx->ec; Chris@69: Chris@69: /* Special case for one sample */ Chris@69: if (N==1) Chris@69: { Chris@69: return quant_band_n1(ctx, X, Y, b, lowband_out); Chris@69: } Chris@69: Chris@69: orig_fill = fill; Chris@69: Chris@69: compute_theta(ctx, &sctx, X, Y, N, &b, B, B, LM, 1, &fill); Chris@69: inv = sctx.inv; Chris@69: imid = sctx.imid; Chris@69: iside = sctx.iside; Chris@69: delta = sctx.delta; Chris@69: itheta = sctx.itheta; Chris@69: qalloc = sctx.qalloc; Chris@69: #ifdef FIXED_POINT Chris@69: mid = imid; Chris@69: side = iside; Chris@69: #else Chris@69: mid = (1.f/32768)*imid; Chris@69: side = (1.f/32768)*iside; Chris@69: #endif Chris@69: Chris@69: /* This is a special case for N=2 that only works for stereo and takes Chris@69: advantage of the fact that mid and side are orthogonal to encode Chris@69: the side with just one bit. */ Chris@69: if (N==2) Chris@69: { Chris@69: int c; Chris@69: int sign=0; Chris@69: celt_norm *x2, *y2; Chris@69: mbits = b; Chris@69: sbits = 0; Chris@69: /* Only need one bit for the side. */ Chris@69: if (itheta != 0 && itheta != 16384) Chris@69: sbits = 1< 8192; Chris@69: ctx->remaining_bits -= qalloc+sbits; Chris@69: Chris@69: x2 = c ? Y : X; Chris@69: y2 = c ? X : Y; Chris@69: if (sbits) Chris@69: { Chris@69: if (encode) Chris@69: { Chris@69: /* Here we only need to encode a sign for the side. */ Chris@69: sign = x2[0]*y2[1] - x2[1]*y2[0] < 0; Chris@69: ec_enc_bits(ec, sign, 1); Chris@69: } else { Chris@69: sign = ec_dec_bits(ec, 1); Chris@69: } Chris@69: } Chris@69: sign = 1-2*sign; Chris@69: /* We use orig_fill here because we want to fold the side, but if Chris@69: itheta==16384, we'll have cleared the low bits of fill. */ Chris@69: cm = quant_band(ctx, x2, N, mbits, B, lowband, LM, lowband_out, Q15ONE, Chris@69: lowband_scratch, orig_fill); Chris@69: /* We don't split N=2 bands, so cm is either 1 or 0 (for a fold-collapse), Chris@69: and there's no need to worry about mixing with the other channel. */ Chris@69: y2[0] = -sign*x2[1]; Chris@69: y2[1] = sign*x2[0]; Chris@69: if (ctx->resynth) Chris@69: { Chris@69: celt_norm tmp; Chris@69: X[0] = MULT16_16_Q15(mid, X[0]); Chris@69: X[1] = MULT16_16_Q15(mid, X[1]); Chris@69: Y[0] = MULT16_16_Q15(side, Y[0]); Chris@69: Y[1] = MULT16_16_Q15(side, Y[1]); Chris@69: tmp = X[0]; Chris@69: X[0] = SUB16(tmp,Y[0]); Chris@69: Y[0] = ADD16(tmp,Y[0]); Chris@69: tmp = X[1]; Chris@69: X[1] = SUB16(tmp,Y[1]); Chris@69: Y[1] = ADD16(tmp,Y[1]); Chris@69: } Chris@69: } else { Chris@69: /* "Normal" split code */ Chris@69: opus_int32 rebalance; Chris@69: Chris@69: mbits = IMAX(0, IMIN(b, (b-delta)/2)); Chris@69: sbits = b-mbits; Chris@69: ctx->remaining_bits -= qalloc; Chris@69: Chris@69: rebalance = ctx->remaining_bits; Chris@69: if (mbits >= sbits) Chris@69: { Chris@69: /* In stereo mode, we do not apply a scaling to the mid because we need the normalized Chris@69: mid for folding later. */ Chris@69: cm = quant_band(ctx, X, N, mbits, B, lowband, LM, lowband_out, Q15ONE, Chris@69: lowband_scratch, fill); Chris@69: rebalance = mbits - (rebalance-ctx->remaining_bits); Chris@69: if (rebalance > 3<>B); Chris@69: } else { Chris@69: /* For a stereo split, the high bits of fill are always zero, so no Chris@69: folding will be done to the side. */ Chris@69: cm = quant_band(ctx, Y, N, sbits, B, NULL, LM, NULL, side, NULL, fill>>B); Chris@69: rebalance = sbits - (rebalance-ctx->remaining_bits); Chris@69: if (rebalance > 3<resynth) Chris@69: { Chris@69: if (N!=2) Chris@69: stereo_merge(X, Y, mid, N, ctx->arch); Chris@69: if (inv) Chris@69: { Chris@69: int j; Chris@69: for (j=0;jeBands; Chris@69: n1 = M*(eBands[start+1]-eBands[start]); Chris@69: n2 = M*(eBands[start+2]-eBands[start+1]); Chris@69: /* Duplicate enough of the first band folding data to be able to fold the second band. Chris@69: Copies no data for CELT-only mode. */ Chris@69: OPUS_COPY(&norm[n1], &norm[2*n1 - n2], n2-n1); Chris@69: if (dual_stereo) Chris@69: OPUS_COPY(&norm2[n1], &norm2[2*n1 - n2], n2-n1); Chris@69: } Chris@69: Chris@69: void quant_all_bands(int encode, const CELTMode *m, int start, int end, Chris@69: celt_norm *X_, celt_norm *Y_, unsigned char *collapse_masks, Chris@69: const celt_ener *bandE, int *pulses, int shortBlocks, int spread, Chris@69: int dual_stereo, int intensity, int *tf_res, opus_int32 total_bits, Chris@69: opus_int32 balance, ec_ctx *ec, int LM, int codedBands, Chris@69: opus_uint32 *seed, int complexity, int arch, int disable_inv) Chris@69: { Chris@69: int i; Chris@69: opus_int32 remaining_bits; Chris@69: const opus_int16 * OPUS_RESTRICT eBands = m->eBands; Chris@69: celt_norm * OPUS_RESTRICT norm, * OPUS_RESTRICT norm2; Chris@69: VARDECL(celt_norm, _norm); Chris@69: VARDECL(celt_norm, _lowband_scratch); Chris@69: VARDECL(celt_norm, X_save); Chris@69: VARDECL(celt_norm, Y_save); Chris@69: VARDECL(celt_norm, X_save2); Chris@69: VARDECL(celt_norm, Y_save2); Chris@69: VARDECL(celt_norm, norm_save2); Chris@69: int resynth_alloc; Chris@69: celt_norm *lowband_scratch; Chris@69: int B; Chris@69: int M; Chris@69: int lowband_offset; Chris@69: int update_lowband = 1; Chris@69: int C = Y_ != NULL ? 2 : 1; Chris@69: int norm_offset; Chris@69: int theta_rdo = encode && Y_!=NULL && !dual_stereo && complexity>=8; Chris@69: #ifdef RESYNTH Chris@69: int resynth = 1; Chris@69: #else Chris@69: int resynth = !encode || theta_rdo; Chris@69: #endif Chris@69: struct band_ctx ctx; Chris@69: SAVE_STACK; Chris@69: Chris@69: M = 1<nbEBands-1]-norm_offset), celt_norm); Chris@69: norm = _norm; Chris@69: norm2 = norm + M*eBands[m->nbEBands-1]-norm_offset; Chris@69: Chris@69: /* For decoding, we can use the last band as scratch space because we don't need that Chris@69: scratch space for the last band and we don't care about the data there until we're Chris@69: decoding the last band. */ Chris@69: if (encode && resynth) Chris@69: resynth_alloc = M*(eBands[m->nbEBands]-eBands[m->nbEBands-1]); Chris@69: else Chris@69: resynth_alloc = ALLOC_NONE; Chris@69: ALLOC(_lowband_scratch, resynth_alloc, celt_norm); Chris@69: if (encode && resynth) Chris@69: lowband_scratch = _lowband_scratch; Chris@69: else Chris@69: lowband_scratch = X_+M*eBands[m->nbEBands-1]; Chris@69: ALLOC(X_save, resynth_alloc, celt_norm); Chris@69: ALLOC(Y_save, resynth_alloc, celt_norm); Chris@69: ALLOC(X_save2, resynth_alloc, celt_norm); Chris@69: ALLOC(Y_save2, resynth_alloc, celt_norm); Chris@69: ALLOC(norm_save2, resynth_alloc, celt_norm); Chris@69: Chris@69: lowband_offset = 0; Chris@69: ctx.bandE = bandE; Chris@69: ctx.ec = ec; Chris@69: ctx.encode = encode; Chris@69: ctx.intensity = intensity; Chris@69: ctx.m = m; Chris@69: ctx.seed = *seed; Chris@69: ctx.spread = spread; Chris@69: ctx.arch = arch; Chris@69: ctx.disable_inv = disable_inv; Chris@69: ctx.resynth = resynth; Chris@69: ctx.theta_round = 0; Chris@69: /* Avoid injecting noise in the first band on transients. */ Chris@69: ctx.avoid_split_noise = B > 1; Chris@69: for (i=start;i 0); Chris@69: tell = ec_tell_frac(ec); Chris@69: Chris@69: /* Compute how many bits we want to allocate to this band */ Chris@69: if (i != start) Chris@69: balance -= tell; Chris@69: remaining_bits = total_bits-tell-1; Chris@69: ctx.remaining_bits = remaining_bits; Chris@69: if (i <= codedBands-1) Chris@69: { Chris@69: curr_balance = celt_sudiv(balance, IMIN(3, codedBands-i)); Chris@69: b = IMAX(0, IMIN(16383, IMIN(remaining_bits+1,pulses[i]+curr_balance))); Chris@69: } else { Chris@69: b = 0; Chris@69: } Chris@69: Chris@69: #ifndef DISABLE_UPDATE_DRAFT Chris@69: if (resynth && (M*eBands[i]-N >= M*eBands[start] || i==start+1) && (update_lowband || lowband_offset==0)) Chris@69: lowband_offset = i; Chris@69: if (i == start+1) Chris@69: special_hybrid_folding(m, norm, norm2, start, M, dual_stereo); Chris@69: #else Chris@69: if (resynth && M*eBands[i]-N >= M*eBands[start] && (update_lowband || lowband_offset==0)) Chris@69: lowband_offset = i; Chris@69: #endif Chris@69: Chris@69: tf_change = tf_res[i]; Chris@69: ctx.tf_change = tf_change; Chris@69: if (i>=m->effEBands) Chris@69: { Chris@69: X=norm; Chris@69: if (Y_!=NULL) Chris@69: Y = norm; Chris@69: lowband_scratch = NULL; Chris@69: } Chris@69: if (last && !theta_rdo) Chris@69: lowband_scratch = NULL; Chris@69: Chris@69: /* Get a conservative estimate of the collapse_mask's for the bands we're Chris@69: going to be folding from. */ Chris@69: if (lowband_offset != 0 && (spread!=SPREAD_AGGRESSIVE || B>1 || tf_change<0)) Chris@69: { Chris@69: int fold_start; Chris@69: int fold_end; Chris@69: int fold_i; Chris@69: /* This ensures we never repeat spectral content within one band */ Chris@69: effective_lowband = IMAX(0, M*eBands[lowband_offset]-norm_offset-N); Chris@69: fold_start = lowband_offset; Chris@69: while(M*eBands[--fold_start] > effective_lowband+norm_offset); Chris@69: fold_end = lowband_offset-1; Chris@69: #ifndef DISABLE_UPDATE_DRAFT Chris@69: while(++fold_end < i && M*eBands[fold_end] < effective_lowband+norm_offset+N); Chris@69: #else Chris@69: while(M*eBands[++fold_end] < effective_lowband+norm_offset+N); Chris@69: #endif Chris@69: x_cm = y_cm = 0; Chris@69: fold_i = fold_start; do { Chris@69: x_cm |= collapse_masks[fold_i*C+0]; Chris@69: y_cm |= collapse_masks[fold_i*C+C-1]; Chris@69: } while (++fold_inbEBands], w); Chris@69: /* Make a copy. */ Chris@69: cm = x_cm|y_cm; Chris@69: ec_save = *ec; Chris@69: ctx_save = ctx; Chris@69: OPUS_COPY(X_save, X, N); Chris@69: OPUS_COPY(Y_save, Y, N); Chris@69: /* Encode and round down. */ Chris@69: ctx.theta_round = -1; Chris@69: x_cm = quant_band_stereo(&ctx, X, Y, N, b, B, Chris@69: effective_lowband != -1 ? norm+effective_lowband : NULL, LM, Chris@69: last?NULL:norm+M*eBands[i]-norm_offset, lowband_scratch, cm); Chris@69: dist0 = MULT16_32_Q15(w[0], celt_inner_prod(X_save, X, N, arch)) + MULT16_32_Q15(w[1], celt_inner_prod(Y_save, Y, N, arch)); Chris@69: Chris@69: /* Save first result. */ Chris@69: cm2 = x_cm; Chris@69: ec_save2 = *ec; Chris@69: ctx_save2 = ctx; Chris@69: OPUS_COPY(X_save2, X, N); Chris@69: OPUS_COPY(Y_save2, Y, N); Chris@69: if (!last) Chris@69: OPUS_COPY(norm_save2, norm+M*eBands[i]-norm_offset, N); Chris@69: nstart_bytes = ec_save.offs; Chris@69: nend_bytes = ec_save.storage; Chris@69: bytes_buf = ec_save.buf+nstart_bytes; Chris@69: save_bytes = nend_bytes-nstart_bytes; Chris@69: OPUS_COPY(bytes_save, bytes_buf, save_bytes); Chris@69: Chris@69: /* Restore */ Chris@69: *ec = ec_save; Chris@69: ctx = ctx_save; Chris@69: OPUS_COPY(X, X_save, N); Chris@69: OPUS_COPY(Y, Y_save, N); Chris@69: #ifndef DISABLE_UPDATE_DRAFT Chris@69: if (i == start+1) Chris@69: special_hybrid_folding(m, norm, norm2, start, M, dual_stereo); Chris@69: #endif Chris@69: /* Encode and round up. */ Chris@69: ctx.theta_round = 1; Chris@69: x_cm = quant_band_stereo(&ctx, X, Y, N, b, B, Chris@69: effective_lowband != -1 ? norm+effective_lowband : NULL, LM, Chris@69: last?NULL:norm+M*eBands[i]-norm_offset, lowband_scratch, cm); Chris@69: dist1 = MULT16_32_Q15(w[0], celt_inner_prod(X_save, X, N, arch)) + MULT16_32_Q15(w[1], celt_inner_prod(Y_save, Y, N, arch)); Chris@69: if (dist0 >= dist1) { Chris@69: x_cm = cm2; Chris@69: *ec = ec_save2; Chris@69: ctx = ctx_save2; Chris@69: OPUS_COPY(X, X_save2, N); Chris@69: OPUS_COPY(Y, Y_save2, N); Chris@69: if (!last) Chris@69: OPUS_COPY(norm+M*eBands[i]-norm_offset, norm_save2, N); Chris@69: OPUS_COPY(bytes_buf, bytes_save, save_bytes); Chris@69: } Chris@69: } else { Chris@69: ctx.theta_round = 0; Chris@69: x_cm = quant_band_stereo(&ctx, X, Y, N, b, B, Chris@69: effective_lowband != -1 ? norm+effective_lowband : NULL, LM, Chris@69: last?NULL:norm+M*eBands[i]-norm_offset, lowband_scratch, x_cm|y_cm); Chris@69: } Chris@69: } else { Chris@69: x_cm = quant_band(&ctx, X, N, b, B, Chris@69: effective_lowband != -1 ? norm+effective_lowband : NULL, LM, Chris@69: last?NULL:norm+M*eBands[i]-norm_offset, Q15ONE, lowband_scratch, x_cm|y_cm); Chris@69: } Chris@69: y_cm = x_cm; Chris@69: } Chris@69: collapse_masks[i*C+0] = (unsigned char)x_cm; Chris@69: collapse_masks[i*C+C-1] = (unsigned char)y_cm; Chris@69: balance += pulses[i] + tell; Chris@69: Chris@69: /* Update the folding position only as long as we have 1 bit/sample depth. */ Chris@69: update_lowband = b>(N<