Skip to content
Snippets Groups Projects
Commit 6a7ee7fb authored by Jean-Marc Valin's avatar Jean-Marc Valin
Browse files

Share auto-correlation code between SILK and CELT

parent a156c5ec
No related branches found
No related tags found
No related merge requests found
...@@ -221,7 +221,7 @@ void celt_iir(const opus_val32 *_x, ...@@ -221,7 +221,7 @@ void celt_iir(const opus_val32 *_x,
#endif #endif
} }
void _celt_autocorr( int _celt_autocorr(
const opus_val16 *x, /* in: [0...n-1] samples x */ const opus_val16 *x, /* in: [0...n-1] samples x */
opus_val32 *ac, /* out: [0...lag-1] ac values */ opus_val32 *ac, /* out: [0...lag-1] ac values */
const opus_val16 *window, const opus_val16 *window,
...@@ -231,49 +231,79 @@ void _celt_autocorr( ...@@ -231,49 +231,79 @@ void _celt_autocorr(
) )
{ {
opus_val32 d; opus_val32 d;
int i; int i, k;
int fastN=n-lag; int fastN=n-lag;
int shift;
const opus_val16 *xptr;
VARDECL(opus_val16, xx); VARDECL(opus_val16, xx);
SAVE_STACK; SAVE_STACK;
ALLOC(xx, n, opus_val16); ALLOC(xx, n, opus_val16);
celt_assert(n>0); celt_assert(n>0);
celt_assert(overlap>=0); celt_assert(overlap>=0);
for (i=0;i<n;i++) if (overlap == 0)
xx[i] = x[i];
for (i=0;i<overlap;i++)
{ {
xx[i] = MULT16_16_Q15(x[i],window[i]); xptr = x;
xx[n-i-1] = MULT16_16_Q15(x[n-i-1],window[i]); } else {
for (i=0;i<n;i++)
xx[i] = x[i];
for (i=0;i<overlap;i++)
{
xx[i] = MULT16_16_Q15(x[i],window[i]);
xx[n-i-1] = MULT16_16_Q15(x[n-i-1],window[i]);
}
xptr = xx;
} }
shift=0;
#ifdef FIXED_POINT #ifdef FIXED_POINT
{ {
opus_val32 ac0; opus_val32 ac0;
int shift; ac0 = 1+(n<<7);
ac0 = 1+n; if (n&1) ac0 += SHR32(MULT16_16(xptr[0],xptr[0]),9);
if (n&1) ac0 += SHR32(MULT16_16(xx[0],xx[0]),9);
for(i=(n&1);i<n;i+=2) for(i=(n&1);i<n;i+=2)
{ {
ac0 += SHR32(MULT16_16(xx[i],xx[i]),9); ac0 += SHR32(MULT16_16(xptr[i],xptr[i]),9);
ac0 += SHR32(MULT16_16(xx[i+1],xx[i+1]),9); ac0 += SHR32(MULT16_16(xptr[i+1],xptr[i+1]),9);
} }
shift = celt_ilog2(ac0)-30+10; shift = celt_ilog2(ac0)-30+10;
shift = (shift+1)/2; shift = (shift)/2;
for(i=0;i<n;i++) if (shift>0)
xx[i] = VSHR32(xx[i], shift); {
for(i=0;i<n;i++)
xx[i] = PSHR32(xptr[i], shift);
xptr = xx;
} else
shift = 0;
} }
#endif #endif
celt_pitch_xcorr(xx, xx, ac, fastN, lag+1); celt_pitch_xcorr(xptr, xptr, ac, fastN, lag+1);
while (lag>=0) for (k=0;k<=lag;k++)
{
for (i = k+fastN, d = 0; i < n; i++)
d = MAC16_16(d, xptr[i], xptr[i-k]);
ac[k] += d;
}
#ifdef FIXED_POINT
shift = 2*shift;
if (shift<=0)
ac[0] += SHL32((opus_int32)1, -shift);
if (ac[0] < 268435456)
{ {
for (i = lag+fastN, d = 0; i < n; i++) int shift2 = 29 - EC_ILOG(ac[0]);
d = MAC16_16(d, xx[i], xx[i-lag]); for (i=0;i<=lag;i++)
ac[lag] += d; ac[i] = SHL32(ac[i], shift2);
/*printf ("%f ", ac[lag]);*/ shift -= shift2;
lag--; } else if (ac[0] >= 536870912)
{
int shift2=1;
if (ac[0] >= 1073741824)
shift2++;
for (i=0;i<=lag;i++)
ac[i] = SHR32(ac[i], shift2);
shift += shift2;
} }
/*printf ("\n");*/ #endif
ac[0] += 10;
RESTORE_STACK; RESTORE_STACK;
return shift;
} }
...@@ -48,6 +48,6 @@ void celt_iir(const opus_val32 *x, ...@@ -48,6 +48,6 @@ void celt_iir(const opus_val32 *x,
int ord, int ord,
opus_val16 *mem); opus_val16 *mem);
void _celt_autocorr(const opus_val16 *x, opus_val32 *ac, const opus_val16 *window, int overlap, int lag, int n); int _celt_autocorr(const opus_val16 *x, opus_val32 *ac, const opus_val16 *window, int overlap, int lag, int n);
#endif /* PLC_H */ #endif /* PLC_H */
...@@ -30,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. ...@@ -30,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
#endif #endif
#include "SigProc_FIX.h" #include "SigProc_FIX.h"
#include "celt_lpc.h"
/* Compute autocorrelation */ /* Compute autocorrelation */
void silk_autocorr( void silk_autocorr(
...@@ -40,37 +41,7 @@ void silk_autocorr( ...@@ -40,37 +41,7 @@ void silk_autocorr(
const opus_int correlationCount /* I Number of correlation taps to compute */ const opus_int correlationCount /* I Number of correlation taps to compute */
) )
{ {
opus_int i, lz, nRightShifts, corrCount; opus_int corrCount;
opus_int64 corr64;
corrCount = silk_min_int( inputDataSize, correlationCount ); corrCount = silk_min_int( inputDataSize, correlationCount );
*scale = _celt_autocorr(inputData, results, NULL, 0, corrCount-1, inputDataSize);
/* compute energy (zero-lag correlation) */
corr64 = silk_inner_prod16_aligned_64( inputData, inputData, inputDataSize );
/* deal with all-zero input data */
corr64 += 1;
/* number of leading zeros */
lz = silk_CLZ64( corr64 );
/* scaling: number of right shifts applied to correlations */
nRightShifts = 35 - lz;
*scale = nRightShifts;
if( nRightShifts <= 0 ) {
results[ 0 ] = silk_LSHIFT( (opus_int32)silk_CHECK_FIT32( corr64 ), -nRightShifts );
/* compute remaining correlations based on int32 inner product */
for( i = 1; i < corrCount; i++ ) {
results[ i ] = silk_LSHIFT( silk_inner_prod_aligned( inputData, inputData + i, inputDataSize - i ), -nRightShifts );
}
} else {
results[ 0 ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( corr64, nRightShifts ) );
/* compute remaining correlations based on int64 inner product */
for( i = 1; i < corrCount; i++ ) {
results[ i ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( silk_inner_prod16_aligned_64( inputData, inputData + i, inputDataSize - i ), nRightShifts ) );
}
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment