static void exp_rotation(celt_norm *X, int len, int dir, int stride, int K, int spread) { static const int SPREAD_FACTOR[3]= {15,10,5}; int i; opus_val16 c, s; opus_val16 gain, theta; int stride2=0; int factor; if (2*K>=len || spread==SPREAD_NONE) return; factor = SPREAD_FACTOR[spread-1]; gain = celt_div((opus_val32)MULT16_16(Q15_ONE,len),(opus_val32)(len+factor*K)); theta = HALF16(MULT16_16_Q15(gain,gain)); c = celt_cos_norm(EXTEND32(theta)); s = celt_cos_norm(EXTEND32(SUB16(Q15ONE,theta))); /* sin(theta) */ if (len>=8*stride) { stride2 = 1; /* This is just a simple (equivalent) way of computing sqrt(len/stride) with rounding. It's basically incrementing long as (stride2+0.5)^2 < len/stride. */ while ((stride2*stride2+stride2)*stride + (stride>>2) < len) stride2++; }
static void exp_rotation(celt_norm *X, int len, int dir, int stride, int K) { int i, k, iter; celt_word16 c, s; celt_word16 gain, theta; celt_norm *Xptr; gain = celt_div((celt_word32)MULT16_16(Q15_ONE,len),(celt_word32)(3+len+6*K)); /* FIXME: Make that HALF16 instead of HALF32 */ theta = SUB16(Q15ONE, HALF32(MULT16_16_Q15(gain,gain))); /*if (len==30) { for (i=0;i<len;i++) X[i] = 0; X[14] = 1; }*/ c = celt_cos_norm(EXTEND32(theta)); s = dir*celt_cos_norm(EXTEND32(SUB16(Q15ONE,theta))); /* sin(theta) */ if (len > 8*stride) stride *= len/(8*stride); iter = 1; for (k=0;k<iter;k++) { /* We could use MULT16_16_P15 instead of MULT16_16_Q15 for more accuracy, but at this point, I really don't think it's necessary */ Xptr = X; for (i=0;i<len-stride;i++) { celt_norm x1, x2; x1 = Xptr[0]; x2 = Xptr[stride]; Xptr[stride] = MULT16_16_Q15(c,x2) + MULT16_16_Q15(s,x1); *Xptr++ = MULT16_16_Q15(c,x1) - MULT16_16_Q15(s,x2); } Xptr = &X[len-2*stride-1]; for (i=len-2*stride-1;i>=0;i--) { celt_norm x1, x2; x1 = Xptr[0]; x2 = Xptr[stride]; Xptr[stride] = MULT16_16_Q15(c,x2) + MULT16_16_Q15(s,x1); *Xptr-- = MULT16_16_Q15(c,x1) - MULT16_16_Q15(s,x2); } } /*if (len==30) { for (i=0;i<len;i++) printf ("%f ", X[i]); printf ("\n"); exit(0); }*/ }
void clt_mdct_init(mdct_lookup *l,int N) { int i; int N2; l->n = N; N2 = N>>1; l->kfft = cpx32_fft_alloc(N>>2); #ifndef ENABLE_TI_DSPLIB55 if (l->kfft==NULL) return; #endif l->trig = (kiss_twiddle_scalar*)celt_alloc(N2*sizeof(kiss_twiddle_scalar)); if (l->trig==NULL) return; /* We have enough points that sine isn't necessary */ #if defined(FIXED_POINT) #if defined(DOUBLE_PRECISION) & !defined(MIXED_PRECISION) for (i=0;i<N2;i++) l->trig[i] = SAMP_MAX*cos(2*M_PI*(i+1./8.)/N); #else for (i=0;i<N2;i++) l->trig[i] = TRIG_UPSCALE*celt_cos_norm(DIV32(ADD32(SHL32(EXTEND32(i),17),16386),N)); #endif #else for (i=0;i<N2;i++) l->trig[i] = cos(2*M_PI*(i+1./8.)/N); #endif }