1885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* Copyright (c) 2007-2008 CSIRO 2885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Copyright (c) 2007-2009 Xiph.Org Foundation 3885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Written by Jean-Marc Valin */ 4885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* 5885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Redistribution and use in source and binary forms, with or without 6885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org modification, are permitted provided that the following conditions 7885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org are met: 8885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 9885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org - Redistributions of source code must retain the above copyright 10885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org notice, this list of conditions and the following disclaimer. 11885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 12885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org - Redistributions in binary form must reproduce the above copyright 13885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org notice, this list of conditions and the following disclaimer in the 14885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org documentation and/or other materials provided with the distribution. 15885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 16885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 20885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org*/ 28885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 29885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef HAVE_CONFIG_H 30885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "config.h" 31885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 32885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 33885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "mathops.h" 34885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "cwrs.h" 35885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "vq.h" 36885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "arch.h" 37885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "os_support.h" 38885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "bands.h" 39885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "rate.h" 40885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 41885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void exp_rotation1(celt_norm *X, int len, int stride, opus_val16 c, opus_val16 s) 42885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 43885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int i; 44885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org celt_norm *Xptr; 45885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Xptr = X; 46885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=0;i<len-stride;i++) 47885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 48885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org celt_norm x1, x2; 49885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org x1 = Xptr[0]; 50885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org x2 = Xptr[stride]; 51885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Xptr[stride] = EXTRACT16(SHR32(MULT16_16(c,x2) + MULT16_16(s,x1), 15)); 52885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org *Xptr++ = EXTRACT16(SHR32(MULT16_16(c,x1) - MULT16_16(s,x2), 15)); 53885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 54885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Xptr = &X[len-2*stride-1]; 55885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=len-2*stride-1;i>=0;i--) 56885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 57885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org celt_norm x1, x2; 58885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org x1 = Xptr[0]; 59885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org x2 = Xptr[stride]; 60885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Xptr[stride] = EXTRACT16(SHR32(MULT16_16(c,x2) + MULT16_16(s,x1), 15)); 61885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org *Xptr-- = EXTRACT16(SHR32(MULT16_16(c,x1) - MULT16_16(s,x2), 15)); 62885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 63885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 64885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 65885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void exp_rotation(celt_norm *X, int len, int dir, int stride, int K, int spread) 66885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 67885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org static const int SPREAD_FACTOR[3]={15,10,5}; 68885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int i; 69885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val16 c, s; 70885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val16 gain, theta; 71885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int stride2=0; 72885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int factor; 73885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 74885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (2*K>=len || spread==SPREAD_NONE) 75885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org return; 76885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org factor = SPREAD_FACTOR[spread-1]; 77885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 78885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org gain = celt_div((opus_val32)MULT16_16(Q15_ONE,len),(opus_val32)(len+factor*K)); 79885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org theta = HALF16(MULT16_16_Q15(gain,gain)); 80885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 81885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org c = celt_cos_norm(EXTEND32(theta)); 82885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org s = celt_cos_norm(EXTEND32(SUB16(Q15ONE,theta))); /* sin(theta) */ 83885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 84885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (len>=8*stride) 85885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 86885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org stride2 = 1; 87885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* This is just a simple (equivalent) way of computing sqrt(len/stride) with rounding. 88885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org It's basically incrementing long as (stride2+0.5)^2 < len/stride. */ 89885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org while ((stride2*stride2+stride2)*stride + (stride>>2) < len) 90885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org stride2++; 91885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 92885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /*NOTE: As a minor optimization, we could be passing around log2(B), not B, for both this and for 93885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org extract_collapse_mask().*/ 94885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org len /= stride; 95885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=0;i<stride;i++) 96885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 97885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (dir < 0) 98885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 99885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (stride2) 100885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org exp_rotation1(X+i*len, len, stride2, s, c); 101885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org exp_rotation1(X+i*len, len, 1, c, s); 102885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } else { 103885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org exp_rotation1(X+i*len, len, 1, c, -s); 104885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (stride2) 105885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org exp_rotation1(X+i*len, len, stride2, s, -c); 106885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 107885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 108885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 109885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 110885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/** Takes the pitch vector and the decoded residual vector, computes the gain 111885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org that will give ||p+g*y||=1 and mixes the residual with the pitch. */ 112885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void normalise_residual(int * OPUS_RESTRICT iy, celt_norm * OPUS_RESTRICT X, 113885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int N, opus_val32 Ryy, opus_val16 gain) 114885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 115885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int i; 116885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT 117885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int k; 118885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 119885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val32 t; 120885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val16 g; 121885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 122885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT 123885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org k = celt_ilog2(Ryy)>>1; 124885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 125885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org t = VSHR32(Ryy, 2*(k-7)); 126885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org g = MULT16_16_P15(celt_rsqrt_norm(t),gain); 127885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 128885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org i=0; 129885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org do 130885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org X[i] = EXTRACT16(PSHR32(MULT16_16(g, iy[i]), k+1)); 131885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org while (++i < N); 132885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 133885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 134885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic unsigned extract_collapse_mask(int *iy, int N, int B) 135885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 136885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org unsigned collapse_mask; 137885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int N0; 138885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int i; 139885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (B<=1) 140885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org return 1; 141885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /*NOTE: As a minor optimization, we could be passing around log2(B), not B, for both this and for 142885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org exp_rotation().*/ 143885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org N0 = N/B; 144885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org collapse_mask = 0; 145885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org i=0; do { 146885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int j; 147885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org j=0; do { 148885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org collapse_mask |= (iy[i*N0+j]!=0)<<i; 149885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } while (++j<N0); 150885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } while (++i<B); 151885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org return collapse_mask; 152885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 153885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 154885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgunsigned alg_quant(celt_norm *X, int N, int K, int spread, int B, ec_enc *enc 155885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef RESYNTH 156885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org , opus_val16 gain 157885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 158885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ) 159885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 160885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org VARDECL(celt_norm, y); 161885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org VARDECL(int, iy); 162885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org VARDECL(opus_val16, signx); 163885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int i, j; 164885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val16 s; 165885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int pulsesLeft; 166885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val32 sum; 167885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val32 xy; 168885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val16 yy; 169885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org unsigned collapse_mask; 170885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org SAVE_STACK; 171885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 172885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org celt_assert2(K>0, "alg_quant() needs at least one pulse"); 173885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org celt_assert2(N>1, "alg_quant() needs at least two dimensions"); 174885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 175885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ALLOC(y, N, celt_norm); 176885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ALLOC(iy, N, int); 177885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ALLOC(signx, N, opus_val16); 178885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 179885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org exp_rotation(X, N, 1, B, K, spread); 180885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 181885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Get rid of the sign */ 182885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org sum = 0; 183885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org j=0; do { 184885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (X[j]>0) 185885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org signx[j]=1; 186885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org else { 187885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org signx[j]=-1; 188885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org X[j]=-X[j]; 189885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 190885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org iy[j] = 0; 191885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org y[j] = 0; 192885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } while (++j<N); 193885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 194885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org xy = yy = 0; 195885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 196885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org pulsesLeft = K; 197885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 198885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Do a pre-search by projecting on the pyramid */ 199885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (K > (N>>1)) 200885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 201885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val16 rcp; 202885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org j=0; do { 203885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org sum += X[j]; 204885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } while (++j<N); 205885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 206885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* If X is too small, just replace it with a pulse at 0 */ 207885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT 208885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (sum <= K) 209885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#else 210885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Prevents infinities and NaNs from causing too many pulses 211885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org to be allocated. 64 is an approximation of infinity here. */ 212885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (!(sum > EPSILON && sum < 64)) 213885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 214885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 215885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org X[0] = QCONST16(1.f,14); 216885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org j=1; do 217885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org X[j]=0; 218885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org while (++j<N); 219885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org sum = QCONST16(1.f,14); 220885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 221885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org rcp = EXTRACT16(MULT16_32_Q16(K-1, celt_rcp(sum))); 222885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org j=0; do { 223885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT 224885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* It's really important to round *towards zero* here */ 225885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org iy[j] = MULT16_16_Q15(X[j],rcp); 226885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#else 227885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org iy[j] = (int)floor(rcp*X[j]); 228885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 229885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org y[j] = (celt_norm)iy[j]; 230885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org yy = MAC16_16(yy, y[j],y[j]); 231885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org xy = MAC16_16(xy, X[j],y[j]); 232885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org y[j] *= 2; 233885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org pulsesLeft -= iy[j]; 234885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } while (++j<N); 235885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 236885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org celt_assert2(pulsesLeft>=1, "Allocated too many pulses in the quick pass"); 237885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 238885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* This should never happen, but just in case it does (e.g. on silence) 239885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org we fill the first bin with pulses. */ 240885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT_DEBUG 241885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org celt_assert2(pulsesLeft<=N+3, "Not enough pulses in the quick pass"); 242885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 243885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (pulsesLeft > N+3) 244885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 245885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val16 tmp = (opus_val16)pulsesLeft; 246885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org yy = MAC16_16(yy, tmp, tmp); 247885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org yy = MAC16_16(yy, tmp, y[0]); 248885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org iy[0] += pulsesLeft; 249885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org pulsesLeft=0; 250885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 251885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 252885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org s = 1; 253885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=0;i<pulsesLeft;i++) 254885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 255885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int best_id; 256885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val32 best_num = -VERY_LARGE16; 257885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val16 best_den = 0; 258885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT 259885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int rshift; 260885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 261885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT 262885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org rshift = 1+celt_ilog2(K-pulsesLeft+i+1); 263885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 264885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org best_id = 0; 265885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* The squared magnitude term gets added anyway, so we might as well 266885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org add it outside the loop */ 267885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org yy = ADD32(yy, 1); 268885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org j=0; 269885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org do { 270885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val16 Rxy, Ryy; 271885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Temporary sums of the new pulse(s) */ 272885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Rxy = EXTRACT16(SHR32(ADD32(xy, EXTEND32(X[j])),rshift)); 273885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* We're multiplying y[j] by two so we don't have to do it here */ 274885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Ryy = ADD16(yy, y[j]); 275885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 276885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Approximate score: we maximise Rxy/sqrt(Ryy) (we're guaranteed that 277885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Rxy is positive because the sign is pre-computed) */ 278885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Rxy = MULT16_16_Q15(Rxy,Rxy); 279885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* The idea is to check for num/den >= best_num/best_den, but that way 280885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org we can do it without any division */ 281885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* OPT: Make sure to use conditional moves here */ 282885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (MULT16_16(best_den, Rxy) > MULT16_16(Ryy, best_num)) 283885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 284885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org best_den = Ryy; 285885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org best_num = Rxy; 286885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org best_id = j; 287885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 288885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } while (++j<N); 289885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 290885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Updating the sums of the new pulse(s) */ 291885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org xy = ADD32(xy, EXTEND32(X[best_id])); 292885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* We're multiplying y[j] by two so we don't have to do it here */ 293885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org yy = ADD16(yy, y[best_id]); 294885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 295885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Only now that we've made the final choice, update y/iy */ 296885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Multiplying y[j] by 2 so we don't have to do it everywhere else */ 297885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org y[best_id] += 2*s; 298885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org iy[best_id]++; 299885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 300885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 301885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Put the original sign back */ 302885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org j=0; 303885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org do { 304885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org X[j] = MULT16_16(signx[j],X[j]); 305885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (signx[j] < 0) 306885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org iy[j] = -iy[j]; 307885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } while (++j<N); 308885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org encode_pulses(iy, N, K, enc); 309885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 310885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef RESYNTH 311885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org normalise_residual(iy, X, N, yy, gain); 312885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org exp_rotation(X, N, -1, B, K, spread); 313885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 314885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 315885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org collapse_mask = extract_collapse_mask(iy, N, B); 316885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org RESTORE_STACK; 317885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org return collapse_mask; 318885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 319885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 320885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/** Decode pulse vector and combine the result with the pitch vector to produce 321885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org the final normalised signal in the current band. */ 322885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgunsigned alg_unquant(celt_norm *X, int N, int K, int spread, int B, 323885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ec_dec *dec, opus_val16 gain) 324885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 325885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int i; 326885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val32 Ryy; 327885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org unsigned collapse_mask; 328885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org VARDECL(int, iy); 329885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org SAVE_STACK; 330885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 331885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org celt_assert2(K>0, "alg_unquant() needs at least one pulse"); 332885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org celt_assert2(N>1, "alg_unquant() needs at least two dimensions"); 333885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ALLOC(iy, N, int); 334885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org decode_pulses(iy, N, K, dec); 335885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Ryy = 0; 336885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org i=0; 337885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org do { 338885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Ryy = MAC16_16(Ryy, iy[i], iy[i]); 339885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } while (++i < N); 340885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org normalise_residual(iy, X, N, Ryy, gain); 341885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org exp_rotation(X, N, -1, B, K, spread); 342885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org collapse_mask = extract_collapse_mask(iy, N, B); 343885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org RESTORE_STACK; 344885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org return collapse_mask; 345885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 346885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 347885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgvoid renormalise_vector(celt_norm *X, int N, opus_val16 gain) 348885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 349885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int i; 350885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT 351885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int k; 352885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 353885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val32 E = EPSILON; 354885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val16 g; 355885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val32 t; 356885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org celt_norm *xptr = X; 357885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=0;i<N;i++) 358885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 359885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org E = MAC16_16(E, *xptr, *xptr); 360885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org xptr++; 361885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 362885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT 363885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org k = celt_ilog2(E)>>1; 364885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 365885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org t = VSHR32(E, 2*(k-7)); 366885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org g = MULT16_16_P15(celt_rsqrt_norm(t),gain); 367885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 368885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org xptr = X; 369885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=0;i<N;i++) 370885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 371885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org *xptr = EXTRACT16(PSHR32(MULT16_16(g, *xptr), k+1)); 372885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org xptr++; 373885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 374885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /*return celt_sqrt(E);*/ 375885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 376885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 377885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgint stereo_itheta(celt_norm *X, celt_norm *Y, int stereo, int N) 378885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 379885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int i; 380885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int itheta; 381885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val16 mid, side; 382885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val32 Emid, Eside; 383885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 384885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Emid = Eside = EPSILON; 385885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (stereo) 386885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 387885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=0;i<N;i++) 388885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 389885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org celt_norm m, s; 390885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org m = ADD16(SHR16(X[i],1),SHR16(Y[i],1)); 391885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org s = SUB16(SHR16(X[i],1),SHR16(Y[i],1)); 392885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Emid = MAC16_16(Emid, m, m); 393885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Eside = MAC16_16(Eside, s, s); 394885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 395885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } else { 396885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=0;i<N;i++) 397885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 398885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org celt_norm m, s; 399885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org m = X[i]; 400885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org s = Y[i]; 401885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Emid = MAC16_16(Emid, m, m); 402885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Eside = MAC16_16(Eside, s, s); 403885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 404885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 405885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org mid = celt_sqrt(Emid); 406885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org side = celt_sqrt(Eside); 407885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT 408885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* 0.63662 = 2/pi */ 409885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org itheta = MULT16_16_Q15(QCONST16(0.63662f,15),celt_atan2p(side, mid)); 410885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#else 411885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org itheta = (int)floor(.5f+16384*0.63662f*atan2(side,mid)); 412885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 413885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 414885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org return itheta; 415885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 416