staticvoid find_best_pitch(opus_val32 *xcorr, opus_val16 *y, int len, int max_pitch, int *best_pitch #ifdef FIXED_POINT
, int yshift, opus_val32 maxcorr #endif
)
{ int i, j;
opus_val32 Syy=1;
opus_val16 best_num[2];
opus_val32 best_den[2]; #ifdef FIXED_POINT int xshift;
xshift = celt_ilog2(maxcorr)-14; #endif
best_num[0] = -1;
best_num[1] = -1;
best_den[0] = 0;
best_den[1] = 0;
best_pitch[0] = 0;
best_pitch[1] = 1; for (j=0;j<len;j++)
Syy = ADD32(Syy, SHR32(MULT16_16(y[j],y[j]), yshift)); for (i=0;i<max_pitch;i++)
{ if (xcorr[i]>0)
{
opus_val16 num;
opus_val32 xcorr16;
xcorr16 = EXTRACT16(VSHR32(xcorr[i], xshift)); #ifndef FIXED_POINT /* Considering the range of xcorr16, this should avoid both underflows
and overflows (inf) when squaring xcorr16 */
xcorr16 *= 1e-12f; #endif
num = MULT16_16_Q15(xcorr16,xcorr16); if (MULT16_32_Q15(num,best_den[1]) > MULT16_32_Q15(best_num[1],Syy))
{ if (MULT16_32_Q15(num,best_den[0]) > MULT16_32_Q15(best_num[0],Syy))
{
best_num[1] = best_num[0];
best_den[1] = best_den[0];
best_pitch[1] = best_pitch[0];
best_num[0] = num;
best_den[0] = Syy;
best_pitch[0] = i;
} else {
best_num[1] = num;
best_den[1] = Syy;
best_pitch[1] = i;
}
}
}
Syy += SHR32(MULT16_16(y[i+len],y[i+len]),yshift) - SHR32(MULT16_16(y[i],y[i]),yshift);
Syy = MAX32(1, Syy);
}
}
staticvoid celt_fir5(opus_val16 *x, const opus_val16 *num, int N)
{ int i;
opus_val16 num0, num1, num2, num3, num4;
opus_val32 mem0, mem1, mem2, mem3, mem4;
num0=num[0];
num1=num[1];
num2=num[2];
num3=num[3];
num4=num[4];
mem0=0;
mem1=0;
mem2=0;
mem3=0;
mem4=0; for (i=0;i<N;i++)
{
opus_val32 sum = SHL32(EXTEND32(x[i]), SIG_SHIFT);
sum = MAC16_16(sum,num0,mem0);
sum = MAC16_16(sum,num1,mem1);
sum = MAC16_16(sum,num2,mem2);
sum = MAC16_16(sum,num3,mem3);
sum = MAC16_16(sum,num4,mem4);
mem4 = mem3;
mem3 = mem2;
mem2 = mem1;
mem1 = mem0;
mem0 = x[i];
x[i] = ROUND16(sum, SIG_SHIFT);
}
}
void pitch_downsample(celt_sig * OPUS_RESTRICT x[], opus_val16 * OPUS_RESTRICT x_lp, int len, int C, int factor, int arch)
{ int i;
opus_val32 ac[5];
opus_val16 tmp=Q15ONE;
opus_val16 lpc[4];
opus_val16 lpc2[5];
opus_val16 c1 = QCONST16(.8f,15); int offset; #ifdef FIXED_POINT int shift;
opus_val32 maxabs; #endif
offset = factor/2; #ifdef FIXED_POINT
maxabs = celt_maxabs32(x[0], len*factor); if (C==2)
{
opus_val32 maxabs_1 = celt_maxabs32(x[1], len*factor);
maxabs = MAX32(maxabs, maxabs_1);
} if (maxabs<1)
maxabs=1;
shift = celt_ilog2(maxabs)-10; if (shift<0)
shift=0; if (C==2)
shift++; for (i=1;i<len;i++)
x_lp[i] = SHR32(x[0][(factor*i-offset)], shift+2) + SHR32(x[0][(factor*i+offset)], shift+2) + SHR32(x[0][factor*i], shift+1);
x_lp[0] = SHR32(x[0][offset], shift+2) + SHR32(x[0][0], shift+1); if (C==2)
{ for (i=1;i<len;i++)
x_lp[i] += SHR32(x[1][(factor*i-offset)], shift+2) + SHR32(x[1][(factor*i+offset)], shift+2) + SHR32(x[1][factor*i], shift+1);
x_lp[0] += SHR32(x[1][offset], shift+2) + SHR32(x[1][0], shift+1);
} #else for (i=1;i<len;i++)
x_lp[i] = .25f*x[0][(factor*i-offset)] + .25f*x[0][(factor*i+offset)] + .5f*x[0][factor*i];
x_lp[0] = .25f*x[0][offset] + .5f*x[0][0]; if (C==2)
{ for (i=1;i<len;i++)
x_lp[i] += .25f*x[1][(factor*i-offset)] + .25f*x[1][(factor*i+offset)] + .5f*x[1][factor*i];
x_lp[0] += .25f*x[1][offset] + .5f*x[1][0];
} #endif
_celt_autocorr(x_lp, ac, NULL, 0, 4, len, arch);
/* Pure C implementation. */ #ifdef FIXED_POINT
opus_val32 #else void #endif
celt_pitch_xcorr_c(const opus_val16 *_x, const opus_val16 *_y,
opus_val32 *xcorr, int len, int max_pitch, int arch)
{
#if0/* This is a simple version of the pitch correlation that should work
well on DSPs like Blackfin and TI C5x/C6x */ int i, j; #ifdef FIXED_POINT
opus_val32 maxcorr=1; #endif #if !defined(OVERRIDE_PITCH_XCORR)
(void)arch; #endif for (i=0;i<max_pitch;i++)
{
opus_val32 sum = 0; for (j=0;j<len;j++)
sum = MAC16_16(sum, _x[j], _y[i+j]);
xcorr[i] = sum; #ifdef FIXED_POINT
maxcorr = MAX32(maxcorr, sum); #endif
} #ifdef FIXED_POINT return maxcorr; #endif
#else/* Unrolled version of the pitch correlation -- runs faster on x86 and ARM */ int i; /*The EDSP version requires that max_pitch is at least 1, and that _x is 32-bitaligned.
Since it's hard to put asserts in assembly, put them here.*/ #ifdef FIXED_POINT
opus_val32 maxcorr=1; #endif
celt_assert(max_pitch>0);
celt_sig_assert(((size_t)_x&3)==0); for (i=0;i<max_pitch-3;i+=4)
{
opus_val32 sum[4]={0,0,0,0}; #ifdefined(OPUS_CHECK_ASM) && defined(FIXED_POINT)
{
opus_val32 sum_c[4]={0,0,0,0};
xcorr_kernel_c(_x, _y+i, sum_c, len); #endif
xcorr_kernel(_x, _y+i, sum, len, arch); #ifdefined(OPUS_CHECK_ASM) && defined(FIXED_POINT)
celt_assert(memcmp(sum, sum_c, sizeof(sum)) == 0);
} #endif
xcorr[i]=sum[0];
xcorr[i+1]=sum[1];
xcorr[i+2]=sum[2];
xcorr[i+3]=sum[3]; #ifdef FIXED_POINT
sum[0] = MAX32(sum[0], sum[1]);
sum[2] = MAX32(sum[2], sum[3]);
sum[0] = MAX32(sum[0], sum[2]);
maxcorr = MAX32(maxcorr, sum[0]); #endif
} /* In case max_pitch isn't a multiple of 4, do non-unrolled version. */ for (;i<max_pitch;i++)
{
opus_val32 sum;
sum = celt_inner_prod(_x, _y+i, len, arch);
xcorr[i] = sum; #ifdef FIXED_POINT
maxcorr = MAX32(maxcorr, sum); #endif
} #ifdef FIXED_POINT return maxcorr; #endif #endif
}
void pitch_search(const opus_val16 * OPUS_RESTRICT x_lp, opus_val16 * OPUS_RESTRICT y, int len, int max_pitch, int *pitch, int arch)
{ int i, j; int lag; int best_pitch[2]={0,0};
VARDECL(opus_val16, x_lp4);
VARDECL(opus_val16, y_lp4);
VARDECL(opus_val32, xcorr); #ifdef FIXED_POINT
opus_val32 maxcorr;
opus_val32 xmax, ymax; int shift=0; #endif int offset;
SAVE_STACK;
celt_assert(len>0);
celt_assert(max_pitch>0);
lag = len+max_pitch;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.