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