1885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* Copyright (c) 2007-2008 CSIRO 2885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Copyright (c) 2007-2009 Xiph.Org Foundation 3885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Copyright (c) 2008-2009 Gregory Maxwell 4885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Written by Jean-Marc Valin and Gregory Maxwell */ 5885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* 6885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Redistribution and use in source and binary forms, with or without 7885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org modification, are permitted provided that the following conditions 8885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org are met: 9885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 10885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org - Redistributions of source code must retain the above copyright 11885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org notice, this list of conditions and the following disclaimer. 12885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 13885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org - Redistributions in binary form must reproduce the above copyright 14885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org notice, this list of conditions and the following disclaimer in the 15885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org documentation and/or other materials provided with the distribution. 16885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 17885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 21885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 24885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 25885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org*/ 29885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 30885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef HAVE_CONFIG_H 31885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "config.h" 32885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 33885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 34885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include <math.h> 35885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "bands.h" 36885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "modes.h" 37885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "vq.h" 38885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "cwrs.h" 39885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "stack_alloc.h" 40885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "os_support.h" 41885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "mathops.h" 42885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "rate.h" 43e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#include "quant_bands.h" 44e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#include "pitch.h" 45e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 46e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgint hysteresis_decision(opus_val16 val, const opus_val16 *thresholds, const opus_val16 *hysteresis, int N, int prev) 47e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{ 48e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int i; 49e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (i=0;i<N;i++) 50e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 51e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (val < thresholds[i]) 52e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org break; 53e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 54e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (i>prev && val < thresholds[prev]+hysteresis[prev]) 55e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org i=prev; 56e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (i<prev && val > thresholds[prev-1]-hysteresis[prev-1]) 57e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org i=prev; 58e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return i; 59e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 60885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 61885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgopus_uint32 celt_lcg_rand(opus_uint32 seed) 62885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 63885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org return 1664525 * seed + 1013904223; 64885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 65885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 66885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* This is a cos() approximation designed to be bit-exact on any platform. Bit exactness 67885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org with this approximation is important because it has an impact on the bit allocation */ 68885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic opus_int16 bitexact_cos(opus_int16 x) 69885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 70885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_int32 tmp; 71885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_int16 x2; 72885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tmp = (4096+((opus_int32)(x)*(x)))>>13; 73885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org celt_assert(tmp<=32767); 74885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org x2 = tmp; 75885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org x2 = (32767-x2) + FRAC_MUL16(x2, (-7651 + FRAC_MUL16(x2, (8277 + FRAC_MUL16(-626, x2))))); 76885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org celt_assert(x2<=32766); 77885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org return 1+x2; 78885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 79885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 80885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic int bitexact_log2tan(int isin,int icos) 81885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 82885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int lc; 83885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int ls; 84885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org lc=EC_ILOG(icos); 85885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ls=EC_ILOG(isin); 86885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org icos<<=15-lc; 87885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org isin<<=15-ls; 88885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org return (ls-lc)*(1<<11) 89885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org +FRAC_MUL16(isin, FRAC_MUL16(isin, -2597) + 7932) 90885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org -FRAC_MUL16(icos, FRAC_MUL16(icos, -2597) + 7932); 91885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 92885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 93885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT 94885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* Compute the amplitude (sqrt energy) in each of the bands */ 95885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgvoid compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int M) 96885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 97885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int i, c, N; 98885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const opus_int16 *eBands = m->eBands; 99885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org N = M*m->shortMdctSize; 100885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org c=0; do { 101885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=0;i<end;i++) 102885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 103885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int j; 104885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val32 maxval=0; 105885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val32 sum = 0; 106885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 107885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org j=M*eBands[i]; do { 108885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org maxval = MAX32(maxval, X[j+c*N]); 109885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org maxval = MAX32(maxval, -X[j+c*N]); 110885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } while (++j<M*eBands[i+1]); 111885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 112885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (maxval > 0) 113885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 114885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int shift = celt_ilog2(maxval)-10; 115885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org j=M*eBands[i]; do { 116885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org sum = MAC16_16(sum, EXTRACT16(VSHR32(X[j+c*N],shift)), 117885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org EXTRACT16(VSHR32(X[j+c*N],shift))); 118885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } while (++j<M*eBands[i+1]); 119885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* We're adding one here to ensure the normalized band isn't larger than unity norm */ 120885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org bandE[i+c*m->nbEBands] = EPSILON+VSHR32(EXTEND32(celt_sqrt(sum)),-shift); 121885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } else { 122885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org bandE[i+c*m->nbEBands] = EPSILON; 123885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 124885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /*printf ("%f ", bandE[i+c*m->nbEBands]);*/ 125885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 126885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } while (++c<C); 127885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /*printf ("\n");*/ 128885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 129885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 130885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* Normalise each band such that the energy is one. */ 131885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgvoid normalise_bands(const CELTMode *m, const celt_sig * OPUS_RESTRICT freq, celt_norm * OPUS_RESTRICT X, const celt_ener *bandE, int end, int C, int M) 132885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 133885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int i, c, N; 134885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const opus_int16 *eBands = m->eBands; 135885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org N = M*m->shortMdctSize; 136885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org c=0; do { 137885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org i=0; do { 138885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val16 g; 139885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int j,shift; 140885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val16 E; 141885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org shift = celt_zlog2(bandE[i+c*m->nbEBands])-13; 142885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org E = VSHR32(bandE[i+c*m->nbEBands], shift); 143885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org g = EXTRACT16(celt_rcp(SHL32(E,3))); 144885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org j=M*eBands[i]; do { 145885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org X[j+c*N] = MULT16_16_Q15(VSHR32(freq[j+c*N],shift-1),g); 146885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } while (++j<M*eBands[i+1]); 147885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } while (++i<end); 148885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } while (++c<C); 149885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 150885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 151885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#else /* FIXED_POINT */ 152885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* Compute the amplitude (sqrt energy) in each of the bands */ 153885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgvoid compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int M) 154885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 155885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int i, c, N; 156885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const opus_int16 *eBands = m->eBands; 157885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org N = M*m->shortMdctSize; 158885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org c=0; do { 159885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=0;i<end;i++) 160885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 161885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int j; 162885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val32 sum = 1e-27f; 163885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (j=M*eBands[i];j<M*eBands[i+1];j++) 164885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org sum += X[j+c*N]*X[j+c*N]; 165885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org bandE[i+c*m->nbEBands] = celt_sqrt(sum); 166885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /*printf ("%f ", bandE[i+c*m->nbEBands]);*/ 167885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 168885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } while (++c<C); 169885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /*printf ("\n");*/ 170885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 171885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 172885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* Normalise each band such that the energy is one. */ 173885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgvoid normalise_bands(const CELTMode *m, const celt_sig * OPUS_RESTRICT freq, celt_norm * OPUS_RESTRICT X, const celt_ener *bandE, int end, int C, int M) 174885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 175885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int i, c, N; 176885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const opus_int16 *eBands = m->eBands; 177885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org N = M*m->shortMdctSize; 178885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org c=0; do { 179885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=0;i<end;i++) 180885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 181885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int j; 182885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val16 g = 1.f/(1e-27f+bandE[i+c*m->nbEBands]); 183885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (j=M*eBands[i];j<M*eBands[i+1];j++) 184885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org X[j+c*N] = freq[j+c*N]*g; 185885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 186885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } while (++c<C); 187885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 188885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 189885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif /* FIXED_POINT */ 190885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 191885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* De-normalise the energy to produce the synthesis from the unit-energy bands */ 192e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgvoid denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X, 193e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org celt_sig * OPUS_RESTRICT freq, const opus_val16 *bandLogE, int start, int end, int C, int M) 194885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 195885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int i, c, N; 196885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const opus_int16 *eBands = m->eBands; 197885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org N = M*m->shortMdctSize; 198885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org celt_assert2(C<=2, "denormalise_bands() not implemented for >2 channels"); 199885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org c=0; do { 200885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org celt_sig * OPUS_RESTRICT f; 201885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const celt_norm * OPUS_RESTRICT x; 202885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org f = freq+c*N; 203e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org x = X+c*N+M*eBands[start]; 204e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (i=0;i<M*eBands[start];i++) 205e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org *f++ = 0; 206e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (i=start;i<end;i++) 207885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 208885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int j, band_end; 209e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val16 g; 210e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val16 lg; 211e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#ifdef FIXED_POINT 212e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int shift; 213e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif 214885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org j=M*eBands[i]; 215885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org band_end = M*eBands[i+1]; 216e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org lg = ADD16(bandLogE[i+c*m->nbEBands], SHL16((opus_val16)eMeans[i],6)); 2173c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com#ifndef FIXED_POINT 2183c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com g = celt_exp2(lg); 2193c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com#else 220e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Handle the integer part of the log energy */ 221e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org shift = 16-(lg>>DB_SHIFT); 222e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (shift>31) 223e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 224e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org shift=0; 225e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org g=0; 226e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else { 227e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Handle the fractional part. */ 228e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org g = celt_exp2_frac(lg&((1<<DB_SHIFT)-1)); 229e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 2303c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com /* Handle extreme gains with negative shift. */ 2313c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com if (shift<0) 2323c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com { 2333c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com /* For shift < -2 we'd be likely to overflow, so we're capping 2343c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com the gain here. This shouldn't happen unless the bitstream is 2353c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com already corrupted. */ 2363c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com if (shift < -2) 2373c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com { 2383c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com g = 32767; 2393c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com shift = -2; 2403c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com } 2413c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com do { 2423c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com *f++ = SHL32(MULT16_16(*x++, g), -shift); 2433c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com } while (++j<band_end); 2443c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com } else 245e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif 2463c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com /* Be careful of the fixed-point "else" just above when changing this code */ 247885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org do { 248e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org *f++ = SHR32(MULT16_16(*x++, g), shift); 249885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } while (++j<band_end); 250885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 251e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org celt_assert(start <= end); 252885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=M*eBands[end];i<N;i++) 253885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org *f++ = 0; 254885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } while (++c<C); 255885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 256885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 257885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* This prevents energy collapse for transients with multiple short MDCTs */ 258885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgvoid anti_collapse(const CELTMode *m, celt_norm *X_, unsigned char *collapse_masks, int LM, int C, int size, 259885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int start, int end, opus_val16 *logE, opus_val16 *prev1logE, 260885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val16 *prev2logE, int *pulses, opus_uint32 seed) 261885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 262885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int c, i, j, k; 263885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=start;i<end;i++) 264885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 265885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int N0; 266885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val16 thresh, sqrt_1; 267885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int depth; 268885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT 269885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int shift; 270885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val32 thresh32; 271885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 272885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 273885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org N0 = m->eBands[i+1]-m->eBands[i]; 274885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* depth in 1/8 bits */ 275885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org depth = (1+pulses[i])/((m->eBands[i+1]-m->eBands[i])<<LM); 276885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 277885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT 278885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org thresh32 = SHR32(celt_exp2(-SHL16(depth, 10-BITRES)),1); 279885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org thresh = MULT16_32_Q15(QCONST16(0.5f, 15), MIN32(32767,thresh32)); 280885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 281885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val32 t; 282885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org t = N0<<LM; 283885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org shift = celt_ilog2(t)>>1; 284885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org t = SHL32(t, (7-shift)<<1); 285885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org sqrt_1 = celt_rsqrt_norm(t); 286885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 287885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#else 288885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org thresh = .5f*celt_exp2(-.125f*depth); 289885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org sqrt_1 = celt_rsqrt(N0<<LM); 290885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 291885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 292885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org c=0; do 293885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 294885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org celt_norm *X; 295885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val16 prev1; 296885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val16 prev2; 297885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val32 Ediff; 298885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val16 r; 299885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int renormalize=0; 300885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org prev1 = prev1logE[c*m->nbEBands+i]; 301885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org prev2 = prev2logE[c*m->nbEBands+i]; 302885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (C==1) 303885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 304885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org prev1 = MAX16(prev1,prev1logE[m->nbEBands+i]); 305885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org prev2 = MAX16(prev2,prev2logE[m->nbEBands+i]); 306885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 307885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Ediff = EXTEND32(logE[c*m->nbEBands+i])-EXTEND32(MIN16(prev1,prev2)); 308885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Ediff = MAX32(0, Ediff); 309885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 310885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT 311885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (Ediff < 16384) 312885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 313885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val32 r32 = SHR32(celt_exp2(-EXTRACT16(Ediff)),1); 314885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org r = 2*MIN16(16383,r32); 315885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } else { 316885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org r = 0; 317885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 318885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (LM==3) 319885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org r = MULT16_16_Q14(23170, MIN32(23169, r)); 320885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org r = SHR16(MIN16(thresh, r),1); 321885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org r = SHR32(MULT16_16_Q15(sqrt_1, r),shift); 322885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#else 323885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* r needs to be multiplied by 2 or 2*sqrt(2) depending on LM because 324885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org short blocks don't have the same energy as long */ 325885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org r = 2.f*celt_exp2(-Ediff); 326885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (LM==3) 327885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org r *= 1.41421356f; 328885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org r = MIN16(thresh, r); 329885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org r = r*sqrt_1; 330885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 331885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org X = X_+c*size+(m->eBands[i]<<LM); 332885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (k=0;k<1<<LM;k++) 333885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 334885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Detect collapse */ 335885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (!(collapse_masks[i*C+c]&1<<k)) 336885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 337885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Fill with noise */ 338885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (j=0;j<N0;j++) 339885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 340885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org seed = celt_lcg_rand(seed); 341885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org X[(j<<LM)+k] = (seed&0x8000 ? r : -r); 342885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 343885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org renormalize = 1; 344885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 345885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 346885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* We just added some energy, so we need to renormalise */ 347885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (renormalize) 348885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org renormalise_vector(X, N0<<LM, Q15ONE); 349885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } while (++c<C); 350885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 351885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 352885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 353885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void intensity_stereo(const CELTMode *m, celt_norm *X, celt_norm *Y, const celt_ener *bandE, int bandID, int N) 354885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 355885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int i = bandID; 356885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int j; 357885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val16 a1, a2; 358885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val16 left, right; 359885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val16 norm; 360885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT 361885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int shift = celt_zlog2(MAX32(bandE[i], bandE[i+m->nbEBands]))-13; 362885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 363885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org left = VSHR32(bandE[i],shift); 364885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org right = VSHR32(bandE[i+m->nbEBands],shift); 365885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org norm = EPSILON + celt_sqrt(EPSILON+MULT16_16(left,left)+MULT16_16(right,right)); 366885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org a1 = DIV32_16(SHL32(EXTEND32(left),14),norm); 367885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org a2 = DIV32_16(SHL32(EXTEND32(right),14),norm); 368885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (j=0;j<N;j++) 369885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 370885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org celt_norm r, l; 371885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org l = X[j]; 372885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org r = Y[j]; 373885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org X[j] = MULT16_16_Q14(a1,l) + MULT16_16_Q14(a2,r); 374885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Side is not encoded, no need to calculate */ 375885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 376885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 377885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 378885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void stereo_split(celt_norm *X, celt_norm *Y, int N) 379885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 380885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int j; 381885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (j=0;j<N;j++) 382885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 383885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org celt_norm r, l; 384885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org l = MULT16_16_Q15(QCONST16(.70710678f,15), X[j]); 385885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org r = MULT16_16_Q15(QCONST16(.70710678f,15), Y[j]); 386885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org X[j] = l+r; 387885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Y[j] = r-l; 388885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 389885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 390885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 391885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void stereo_merge(celt_norm *X, celt_norm *Y, opus_val16 mid, int N) 392885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 393885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int j; 394885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val32 xp=0, side=0; 395885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val32 El, Er; 396885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val16 mid2; 397885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT 398885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int kl, kr; 399885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 400885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val32 t, lgain, rgain; 401885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 402885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Compute the norm of X+Y and X-Y as |X|^2 + |Y|^2 +/- sum(xy) */ 403e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org dual_inner_prod(Y, X, Y, N, &xp, &side); 404885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Compensating for the mid normalization */ 405885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org xp = MULT16_32_Q15(mid, xp); 406885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* mid and side are in Q15, not Q14 like X and Y */ 407885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org mid2 = SHR32(mid, 1); 408885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org El = MULT16_16(mid2, mid2) + side - 2*xp; 409885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Er = MULT16_16(mid2, mid2) + side + 2*xp; 410885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (Er < QCONST32(6e-4f, 28) || El < QCONST32(6e-4f, 28)) 411885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 412885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (j=0;j<N;j++) 413885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Y[j] = X[j]; 414885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org return; 415885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 416885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 417885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT 418885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kl = celt_ilog2(El)>>1; 419885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kr = celt_ilog2(Er)>>1; 420885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 421885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org t = VSHR32(El, (kl-7)<<1); 422885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org lgain = celt_rsqrt_norm(t); 423885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org t = VSHR32(Er, (kr-7)<<1); 424885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org rgain = celt_rsqrt_norm(t); 425885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 426885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT 427885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (kl < 7) 428885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kl = 7; 429885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (kr < 7) 430885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kr = 7; 431885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 432885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 433885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (j=0;j<N;j++) 434885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 435885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org celt_norm r, l; 436885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Apply mid scaling (side is already scaled) */ 437885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org l = MULT16_16_Q15(mid, X[j]); 438885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org r = Y[j]; 439885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org X[j] = EXTRACT16(PSHR32(MULT16_16(lgain, SUB16(l,r)), kl+1)); 440885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Y[j] = EXTRACT16(PSHR32(MULT16_16(rgain, ADD16(l,r)), kr+1)); 441885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 442885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 443885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 444885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* Decide whether we should spread the pulses in the current frame */ 445885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgint spreading_decision(const CELTMode *m, celt_norm *X, int *average, 446885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int last_decision, int *hf_average, int *tapset_decision, int update_hf, 447885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int end, int C, int M) 448885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 449885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int i, c, N0; 450885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int sum = 0, nbBands=0; 451885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const opus_int16 * OPUS_RESTRICT eBands = m->eBands; 452885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int decision; 453885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int hf_sum=0; 454885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 455885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org celt_assert(end>0); 456885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 457885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org N0 = M*m->shortMdctSize; 458885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 459885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (M*(eBands[end]-eBands[end-1]) <= 8) 460885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org return SPREAD_NONE; 461885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org c=0; do { 462885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=0;i<end;i++) 463885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 464885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int j, N, tmp=0; 465885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int tcount[3] = {0,0,0}; 466885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org celt_norm * OPUS_RESTRICT x = X+M*eBands[i]+c*N0; 467885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org N = M*(eBands[i+1]-eBands[i]); 468885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (N<=8) 469885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org continue; 470885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Compute rough CDF of |x[j]| */ 471885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (j=0;j<N;j++) 472885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 473885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val32 x2N; /* Q13 */ 474885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 475885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org x2N = MULT16_16(MULT16_16_Q15(x[j], x[j]), N); 476885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (x2N < QCONST16(0.25f,13)) 477885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tcount[0]++; 478885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (x2N < QCONST16(0.0625f,13)) 479885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tcount[1]++; 480885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (x2N < QCONST16(0.015625f,13)) 481885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tcount[2]++; 482885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 483885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 484885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Only include four last bands (8 kHz and up) */ 485885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (i>m->nbEBands-4) 486885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org hf_sum += 32*(tcount[1]+tcount[0])/N; 487885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tmp = (2*tcount[2] >= N) + (2*tcount[1] >= N) + (2*tcount[0] >= N); 488885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org sum += tmp*256; 489885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org nbBands++; 490885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 491885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } while (++c<C); 492885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 493885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (update_hf) 494885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 495885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (hf_sum) 496885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org hf_sum /= C*(4-m->nbEBands+end); 497885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org *hf_average = (*hf_average+hf_sum)>>1; 498885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org hf_sum = *hf_average; 499885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (*tapset_decision==2) 500885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org hf_sum += 4; 501885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org else if (*tapset_decision==0) 502885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org hf_sum -= 4; 503885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (hf_sum > 22) 504885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org *tapset_decision=2; 505885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org else if (hf_sum > 18) 506885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org *tapset_decision=1; 507885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org else 508885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org *tapset_decision=0; 509885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 510885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /*printf("%d %d %d\n", hf_sum, *hf_average, *tapset_decision);*/ 5113c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com celt_assert(nbBands>0); /* end has to be non-zero */ 512885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org sum /= nbBands; 513885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Recursive averaging */ 514885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org sum = (sum+*average)>>1; 515885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org *average = sum; 516885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Hysteresis */ 517885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org sum = (3*sum + (((3-last_decision)<<7) + 64) + 2)>>2; 518885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (sum < 80) 519885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 520885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org decision = SPREAD_AGGRESSIVE; 521885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } else if (sum < 256) 522885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 523885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org decision = SPREAD_NORMAL; 524885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } else if (sum < 384) 525885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 526885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org decision = SPREAD_LIGHT; 527885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } else { 528885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org decision = SPREAD_NONE; 529885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 530885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FUZZING 531885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org decision = rand()&0x3; 532885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org *tapset_decision=rand()%3; 533885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 534885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org return decision; 535885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 536885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 537885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* Indexing table for converting from natural Hadamard to ordery Hadamard 538885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org This is essentially a bit-reversed Gray, on top of which we've added 539885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org an inversion of the order because we want the DC at the end rather than 540885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org the beginning. The lines are for N=2, 4, 8, 16 */ 541885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic const int ordery_table[] = { 542885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 1, 0, 543885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 3, 0, 2, 1, 544885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 7, 0, 4, 3, 6, 1, 5, 2, 545885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 15, 0, 8, 7, 12, 3, 11, 4, 14, 1, 9, 6, 13, 2, 10, 5, 546885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}; 547885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 548885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void deinterleave_hadamard(celt_norm *X, int N0, int stride, int hadamard) 549885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 550885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int i,j; 551885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org VARDECL(celt_norm, tmp); 552885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int N; 553885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org SAVE_STACK; 554885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org N = N0*stride; 555885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ALLOC(tmp, N, celt_norm); 556885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org celt_assert(stride>0); 557885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (hadamard) 558885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 559885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const int *ordery = ordery_table+stride-2; 560885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=0;i<stride;i++) 561885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 562885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (j=0;j<N0;j++) 563885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tmp[ordery[i]*N0+j] = X[j*stride+i]; 564885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 565885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } else { 566885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=0;i<stride;i++) 567885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (j=0;j<N0;j++) 568885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tmp[i*N0+j] = X[j*stride+i]; 569885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 570885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (j=0;j<N;j++) 571885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org X[j] = tmp[j]; 572885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org RESTORE_STACK; 573885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 574885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 575885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void interleave_hadamard(celt_norm *X, int N0, int stride, int hadamard) 576885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 577885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int i,j; 578885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org VARDECL(celt_norm, tmp); 579885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int N; 580885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org SAVE_STACK; 581885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org N = N0*stride; 582885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ALLOC(tmp, N, celt_norm); 583885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (hadamard) 584885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 585885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const int *ordery = ordery_table+stride-2; 586885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=0;i<stride;i++) 587885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (j=0;j<N0;j++) 588885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tmp[j*stride+i] = X[ordery[i]*N0+j]; 589885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } else { 590885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=0;i<stride;i++) 591885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (j=0;j<N0;j++) 592885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tmp[j*stride+i] = X[i*N0+j]; 593885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 594885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (j=0;j<N;j++) 595885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org X[j] = tmp[j]; 596885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org RESTORE_STACK; 597885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 598885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 599885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgvoid haar1(celt_norm *X, int N0, int stride) 600885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 601885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int i, j; 602885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org N0 >>= 1; 603885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=0;i<stride;i++) 604885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (j=0;j<N0;j++) 605885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 606885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org celt_norm tmp1, tmp2; 607885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tmp1 = MULT16_16_Q15(QCONST16(.70710678f,15), X[stride*2*j+i]); 608885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tmp2 = MULT16_16_Q15(QCONST16(.70710678f,15), X[stride*(2*j+1)+i]); 609885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org X[stride*2*j+i] = tmp1 + tmp2; 610885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org X[stride*(2*j+1)+i] = tmp1 - tmp2; 611885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 612885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 613885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 614885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic int compute_qn(int N, int b, int offset, int pulse_cap, int stereo) 615885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 616885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org static const opus_int16 exp2_table8[8] = 617885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org {16384, 17866, 19483, 21247, 23170, 25267, 27554, 30048}; 618885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int qn, qb; 619885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int N2 = 2*N-1; 620885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (stereo && N==2) 621885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org N2--; 622885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* The upper limit ensures that in a stereo split with itheta==16384, we'll 623885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org always have enough bits left over to code at least one pulse in the 624885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org side; otherwise it would collapse, since it doesn't get folded. */ 625885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org qb = IMIN(b-pulse_cap-(4<<BITRES), (b+N2*offset)/N2); 626885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 627885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org qb = IMIN(8<<BITRES, qb); 628885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 629885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (qb<(1<<BITRES>>1)) { 630885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org qn = 1; 631885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } else { 632885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org qn = exp2_table8[qb&0x7]>>(14-(qb>>BITRES)); 633885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org qn = (qn+1)>>1<<1; 634885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 635885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org celt_assert(qn <= 256); 636885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org return qn; 637885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 638885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 639e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgstruct band_ctx { 640e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int encode; 641e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org const CELTMode *m; 642e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int i; 643e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int intensity; 644e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int spread; 645e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int tf_change; 646e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ec_ctx *ec; 647e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_int32 remaining_bits; 648e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org const celt_ener *bandE; 649e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_uint32 seed; 650e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org}; 651e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 652e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgstruct split_ctx { 653e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int inv; 654e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int imid; 655e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int iside; 656e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int delta; 657e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int itheta; 658e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int qalloc; 659e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org}; 660e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 661e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgstatic void compute_theta(struct band_ctx *ctx, struct split_ctx *sctx, 662e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org celt_norm *X, celt_norm *Y, int N, int *b, int B, int B0, 663e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int LM, 664e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int stereo, int *fill) 665885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 666e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int qn; 667e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int itheta=0; 668e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int delta; 669e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int imid, iside; 670e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int qalloc; 671e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int pulse_cap; 672e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int offset; 673e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_int32 tell; 674e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int inv=0; 675e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int encode; 676e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org const CELTMode *m; 677e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int i; 678e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int intensity; 679e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ec_ctx *ec; 680e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org const celt_ener *bandE; 681e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 682e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org encode = ctx->encode; 683e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org m = ctx->m; 684e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org i = ctx->i; 685e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org intensity = ctx->intensity; 686e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ec = ctx->ec; 687e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org bandE = ctx->bandE; 688e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 689e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Decide on the resolution to give to the split parameter theta */ 690e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org pulse_cap = m->logN[i]+LM*(1<<BITRES); 691e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org offset = (pulse_cap>>1) - (stereo&&N==2 ? QTHETA_OFFSET_TWOPHASE : QTHETA_OFFSET); 692e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org qn = compute_qn(N, *b, offset, pulse_cap, stereo); 693e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (stereo && i>=intensity) 694e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org qn = 1; 695e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (encode) 696e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 697e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* theta is the atan() of the ratio between the (normalized) 698e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org side and mid. With just that parameter, we can re-scale both 699e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mid and side because we know that 1) they have unit norm and 700e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 2) they are orthogonal. */ 701e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org itheta = stereo_itheta(X, Y, stereo, N); 702e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 703e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org tell = ec_tell_frac(ec); 704e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (qn!=1) 705e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 706e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (encode) 707e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org itheta = (itheta*qn+8192)>>14; 708885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 709e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Entropy coding of the angle. We use a uniform pdf for the 710e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org time split, a step for stereo, and a triangular one for the rest. */ 711e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (stereo && N>2) 712e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 713e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int p0 = 3; 714e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int x = itheta; 715e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int x0 = qn/2; 716e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int ft = p0*(x0+1) + x0; 717e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Use a probability of p0 up to itheta=8192 and then use 1 after */ 718e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (encode) 719e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 720e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ec_encode(ec,x<=x0?p0*x:(x-1-x0)+(x0+1)*p0,x<=x0?p0*(x+1):(x-x0)+(x0+1)*p0,ft); 721e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else { 722e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int fs; 723e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org fs=ec_decode(ec,ft); 724e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (fs<(x0+1)*p0) 725e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org x=fs/p0; 726e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org else 727e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org x=x0+1+(fs-(x0+1)*p0); 728e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 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); 729e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org itheta = x; 730e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 731e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else if (B0>1 || stereo) { 732e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Uniform pdf */ 733e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (encode) 734e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ec_enc_uint(ec, itheta, qn+1); 735e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org else 736e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org itheta = ec_dec_uint(ec, qn+1); 737e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else { 738e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int fs=1, ft; 739e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ft = ((qn>>1)+1)*((qn>>1)+1); 740e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (encode) 741e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 742e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int fl; 743885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 744e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org fs = itheta <= (qn>>1) ? itheta + 1 : qn + 1 - itheta; 745e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org fl = itheta <= (qn>>1) ? itheta*(itheta + 1)>>1 : 746e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ft - ((qn + 1 - itheta)*(qn + 2 - itheta)>>1); 747885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 748e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ec_encode(ec, fl, fl+fs, ft); 749e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else { 750e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Triangular pdf */ 751e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int fl=0; 752e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int fm; 753e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org fm = ec_decode(ec, ft); 754885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 755e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (fm < ((qn>>1)*((qn>>1) + 1)>>1)) 756885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 757e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org itheta = (isqrt32(8*(opus_uint32)fm + 1) - 1)>>1; 758e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org fs = itheta + 1; 759e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org fl = itheta*(itheta + 1)>>1; 760e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 761e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org else 762e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 763e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org itheta = (2*(qn + 1) 764e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org - isqrt32(8*(opus_uint32)(ft - fm - 1) + 1))>>1; 765e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org fs = qn + 1 - itheta; 766e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org fl = ft - ((qn + 1 - itheta)*(qn + 2 - itheta)>>1); 767885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 768885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 769e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ec_dec_update(ec, fl, fl+fs, ft); 770e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 771885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 772e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org itheta = (opus_int32)itheta*16384/qn; 773e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (encode && stereo) 774885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 775e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (itheta==0) 776e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org intensity_stereo(m, X, Y, bandE, i, N); 777e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org else 778e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org stereo_split(X, Y, N); 779885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 780e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* NOTE: Renormalising X and Y *may* help fixed-point a bit at very high rate. 781e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org Let's do that at higher complexity */ 782e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else if (stereo) { 783e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (encode) 784885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 785e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org inv = itheta > 8192; 786e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (inv) 787e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 788e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int j; 789e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (j=0;j<N;j++) 790e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org Y[j] = -Y[j]; 791e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 792e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org intensity_stereo(m, X, Y, bandE, i, N); 793885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 794e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (*b>2<<BITRES && ctx->remaining_bits > 2<<BITRES) 795885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 796885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (encode) 797e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ec_enc_bit_logp(ec, inv, 2); 798e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org else 799e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org inv = ec_dec_bit_logp(ec, 2); 800e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else 801e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org inv = 0; 802e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org itheta = 0; 803885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 804e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org qalloc = ec_tell_frac(ec) - tell; 805e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org *b -= qalloc; 806885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 807e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (itheta == 0) 808885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 809e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org imid = 32767; 810e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org iside = 0; 811e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org *fill &= (1<<B)-1; 812e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org delta = -16384; 813e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else if (itheta == 16384) 814e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 815e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org imid = 0; 816e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org iside = 32767; 817e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org *fill &= ((1<<B)-1)<<B; 818e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org delta = 16384; 819e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else { 820e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org imid = bitexact_cos((opus_int16)itheta); 821e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org iside = bitexact_cos((opus_int16)(16384-itheta)); 822e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* This is the mid vs side allocation that minimizes squared error 823e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org in that band. */ 824e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org delta = FRAC_MUL16((N-1)<<7,bitexact_log2tan(iside,imid)); 825885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 826885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 827e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org sctx->inv = inv; 828e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org sctx->imid = imid; 829e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org sctx->iside = iside; 830e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org sctx->delta = delta; 831e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org sctx->itheta = itheta; 832e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org sctx->qalloc = qalloc; 833e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 834e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgstatic unsigned quant_band_n1(struct band_ctx *ctx, celt_norm *X, celt_norm *Y, int b, 835e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org celt_norm *lowband_out) 836e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{ 837e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#ifdef RESYNTH 838e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int resynth = 1; 839e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#else 840e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int resynth = !ctx->encode; 841e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif 842e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int c; 843e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int stereo; 844e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org celt_norm *x = X; 845e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int encode; 846e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ec_ctx *ec; 847885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 848e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org encode = ctx->encode; 849e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ec = ctx->ec; 850e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 851e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org stereo = Y != NULL; 852e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org c=0; do { 853e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int sign=0; 854e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (ctx->remaining_bits>=1<<BITRES) 855885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 856885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (encode) 857885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 858e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org sign = x[0]<0; 859e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ec_enc_bits(ec, sign, 1); 860885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } else { 861e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org sign = ec_dec_bits(ec, 1); 862e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 863e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ctx->remaining_bits -= 1<<BITRES; 864e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org b-=1<<BITRES; 865e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 866e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (resynth) 867e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org x[0] = sign ? -NORM_SCALING : NORM_SCALING; 868e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org x = Y; 869e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } while (++c<1+stereo); 870e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (lowband_out) 871e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org lowband_out[0] = SHR16(X[0],4); 872e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return 1; 873e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 874885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 875e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org/* This function is responsible for encoding and decoding a mono partition. 876e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org It can split the band in two and transmit the energy difference with 877e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org the two half-bands. It can be called recursively so bands can end up being 878e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org split in 8 parts. */ 879e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgstatic unsigned quant_partition(struct band_ctx *ctx, celt_norm *X, 880e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int N, int b, int B, celt_norm *lowband, 881e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int LM, 882e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val16 gain, int fill) 883e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{ 884e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org const unsigned char *cache; 885e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int q; 886e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int curr_bits; 887e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int imid=0, iside=0; 888e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int B0=B; 889e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val16 mid=0, side=0; 890e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org unsigned cm=0; 891e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#ifdef RESYNTH 892e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int resynth = 1; 893e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#else 894e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int resynth = !ctx->encode; 895e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif 896e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org celt_norm *Y=NULL; 897e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int encode; 898e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org const CELTMode *m; 899e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int i; 900e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int spread; 901e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ec_ctx *ec; 902885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 903e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org encode = ctx->encode; 904e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org m = ctx->m; 905e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org i = ctx->i; 906e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org spread = ctx->spread; 907e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ec = ctx->ec; 908885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 909e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* If we need 1.5 more bit than we can produce, split the band in two. */ 910e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org cache = m->cache.bits + m->cache.index[(LM+1)*m->nbEBands+i]; 911e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (LM != -1 && b > cache[cache[0]]+12 && N>2) 912e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 913e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int mbits, sbits, delta; 914e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int itheta; 915e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int qalloc; 916e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org struct split_ctx sctx; 917e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org celt_norm *next_lowband2=NULL; 918e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_int32 rebalance; 919885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 920e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org N >>= 1; 921e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org Y = X+N; 922e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org LM -= 1; 923e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (B==1) 924e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org fill = (fill&1)|(fill<<1); 925e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org B = (B+1)>>1; 926885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 927e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org compute_theta(ctx, &sctx, X, Y, N, &b, B, B0, 928e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org LM, 0, &fill); 929e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org imid = sctx.imid; 930e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org iside = sctx.iside; 931e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org delta = sctx.delta; 932e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org itheta = sctx.itheta; 933e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org qalloc = sctx.qalloc; 934885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT 935885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org mid = imid; 936885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org side = iside; 937885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#else 938885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org mid = (1.f/32768)*imid; 939885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org side = (1.f/32768)*iside; 940885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 941885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 942e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Give more bits to low-energy MDCTs than they would otherwise deserve */ 943e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (B0>1 && (itheta&0x3fff)) 944885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 945e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (itheta > 8192) 946e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Rough approximation for pre-echo masking */ 947e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org delta -= delta>>(4-LM); 948885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org else 949e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Corresponds to a forward-masking slope of 1.5 dB per 10 ms */ 950e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org delta = IMIN(0, delta + (N<<BITRES>>(5-LM))); 951885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 952e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mbits = IMAX(0, IMIN(b, (b-delta)/2)); 953e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org sbits = b-mbits; 954e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ctx->remaining_bits -= qalloc; 955e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 956e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (lowband) 957e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org next_lowband2 = lowband+N; /* >32-bit split case */ 958885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 959e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org rebalance = ctx->remaining_bits; 960e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (mbits >= sbits) 961e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 962e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org cm = quant_partition(ctx, X, N, mbits, B, 963e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org lowband, LM, 964e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org MULT16_16_P15(gain,mid), fill); 965e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org rebalance = mbits - (rebalance-ctx->remaining_bits); 966e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (rebalance > 3<<BITRES && itheta!=0) 967e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org sbits += rebalance - (3<<BITRES); 968e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org cm |= quant_partition(ctx, Y, N, sbits, B, 969e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org next_lowband2, LM, 970e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org MULT16_16_P15(gain,side), fill>>B)<<(B0>>1); 971e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else { 972e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org cm = quant_partition(ctx, Y, N, sbits, B, 973e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org next_lowband2, LM, 974e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org MULT16_16_P15(gain,side), fill>>B)<<(B0>>1); 975e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org rebalance = sbits - (rebalance-ctx->remaining_bits); 976e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (rebalance > 3<<BITRES && itheta!=16384) 977e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mbits += rebalance - (3<<BITRES); 978e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org cm |= quant_partition(ctx, X, N, mbits, B, 979e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org lowband, LM, 980e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org MULT16_16_P15(gain,mid), fill); 981e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 982885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } else { 983885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* This is the basic no-split case */ 984885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org q = bits2pulses(m, i, LM, b); 985885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org curr_bits = pulses2bits(m, i, LM, q); 986e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ctx->remaining_bits -= curr_bits; 987885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 988885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Ensures we can never bust the budget */ 989e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org while (ctx->remaining_bits < 0 && q > 0) 990885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 991e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ctx->remaining_bits += curr_bits; 992885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org q--; 993885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org curr_bits = pulses2bits(m, i, LM, q); 994e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ctx->remaining_bits -= curr_bits; 995885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 996885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 997885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (q!=0) 998885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 999885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int K = get_pulses(q); 1000885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 1001885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Finally do the actual quantization */ 1002885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (encode) 1003885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 1004885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org cm = alg_quant(X, N, K, spread, B, ec 1005885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef RESYNTH 1006885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org , gain 1007885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 1008885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ); 1009885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } else { 1010885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org cm = alg_unquant(X, N, K, spread, B, ec, gain); 1011885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 1012885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } else { 1013885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* If there's no pulse, fill the band anyway */ 1014885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int j; 1015885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (resynth) 1016885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 1017885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org unsigned cm_mask; 1018e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* B can be as large as 16, so this shift might overflow an int on a 1019885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 16-bit platform; use a long to get defined behavior.*/ 1020885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org cm_mask = (unsigned)(1UL<<B)-1; 1021885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org fill &= cm_mask; 1022885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (!fill) 1023885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 1024885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (j=0;j<N;j++) 1025885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org X[j] = 0; 1026885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } else { 1027885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (lowband == NULL) 1028885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 1029885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Noise */ 1030885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (j=0;j<N;j++) 1031885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 1032e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ctx->seed = celt_lcg_rand(ctx->seed); 1033e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org X[j] = (celt_norm)((opus_int32)ctx->seed>>20); 1034885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 1035885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org cm = cm_mask; 1036885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } else { 1037885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Folded spectrum */ 1038885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (j=0;j<N;j++) 1039885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 1040885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val16 tmp; 1041e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ctx->seed = celt_lcg_rand(ctx->seed); 1042885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* About 48 dB below the "normal" folding level */ 1043885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tmp = QCONST16(1.0f/256, 10); 1044e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org tmp = (ctx->seed)&0x8000 ? tmp : -tmp; 1045885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org X[j] = lowband[j]+tmp; 1046885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 1047885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org cm = fill; 1048885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 1049885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org renormalise_vector(X, N, gain); 1050885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 1051885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 1052885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 1053885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 1054885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 1055e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return cm; 1056e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 1057e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 1058e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 1059e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org/* This function is responsible for encoding and decoding a band for the mono case. */ 1060e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgstatic unsigned quant_band(struct band_ctx *ctx, celt_norm *X, 1061e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int N, int b, int B, celt_norm *lowband, 1062e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int LM, celt_norm *lowband_out, 1063e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val16 gain, celt_norm *lowband_scratch, int fill) 1064e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{ 1065e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int N0=N; 1066e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int N_B=N; 1067e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int N_B0; 1068e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int B0=B; 1069e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int time_divide=0; 1070e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int recombine=0; 1071e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int longBlocks; 1072e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org unsigned cm=0; 1073e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#ifdef RESYNTH 1074e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int resynth = 1; 1075e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#else 1076e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int resynth = !ctx->encode; 1077e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif 1078e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int k; 1079e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int encode; 1080e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int tf_change; 1081e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 1082e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org encode = ctx->encode; 1083e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org tf_change = ctx->tf_change; 1084e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 1085e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org longBlocks = B0==1; 1086e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 1087e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org N_B /= B; 1088e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 1089e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Special case for one sample */ 1090e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (N==1) 1091e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 1092e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return quant_band_n1(ctx, X, NULL, b, lowband_out); 1093e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 1094e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 1095e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (tf_change>0) 1096e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org recombine = tf_change; 1097e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Band recombining to increase frequency resolution */ 1098e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 1099e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (lowband_scratch && lowband && (recombine || ((N_B&1) == 0 && tf_change<0) || B0>1)) 1100e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 1101e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int j; 1102e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (j=0;j<N;j++) 1103e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org lowband_scratch[j] = lowband[j]; 1104e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org lowband = lowband_scratch; 1105e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 1106e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 1107e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (k=0;k<recombine;k++) 1108e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 1109e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org static const unsigned char bit_interleave_table[16]={ 1110e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 0,1,1,1,2,3,3,3,2,3,3,3,2,3,3,3 1111e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org }; 1112e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (encode) 1113e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org haar1(X, N>>k, 1<<k); 1114e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (lowband) 1115e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org haar1(lowband, N>>k, 1<<k); 1116e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org fill = bit_interleave_table[fill&0xF]|bit_interleave_table[fill>>4]<<2; 1117e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 1118e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org B>>=recombine; 1119e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org N_B<<=recombine; 1120e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 1121e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Increasing the time resolution */ 1122e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org while ((N_B&1) == 0 && tf_change<0) 1123e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 1124e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (encode) 1125e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org haar1(X, N_B, B); 1126e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (lowband) 1127e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org haar1(lowband, N_B, B); 1128e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org fill |= fill<<B; 1129e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org B <<= 1; 1130e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org N_B >>= 1; 1131e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org time_divide++; 1132e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org tf_change++; 1133e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 1134e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org B0=B; 1135e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org N_B0 = N_B; 1136e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 1137e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Reorganize the samples in time order instead of frequency order */ 1138e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (B0>1) 1139e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 1140e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (encode) 1141e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org deinterleave_hadamard(X, N_B>>recombine, B0<<recombine, longBlocks); 1142e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (lowband) 1143e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org deinterleave_hadamard(lowband, N_B>>recombine, B0<<recombine, longBlocks); 1144e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 1145e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 1146e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org cm = quant_partition(ctx, X, N, b, B, lowband, 1147e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org LM, gain, fill); 1148e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 1149885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* This code is used by the decoder and by the resynthesis-enabled encoder */ 1150885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (resynth) 1151885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 1152e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Undo the sample reorganization going from time order to frequency order */ 1153e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (B0>1) 1154e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org interleave_hadamard(X, N_B>>recombine, B0<<recombine, longBlocks); 1155e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 1156e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Undo time-freq changes that we did earlier */ 1157e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org N_B = N_B0; 1158e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org B = B0; 1159e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (k=0;k<time_divide;k++) 1160885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 1161e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org B >>= 1; 1162e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org N_B <<= 1; 1163e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org cm |= cm>>B; 1164e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org haar1(X, N_B, B); 1165e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 1166e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 1167e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (k=0;k<recombine;k++) 1168885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 1169e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org static const unsigned char bit_deinterleave_table[16]={ 1170e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 0x00,0x03,0x0C,0x0F,0x30,0x33,0x3C,0x3F, 1171e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 0xC0,0xC3,0xCC,0xCF,0xF0,0xF3,0xFC,0xFF 1172e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org }; 1173e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org cm = bit_deinterleave_table[cm]; 1174e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org haar1(X, N0>>k, 1<<k); 1175e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 1176e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org B<<=recombine; 1177885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 1178e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Scale output for later folding */ 1179e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (lowband_out) 1180e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 1181e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int j; 1182e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val16 n; 1183e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org n = celt_sqrt(SHL32(EXTEND32(N0),22)); 1184e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (j=0;j<N0;j++) 1185e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org lowband_out[j] = MULT16_16_Q15(n,X[j]); 1186e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 1187e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org cm &= (1<<B)-1; 1188e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 1189e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return cm; 1190e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 1191885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 1192885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 1193e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org/* This function is responsible for encoding and decoding a band for the stereo case. */ 1194e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgstatic unsigned quant_band_stereo(struct band_ctx *ctx, celt_norm *X, celt_norm *Y, 1195e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int N, int b, int B, celt_norm *lowband, 1196e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int LM, celt_norm *lowband_out, 1197e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org celt_norm *lowband_scratch, int fill) 1198e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{ 1199e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int imid=0, iside=0; 1200e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int inv = 0; 1201e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val16 mid=0, side=0; 1202e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org unsigned cm=0; 1203e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#ifdef RESYNTH 1204e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int resynth = 1; 1205e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#else 1206e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int resynth = !ctx->encode; 1207e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif 1208e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int mbits, sbits, delta; 1209e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int itheta; 1210e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int qalloc; 1211e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org struct split_ctx sctx; 1212e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int orig_fill; 1213e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int encode; 1214e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ec_ctx *ec; 1215e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 1216e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org encode = ctx->encode; 1217e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ec = ctx->ec; 1218e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 1219e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Special case for one sample */ 1220e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (N==1) 1221e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 1222e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return quant_band_n1(ctx, X, Y, b, lowband_out); 1223e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 1224e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 1225e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org orig_fill = fill; 1226e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 1227e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org compute_theta(ctx, &sctx, X, Y, N, &b, B, B, 1228e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org LM, 1, &fill); 1229e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org inv = sctx.inv; 1230e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org imid = sctx.imid; 1231e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org iside = sctx.iside; 1232e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org delta = sctx.delta; 1233e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org itheta = sctx.itheta; 1234e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org qalloc = sctx.qalloc; 1235e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#ifdef FIXED_POINT 1236e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mid = imid; 1237e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org side = iside; 1238e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#else 1239e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mid = (1.f/32768)*imid; 1240e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org side = (1.f/32768)*iside; 1241e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif 1242885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 1243e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* This is a special case for N=2 that only works for stereo and takes 1244e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org advantage of the fact that mid and side are orthogonal to encode 1245e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org the side with just one bit. */ 1246e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (N==2) 1247e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 1248e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int c; 1249e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int sign=0; 1250e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org celt_norm *x2, *y2; 1251e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mbits = b; 1252e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org sbits = 0; 1253e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Only need one bit for the side. */ 1254e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (itheta != 0 && itheta != 16384) 1255e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org sbits = 1<<BITRES; 1256e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mbits -= sbits; 1257e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org c = itheta > 8192; 1258e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ctx->remaining_bits -= qalloc+sbits; 1259e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 1260e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org x2 = c ? Y : X; 1261e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org y2 = c ? X : Y; 1262e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (sbits) 1263e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 1264e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (encode) 1265885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 1266e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Here we only need to encode a sign for the side. */ 1267e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org sign = x2[0]*y2[1] - x2[1]*y2[0] < 0; 1268e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ec_enc_bits(ec, sign, 1); 1269e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else { 1270e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org sign = ec_dec_bits(ec, 1); 1271885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 1272e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 1273e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org sign = 1-2*sign; 1274e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* We use orig_fill here because we want to fold the side, but if 1275e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org itheta==16384, we'll have cleared the low bits of fill. */ 1276e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org cm = quant_band(ctx, x2, N, mbits, B, lowband, 1277e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org LM, lowband_out, Q15ONE, lowband_scratch, orig_fill); 1278e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* We don't split N=2 bands, so cm is either 1 or 0 (for a fold-collapse), 1279e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org and there's no need to worry about mixing with the other channel. */ 1280e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org y2[0] = -sign*x2[1]; 1281e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org y2[1] = sign*x2[0]; 1282e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (resynth) 1283e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 1284e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org celt_norm tmp; 1285e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org X[0] = MULT16_16_Q15(mid, X[0]); 1286e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org X[1] = MULT16_16_Q15(mid, X[1]); 1287e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org Y[0] = MULT16_16_Q15(side, Y[0]); 1288e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org Y[1] = MULT16_16_Q15(side, Y[1]); 1289e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org tmp = X[0]; 1290e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org X[0] = SUB16(tmp,Y[0]); 1291e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org Y[0] = ADD16(tmp,Y[0]); 1292e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org tmp = X[1]; 1293e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org X[1] = SUB16(tmp,Y[1]); 1294e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org Y[1] = ADD16(tmp,Y[1]); 1295e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 1296e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else { 1297e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* "Normal" split code */ 1298e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_int32 rebalance; 1299e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 1300e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mbits = IMAX(0, IMIN(b, (b-delta)/2)); 1301e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org sbits = b-mbits; 1302e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ctx->remaining_bits -= qalloc; 1303e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 1304e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org rebalance = ctx->remaining_bits; 1305e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (mbits >= sbits) 1306e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 1307e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* In stereo mode, we do not apply a scaling to the mid because we need the normalized 1308e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mid for folding later. */ 1309e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org cm = quant_band(ctx, X, N, mbits, B, 1310e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org lowband, LM, lowband_out, 1311e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org Q15ONE, lowband_scratch, fill); 1312e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org rebalance = mbits - (rebalance-ctx->remaining_bits); 1313e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (rebalance > 3<<BITRES && itheta!=0) 1314e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org sbits += rebalance - (3<<BITRES); 1315e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 1316e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* For a stereo split, the high bits of fill are always zero, so no 1317e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org folding will be done to the side. */ 1318e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org cm |= quant_band(ctx, Y, N, sbits, B, 1319e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org NULL, LM, NULL, 1320e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org side, NULL, fill>>B); 1321e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else { 1322e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* For a stereo split, the high bits of fill are always zero, so no 1323e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org folding will be done to the side. */ 1324e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org cm = quant_band(ctx, Y, N, sbits, B, 1325e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org NULL, LM, NULL, 1326e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org side, NULL, fill>>B); 1327e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org rebalance = sbits - (rebalance-ctx->remaining_bits); 1328e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (rebalance > 3<<BITRES && itheta!=16384) 1329e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mbits += rebalance - (3<<BITRES); 1330e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* In stereo mode, we do not apply a scaling to the mid because we need the normalized 1331e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mid for folding later. */ 1332e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org cm |= quant_band(ctx, X, N, mbits, B, 1333e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org lowband, LM, lowband_out, 1334e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org Q15ONE, lowband_scratch, fill); 1335e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 1336e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 1337e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 1338e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 1339e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* This code is used by the decoder and by the resynthesis-enabled encoder */ 1340e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (resynth) 1341e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 1342e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (N!=2) 1343e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org stereo_merge(X, Y, mid, N); 1344e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (inv) 1345e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 1346e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int j; 1347e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (j=0;j<N;j++) 1348e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org Y[j] = -Y[j]; 1349885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 1350885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 1351885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org return cm; 1352885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 1353885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 1354e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 1355885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgvoid quant_all_bands(int encode, const CELTMode *m, int start, int end, 1356885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org celt_norm *X_, celt_norm *Y_, unsigned char *collapse_masks, const celt_ener *bandE, int *pulses, 1357885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int shortBlocks, int spread, int dual_stereo, int intensity, int *tf_res, 1358885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_int32 total_bits, opus_int32 balance, ec_ctx *ec, int LM, int codedBands, opus_uint32 *seed) 1359885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 1360885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int i; 1361885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_int32 remaining_bits; 1362885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const opus_int16 * OPUS_RESTRICT eBands = m->eBands; 1363885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org celt_norm * OPUS_RESTRICT norm, * OPUS_RESTRICT norm2; 1364885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org VARDECL(celt_norm, _norm); 1365e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org celt_norm *lowband_scratch; 1366885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int B; 1367885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int M; 1368885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int lowband_offset; 1369885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int update_lowband = 1; 1370885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int C = Y_ != NULL ? 2 : 1; 1371e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int norm_offset; 1372885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef RESYNTH 1373885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int resynth = 1; 1374885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#else 1375885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int resynth = !encode; 1376885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 1377e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org struct band_ctx ctx; 1378885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org SAVE_STACK; 1379885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 1380885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org M = 1<<LM; 1381885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org B = shortBlocks ? M : 1; 1382e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org norm_offset = M*eBands[start]; 1383e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* No need to allocate norm for the last band because we don't need an 1384e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org output in that band. */ 1385e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ALLOC(_norm, C*(M*eBands[m->nbEBands-1]-norm_offset), celt_norm); 1386885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org norm = _norm; 1387e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org norm2 = norm + M*eBands[m->nbEBands-1]-norm_offset; 1388e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* We can use the last band as scratch space because we don't need that 1389e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org scratch space for the last band. */ 1390e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org lowband_scratch = X_+M*eBands[m->nbEBands-1]; 1391885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 1392885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org lowband_offset = 0; 1393e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ctx.bandE = bandE; 1394e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ctx.ec = ec; 1395e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ctx.encode = encode; 1396e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ctx.intensity = intensity; 1397e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ctx.m = m; 1398e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ctx.seed = *seed; 1399e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ctx.spread = spread; 1400885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=start;i<end;i++) 1401885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 1402885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_int32 tell; 1403885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int b; 1404885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int N; 1405885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_int32 curr_balance; 1406885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int effective_lowband=-1; 1407885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org celt_norm * OPUS_RESTRICT X, * OPUS_RESTRICT Y; 1408885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int tf_change=0; 1409885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org unsigned x_cm; 1410885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org unsigned y_cm; 1411e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int last; 1412e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 1413e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ctx.i = i; 1414e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org last = (i==end-1); 1415885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 1416885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org X = X_+M*eBands[i]; 1417885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (Y_!=NULL) 1418885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Y = Y_+M*eBands[i]; 1419885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org else 1420885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Y = NULL; 1421885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org N = M*eBands[i+1]-M*eBands[i]; 1422885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tell = ec_tell_frac(ec); 1423885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 1424885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Compute how many bits we want to allocate to this band */ 1425885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (i != start) 1426885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org balance -= tell; 1427885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org remaining_bits = total_bits-tell-1; 1428e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ctx.remaining_bits = remaining_bits; 1429885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (i <= codedBands-1) 1430885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 1431885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org curr_balance = balance / IMIN(3, codedBands-i); 1432885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org b = IMAX(0, IMIN(16383, IMIN(remaining_bits+1,pulses[i]+curr_balance))); 1433885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } else { 1434885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org b = 0; 1435885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 1436885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 1437885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (resynth && M*eBands[i]-N >= M*eBands[start] && (update_lowband || lowband_offset==0)) 1438885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org lowband_offset = i; 1439885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 1440885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tf_change = tf_res[i]; 1441e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ctx.tf_change = tf_change; 1442885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (i>=m->effEBands) 1443885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 1444885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org X=norm; 1445885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (Y_!=NULL) 1446885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Y = norm; 1447e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org lowband_scratch = NULL; 1448885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 1449e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (i==end-1) 1450e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org lowband_scratch = NULL; 1451885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 1452885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Get a conservative estimate of the collapse_mask's for the bands we're 1453e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org going to be folding from. */ 1454885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (lowband_offset != 0 && (spread!=SPREAD_AGGRESSIVE || B>1 || tf_change<0)) 1455885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 1456885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int fold_start; 1457885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int fold_end; 1458885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int fold_i; 1459885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* This ensures we never repeat spectral content within one band */ 1460e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org effective_lowband = IMAX(0, M*eBands[lowband_offset]-norm_offset-N); 1461885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org fold_start = lowband_offset; 1462e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org while(M*eBands[--fold_start] > effective_lowband+norm_offset); 1463885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org fold_end = lowband_offset-1; 1464e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org while(M*eBands[++fold_end] < effective_lowband+norm_offset+N); 1465885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org x_cm = y_cm = 0; 1466885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org fold_i = fold_start; do { 1467885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org x_cm |= collapse_masks[fold_i*C+0]; 1468885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org y_cm |= collapse_masks[fold_i*C+C-1]; 1469885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } while (++fold_i<fold_end); 1470885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 1471885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Otherwise, we'll be using the LCG to fold, so all blocks will (almost 1472e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org always) be non-zero. */ 1473885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org else 1474885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org x_cm = y_cm = (1<<B)-1; 1475885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 1476885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (dual_stereo && i==intensity) 1477885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 1478885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int j; 1479885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 1480e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Switch off dual stereo to do intensity. */ 1481885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org dual_stereo = 0; 1482885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (resynth) 1483e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (j=0;j<M*eBands[i]-norm_offset;j++) 1484885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org norm[j] = HALF32(norm[j]+norm2[j]); 1485885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 1486885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (dual_stereo) 1487885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 1488e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org x_cm = quant_band(&ctx, X, N, b/2, B, 1489e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org effective_lowband != -1 ? norm+effective_lowband : NULL, LM, 1490e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org last?NULL:norm+M*eBands[i]-norm_offset, Q15ONE, lowband_scratch, x_cm); 1491e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org y_cm = quant_band(&ctx, Y, N, b/2, B, 1492e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org effective_lowband != -1 ? norm2+effective_lowband : NULL, LM, 1493e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org last?NULL:norm2+M*eBands[i]-norm_offset, Q15ONE, lowband_scratch, y_cm); 1494885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } else { 1495e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (Y!=NULL) 1496e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 1497e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org x_cm = quant_band_stereo(&ctx, X, Y, N, b, B, 1498e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org effective_lowband != -1 ? norm+effective_lowband : NULL, LM, 1499e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org last?NULL:norm+M*eBands[i]-norm_offset, lowband_scratch, x_cm|y_cm); 1500e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else { 1501e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org x_cm = quant_band(&ctx, X, N, b, B, 1502e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org effective_lowband != -1 ? norm+effective_lowband : NULL, LM, 1503e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org last?NULL:norm+M*eBands[i]-norm_offset, Q15ONE, lowband_scratch, x_cm|y_cm); 1504e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 1505885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org y_cm = x_cm; 1506885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 1507885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org collapse_masks[i*C+0] = (unsigned char)x_cm; 1508885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org collapse_masks[i*C+C-1] = (unsigned char)y_cm; 1509885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org balance += pulses[i] + tell; 1510885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 1511e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Update the folding position only as long as we have 1 bit/sample depth. */ 1512885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org update_lowband = b>(N<<BITRES); 1513885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 1514e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org *seed = ctx.seed; 1515e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 1516885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org RESTORE_STACK; 1517885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 1518885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 1519