Refactor three signal processing library files. WebRTC issue 545 is solved by the way.
Review URL: https://webrtc-codereview.appspot.com/692007 git-svn-id: http://webrtc.googlecode.com/svn/trunk@2562 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
1e1a250413
commit
8fe5f32ccc
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Use of this source code is governed by a BSD-style license
|
* Use of this source code is governed by a BSD-style license
|
||||||
* that can be found in the LICENSE file in the root of the source
|
* that can be found in the LICENSE file in the root of the source
|
||||||
@ -8,134 +8,61 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file contains the function WebRtcSpl_AutoCorrelation().
|
|
||||||
* The description header can be found in signal_processing_library.h
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "signal_processing_library.h"
|
#include "signal_processing_library.h"
|
||||||
|
|
||||||
int WebRtcSpl_AutoCorrelation(G_CONST WebRtc_Word16* in_vector,
|
int WebRtcSpl_AutoCorrelation(const int16_t* in_vector,
|
||||||
int in_vector_length,
|
int in_vector_length,
|
||||||
int order,
|
int order,
|
||||||
WebRtc_Word32* result,
|
int32_t* result,
|
||||||
int* scale)
|
int* scale) {
|
||||||
{
|
int32_t sum = 0;
|
||||||
WebRtc_Word32 sum;
|
int i = 0, j = 0;
|
||||||
int i, j;
|
int16_t smax = 0;
|
||||||
WebRtc_Word16 smax; // Sample max
|
int scaling = 0;
|
||||||
G_CONST WebRtc_Word16* xptr1;
|
|
||||||
G_CONST WebRtc_Word16* xptr2;
|
|
||||||
WebRtc_Word32* resultptr;
|
|
||||||
int scaling = 0;
|
|
||||||
|
|
||||||
#ifdef _ARM_OPT_
|
if (order > in_vector_length) {
|
||||||
#pragma message("NOTE: _ARM_OPT_ optimizations are used")
|
/* Undefined */
|
||||||
WebRtc_Word16 loops4;
|
return -1;
|
||||||
#endif
|
} else if (order < 0) {
|
||||||
|
order = in_vector_length;
|
||||||
|
}
|
||||||
|
|
||||||
if (order < 0)
|
// Find the maximum absolute value of the samples.
|
||||||
order = in_vector_length;
|
smax = WebRtcSpl_MaxAbsValueW16(in_vector, in_vector_length);
|
||||||
|
|
||||||
// Find the max. sample
|
// In order to avoid overflow when computing the sum we should scale the
|
||||||
smax = WebRtcSpl_MaxAbsValueW16(in_vector, in_vector_length);
|
// samples so that (in_vector_length * smax * smax) will not overflow.
|
||||||
|
if (smax == 0) {
|
||||||
// In order to avoid overflow when computing the sum we should scale the samples so that
|
scaling = 0;
|
||||||
// (in_vector_length * smax * smax) will not overflow.
|
} else {
|
||||||
|
// Number of bits in the sum loop.
|
||||||
if (smax == 0)
|
int nbits = WebRtcSpl_GetSizeInBits(in_vector_length);
|
||||||
{
|
// Number of bits to normalize smax.
|
||||||
scaling = 0;
|
int t = WebRtcSpl_NormW32(WEBRTC_SPL_MUL(smax, smax));
|
||||||
} else
|
|
||||||
{
|
|
||||||
int nbits = WebRtcSpl_GetSizeInBits(in_vector_length); // # of bits in the sum loop
|
|
||||||
int t = WebRtcSpl_NormW32(WEBRTC_SPL_MUL(smax, smax)); // # of bits to normalize smax
|
|
||||||
|
|
||||||
if (t > nbits)
|
|
||||||
{
|
|
||||||
scaling = 0;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
scaling = nbits - t;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (t > nbits) {
|
||||||
|
scaling = 0;
|
||||||
|
} else {
|
||||||
|
scaling = nbits - t;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
resultptr = result;
|
// Perform the actual correlation calculation.
|
||||||
|
for (i = 0; i < order + 1; i++) {
|
||||||
// Perform the actual correlation calculation
|
sum = 0;
|
||||||
for (i = 0; i < order + 1; i++)
|
/* Unroll the loop to improve performance. */
|
||||||
{
|
for (j = 0; j < in_vector_length - i - 3; j += 4) {
|
||||||
int loops = (in_vector_length - i);
|
sum += (in_vector[j + 0] * in_vector[i + j + 0]) >> scaling;
|
||||||
sum = 0;
|
sum += (in_vector[j + 1] * in_vector[i + j + 1]) >> scaling;
|
||||||
xptr1 = in_vector;
|
sum += (in_vector[j + 2] * in_vector[i + j + 2]) >> scaling;
|
||||||
xptr2 = &in_vector[i];
|
sum += (in_vector[j + 3] * in_vector[i + j + 3]) >> scaling;
|
||||||
#ifndef _ARM_OPT_
|
|
||||||
for (j = loops; j > 0; j--)
|
|
||||||
{
|
|
||||||
sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1++, *xptr2++, scaling);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
loops4 = (loops >> 2) << 2;
|
|
||||||
|
|
||||||
if (scaling == 0)
|
|
||||||
{
|
|
||||||
for (j = 0; j < loops4; j = j + 4)
|
|
||||||
{
|
|
||||||
sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2);
|
|
||||||
xptr1++;
|
|
||||||
xptr2++;
|
|
||||||
sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2);
|
|
||||||
xptr1++;
|
|
||||||
xptr2++;
|
|
||||||
sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2);
|
|
||||||
xptr1++;
|
|
||||||
xptr2++;
|
|
||||||
sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2);
|
|
||||||
xptr1++;
|
|
||||||
xptr2++;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (j = loops4; j < loops; j++)
|
|
||||||
{
|
|
||||||
sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2);
|
|
||||||
xptr1++;
|
|
||||||
xptr2++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (j = 0; j < loops4; j = j + 4)
|
|
||||||
{
|
|
||||||
sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling);
|
|
||||||
xptr1++;
|
|
||||||
xptr2++;
|
|
||||||
sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling);
|
|
||||||
xptr1++;
|
|
||||||
xptr2++;
|
|
||||||
sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling);
|
|
||||||
xptr1++;
|
|
||||||
xptr2++;
|
|
||||||
sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling);
|
|
||||||
xptr1++;
|
|
||||||
xptr2++;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (j = loops4; j < loops; j++)
|
|
||||||
{
|
|
||||||
sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling);
|
|
||||||
xptr1++;
|
|
||||||
xptr2++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
*resultptr++ = sum;
|
|
||||||
}
|
}
|
||||||
|
for (; j < in_vector_length - i; j++) {
|
||||||
|
sum += (in_vector[j] * in_vector[i + j]) >> scaling;
|
||||||
|
}
|
||||||
|
*result++ = sum;
|
||||||
|
}
|
||||||
|
|
||||||
*scale = scaling;
|
*scale = scaling;
|
||||||
|
return order + 1;
|
||||||
return order + 1;
|
|
||||||
}
|
}
|
||||||
|
@ -8,258 +8,23 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file contains the function WebRtcSpl_CrossCorrelation().
|
|
||||||
* The description header can be found in signal_processing_library.h
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* TODO(kma): Clean up the code in this file, and break it up for
|
|
||||||
* various platforms (Xscale, ARM/Neon etc.).
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "signal_processing_library.h"
|
#include "signal_processing_library.h"
|
||||||
|
|
||||||
void WebRtcSpl_CrossCorrelation(WebRtc_Word32* cross_correlation, WebRtc_Word16* seq1,
|
void WebRtcSpl_CrossCorrelation(int32_t* cross_correlation,
|
||||||
WebRtc_Word16* seq2, WebRtc_Word16 dim_seq,
|
const int16_t* seq1,
|
||||||
WebRtc_Word16 dim_cross_correlation,
|
const int16_t* seq2,
|
||||||
WebRtc_Word16 right_shifts,
|
int16_t dim_seq,
|
||||||
WebRtc_Word16 step_seq2)
|
int16_t dim_cross_correlation,
|
||||||
{
|
int16_t right_shifts,
|
||||||
int i, j;
|
int16_t step_seq2) {
|
||||||
WebRtc_Word16* seq1Ptr;
|
int i = 0, j = 0;
|
||||||
WebRtc_Word16* seq2Ptr;
|
|
||||||
WebRtc_Word32* CrossCorrPtr;
|
|
||||||
|
|
||||||
#ifdef _XSCALE_OPT_
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#pragma message("NOTE: _XSCALE_OPT_ optimizations are used (overrides _ARM_OPT_ and requires /QRxscale compiler flag)")
|
|
||||||
#endif
|
|
||||||
|
|
||||||
__int64 macc40;
|
|
||||||
|
|
||||||
int iseq1[250];
|
|
||||||
int iseq2[250];
|
|
||||||
int iseq3[250];
|
|
||||||
int * iseq1Ptr;
|
|
||||||
int * iseq2Ptr;
|
|
||||||
int * iseq3Ptr;
|
|
||||||
int len, i_len;
|
|
||||||
|
|
||||||
seq1Ptr = seq1;
|
|
||||||
iseq1Ptr = iseq1;
|
|
||||||
for(i = 0; i < ((dim_seq + 1) >> 1); i++)
|
|
||||||
{
|
|
||||||
*iseq1Ptr = (unsigned short)*seq1Ptr++;
|
|
||||||
*iseq1Ptr++ |= (WebRtc_Word32)*seq1Ptr++ << 16;
|
|
||||||
|
|
||||||
|
for (i = 0; i < dim_cross_correlation; i++) {
|
||||||
|
*cross_correlation = 0;
|
||||||
|
/* Unrolling doesn't seem to improve performance. */
|
||||||
|
for (j = 0; j < dim_seq; j++) {
|
||||||
|
*cross_correlation += (seq1[j] * seq2[step_seq2 * i + j]) >> right_shifts;
|
||||||
}
|
}
|
||||||
|
cross_correlation++;
|
||||||
if(dim_seq%2)
|
}
|
||||||
{
|
|
||||||
*(iseq1Ptr-1) &= 0x0000ffff;
|
|
||||||
}
|
|
||||||
*iseq1Ptr = 0;
|
|
||||||
iseq1Ptr++;
|
|
||||||
*iseq1Ptr = 0;
|
|
||||||
iseq1Ptr++;
|
|
||||||
*iseq1Ptr = 0;
|
|
||||||
|
|
||||||
if(step_seq2 < 0)
|
|
||||||
{
|
|
||||||
seq2Ptr = seq2 - dim_cross_correlation + 1;
|
|
||||||
CrossCorrPtr = &cross_correlation[dim_cross_correlation - 1];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
seq2Ptr = seq2;
|
|
||||||
CrossCorrPtr = cross_correlation;
|
|
||||||
}
|
|
||||||
|
|
||||||
len = dim_seq + dim_cross_correlation - 1;
|
|
||||||
i_len = (len + 1) >> 1;
|
|
||||||
iseq2Ptr = iseq2;
|
|
||||||
|
|
||||||
iseq3Ptr = iseq3;
|
|
||||||
for(i = 0; i < i_len; i++)
|
|
||||||
{
|
|
||||||
*iseq2Ptr = (unsigned short)*seq2Ptr++;
|
|
||||||
*iseq3Ptr = (unsigned short)*seq2Ptr;
|
|
||||||
*iseq2Ptr++ |= (WebRtc_Word32)*seq2Ptr++ << 16;
|
|
||||||
*iseq3Ptr++ |= (WebRtc_Word32)*seq2Ptr << 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(len % 2)
|
|
||||||
{
|
|
||||||
iseq2[i_len - 1] &= 0x0000ffff;
|
|
||||||
iseq3[i_len - 1] = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
iseq3[i_len - 1] &= 0x0000ffff;
|
|
||||||
|
|
||||||
iseq2[i_len] = 0;
|
|
||||||
iseq3[i_len] = 0;
|
|
||||||
iseq2[i_len + 1] = 0;
|
|
||||||
iseq3[i_len + 1] = 0;
|
|
||||||
iseq2[i_len + 2] = 0;
|
|
||||||
iseq3[i_len + 2] = 0;
|
|
||||||
|
|
||||||
// Set pointer to start value
|
|
||||||
iseq2Ptr = iseq2;
|
|
||||||
iseq3Ptr = iseq3;
|
|
||||||
|
|
||||||
i_len = (dim_seq + 7) >> 3;
|
|
||||||
for (i = 0; i < dim_cross_correlation; i++)
|
|
||||||
{
|
|
||||||
|
|
||||||
iseq1Ptr = iseq1;
|
|
||||||
|
|
||||||
macc40 = 0;
|
|
||||||
|
|
||||||
_WriteCoProcessor(macc40, 0);
|
|
||||||
|
|
||||||
if((i & 1))
|
|
||||||
{
|
|
||||||
iseq3Ptr = iseq3 + (i >> 1);
|
|
||||||
for (j = i_len; j > 0; j--)
|
|
||||||
{
|
|
||||||
_SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq3Ptr++);
|
|
||||||
_SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq3Ptr++);
|
|
||||||
_SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq3Ptr++);
|
|
||||||
_SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq3Ptr++);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
iseq2Ptr = iseq2 + (i >> 1);
|
|
||||||
for (j = i_len; j > 0; j--)
|
|
||||||
{
|
|
||||||
_SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq2Ptr++);
|
|
||||||
_SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq2Ptr++);
|
|
||||||
_SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq2Ptr++);
|
|
||||||
_SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq2Ptr++);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
macc40 = _ReadCoProcessor(0);
|
|
||||||
*CrossCorrPtr = (WebRtc_Word32)(macc40 >> right_shifts);
|
|
||||||
CrossCorrPtr += step_seq2;
|
|
||||||
}
|
|
||||||
#else // #ifdef _XSCALE_OPT_
|
|
||||||
#ifdef _ARM_OPT_
|
|
||||||
WebRtc_Word16 dim_seq8 = (dim_seq >> 3) << 3;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CrossCorrPtr = cross_correlation;
|
|
||||||
|
|
||||||
for (i = 0; i < dim_cross_correlation; i++)
|
|
||||||
{
|
|
||||||
// Set the pointer to the static vector, set the pointer to the sliding vector
|
|
||||||
// and initialize cross_correlation
|
|
||||||
seq1Ptr = seq1;
|
|
||||||
seq2Ptr = seq2 + (step_seq2 * i);
|
|
||||||
(*CrossCorrPtr) = 0;
|
|
||||||
|
|
||||||
#ifndef _ARM_OPT_
|
|
||||||
// Perform the cross correlation
|
|
||||||
for (j = 0; j < dim_seq; j++)
|
|
||||||
{
|
|
||||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), right_shifts);
|
|
||||||
seq1Ptr++;
|
|
||||||
seq2Ptr++;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (right_shifts == 0)
|
|
||||||
{
|
|
||||||
// Perform the optimized cross correlation
|
|
||||||
for (j = 0; j < dim_seq8; j = j + 8)
|
|
||||||
{
|
|
||||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
|
|
||||||
seq1Ptr++;
|
|
||||||
seq2Ptr++;
|
|
||||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
|
|
||||||
seq1Ptr++;
|
|
||||||
seq2Ptr++;
|
|
||||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
|
|
||||||
seq1Ptr++;
|
|
||||||
seq2Ptr++;
|
|
||||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
|
|
||||||
seq1Ptr++;
|
|
||||||
seq2Ptr++;
|
|
||||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
|
|
||||||
seq1Ptr++;
|
|
||||||
seq2Ptr++;
|
|
||||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
|
|
||||||
seq1Ptr++;
|
|
||||||
seq2Ptr++;
|
|
||||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
|
|
||||||
seq1Ptr++;
|
|
||||||
seq2Ptr++;
|
|
||||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
|
|
||||||
seq1Ptr++;
|
|
||||||
seq2Ptr++;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (j = dim_seq8; j < dim_seq; j++)
|
|
||||||
{
|
|
||||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
|
|
||||||
seq1Ptr++;
|
|
||||||
seq2Ptr++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // right_shifts != 0
|
|
||||||
|
|
||||||
{
|
|
||||||
// Perform the optimized cross correlation
|
|
||||||
for (j = 0; j < dim_seq8; j = j + 8)
|
|
||||||
{
|
|
||||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
|
|
||||||
right_shifts);
|
|
||||||
seq1Ptr++;
|
|
||||||
seq2Ptr++;
|
|
||||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
|
|
||||||
right_shifts);
|
|
||||||
seq1Ptr++;
|
|
||||||
seq2Ptr++;
|
|
||||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
|
|
||||||
right_shifts);
|
|
||||||
seq1Ptr++;
|
|
||||||
seq2Ptr++;
|
|
||||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
|
|
||||||
right_shifts);
|
|
||||||
seq1Ptr++;
|
|
||||||
seq2Ptr++;
|
|
||||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
|
|
||||||
right_shifts);
|
|
||||||
seq1Ptr++;
|
|
||||||
seq2Ptr++;
|
|
||||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
|
|
||||||
right_shifts);
|
|
||||||
seq1Ptr++;
|
|
||||||
seq2Ptr++;
|
|
||||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
|
|
||||||
right_shifts);
|
|
||||||
seq1Ptr++;
|
|
||||||
seq2Ptr++;
|
|
||||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
|
|
||||||
right_shifts);
|
|
||||||
seq1Ptr++;
|
|
||||||
seq2Ptr++;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (j = dim_seq8; j < dim_seq; j++)
|
|
||||||
{
|
|
||||||
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
|
|
||||||
right_shifts);
|
|
||||||
seq1Ptr++;
|
|
||||||
seq2Ptr++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
CrossCorrPtr++;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Use of this source code is governed by a BSD-style license
|
* Use of this source code is governed by a BSD-style license
|
||||||
* that can be found in the LICENSE file in the root of the source
|
* that can be found in the LICENSE file in the root of the source
|
||||||
@ -8,84 +8,25 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file contains the function WebRtcSpl_DotProductWithScale().
|
|
||||||
* The description header can be found in signal_processing_library.h
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "signal_processing_library.h"
|
#include "signal_processing_library.h"
|
||||||
|
|
||||||
WebRtc_Word32 WebRtcSpl_DotProductWithScale(WebRtc_Word16 *vector1, WebRtc_Word16 *vector2,
|
int32_t WebRtcSpl_DotProductWithScale(const int16_t* vector1,
|
||||||
int length, int scaling)
|
const int16_t* vector2,
|
||||||
{
|
int length,
|
||||||
WebRtc_Word32 sum;
|
int scaling) {
|
||||||
int i;
|
int32_t sum = 0;
|
||||||
#ifdef _ARM_OPT_
|
int i = 0;
|
||||||
#pragma message("NOTE: _ARM_OPT_ optimizations are used")
|
|
||||||
WebRtc_Word16 len4 = (length >> 2) << 2;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
sum = 0;
|
/* Unroll the loop to improve performance. */
|
||||||
|
for (i = 0; i < length - 3; i += 4) {
|
||||||
|
sum += (vector1[i + 0] * vector2[i + 0]) >> scaling;
|
||||||
|
sum += (vector1[i + 1] * vector2[i + 1]) >> scaling;
|
||||||
|
sum += (vector1[i + 2] * vector2[i + 2]) >> scaling;
|
||||||
|
sum += (vector1[i + 3] * vector2[i + 3]) >> scaling;
|
||||||
|
}
|
||||||
|
for (; i < length; i++) {
|
||||||
|
sum += (vector1[i] * vector2[i]) >> scaling;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef _ARM_OPT_
|
return sum;
|
||||||
for (i = 0; i < length; i++)
|
|
||||||
{
|
|
||||||
sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1++, *vector2++, scaling);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (scaling == 0)
|
|
||||||
{
|
|
||||||
for (i = 0; i < len4; i = i + 4)
|
|
||||||
{
|
|
||||||
sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2);
|
|
||||||
vector1++;
|
|
||||||
vector2++;
|
|
||||||
sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2);
|
|
||||||
vector1++;
|
|
||||||
vector2++;
|
|
||||||
sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2);
|
|
||||||
vector1++;
|
|
||||||
vector2++;
|
|
||||||
sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2);
|
|
||||||
vector1++;
|
|
||||||
vector2++;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = len4; i < length; i++)
|
|
||||||
{
|
|
||||||
sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2);
|
|
||||||
vector1++;
|
|
||||||
vector2++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (i = 0; i < len4; i = i + 4)
|
|
||||||
{
|
|
||||||
sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling);
|
|
||||||
vector1++;
|
|
||||||
vector2++;
|
|
||||||
sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling);
|
|
||||||
vector1++;
|
|
||||||
vector2++;
|
|
||||||
sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling);
|
|
||||||
vector1++;
|
|
||||||
vector2++;
|
|
||||||
sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling);
|
|
||||||
vector1++;
|
|
||||||
vector2++;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = len4; i < length; i++)
|
|
||||||
{
|
|
||||||
sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling);
|
|
||||||
vector1++;
|
|
||||||
vector2++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return sum;
|
|
||||||
}
|
}
|
||||||
|
@ -419,32 +419,146 @@ void WebRtcSpl_AffineTransformVector(WebRtc_Word16* out_vector,
|
|||||||
int vector_length);
|
int vector_length);
|
||||||
// End: iLBC specific functions.
|
// End: iLBC specific functions.
|
||||||
|
|
||||||
// Signal processing operations. Descriptions at bottom of this file.
|
// Signal processing operations.
|
||||||
int WebRtcSpl_AutoCorrelation(G_CONST WebRtc_Word16* vector,
|
|
||||||
int vector_length, int order,
|
// A 32-bit fix-point implementation of auto-correlation computation
|
||||||
WebRtc_Word32* result_vector,
|
//
|
||||||
|
// Input:
|
||||||
|
// - in_vector : Vector to calculate autocorrelation upon
|
||||||
|
// - in_vector_length : Length (in samples) of |vector|
|
||||||
|
// - order : The order up to which the autocorrelation should be
|
||||||
|
// calculated
|
||||||
|
//
|
||||||
|
// Output:
|
||||||
|
// - result : auto-correlation values (values should be seen
|
||||||
|
// relative to each other since the absolute values
|
||||||
|
// might have been down shifted to avoid overflow)
|
||||||
|
//
|
||||||
|
// - scale : The number of left shifts required to obtain the
|
||||||
|
// auto-correlation in Q0
|
||||||
|
//
|
||||||
|
// Return value :
|
||||||
|
// - -1, if |order| > |in_vector_length|;
|
||||||
|
// - Number of samples in |result|, i.e. (order+1), otherwise.
|
||||||
|
int WebRtcSpl_AutoCorrelation(const int16_t* in_vector,
|
||||||
|
int in_vector_length,
|
||||||
|
int order,
|
||||||
|
int32_t* result,
|
||||||
int* scale);
|
int* scale);
|
||||||
|
|
||||||
|
// A 32-bit fix-point implementation of the Levinson-Durbin algorithm that
|
||||||
|
// does NOT use the 64 bit class
|
||||||
|
//
|
||||||
|
// Input:
|
||||||
|
// - auto_corr : Vector with autocorrelation values of length >=
|
||||||
|
// |use_order|+1
|
||||||
|
// - use_order : The LPC filter order (support up to order 20)
|
||||||
|
//
|
||||||
|
// Output:
|
||||||
|
// - lpc_coef : lpc_coef[0..use_order] LPC coefficients in Q12
|
||||||
|
// - refl_coef : refl_coef[0...use_order-1]| Reflection coefficients in
|
||||||
|
// Q15
|
||||||
|
//
|
||||||
|
// Return value : 1 for stable 0 for unstable
|
||||||
WebRtc_Word16 WebRtcSpl_LevinsonDurbin(WebRtc_Word32* auto_corr,
|
WebRtc_Word16 WebRtcSpl_LevinsonDurbin(WebRtc_Word32* auto_corr,
|
||||||
WebRtc_Word16* lpc_coef,
|
WebRtc_Word16* lpc_coef,
|
||||||
WebRtc_Word16* refl_coef,
|
WebRtc_Word16* refl_coef,
|
||||||
WebRtc_Word16 order);
|
WebRtc_Word16 order);
|
||||||
|
|
||||||
|
// Converts reflection coefficients |refl_coef| to LPC coefficients |lpc_coef|.
|
||||||
|
// This version is a 16 bit operation.
|
||||||
|
//
|
||||||
|
// NOTE: The 16 bit refl_coef -> lpc_coef conversion might result in a
|
||||||
|
// "slightly unstable" filter (i.e., a pole just outside the unit circle) in
|
||||||
|
// "rare" cases even if the reflection coefficients are stable.
|
||||||
|
//
|
||||||
|
// Input:
|
||||||
|
// - refl_coef : Reflection coefficients in Q15 that should be converted
|
||||||
|
// to LPC coefficients
|
||||||
|
// - use_order : Number of coefficients in |refl_coef|
|
||||||
|
//
|
||||||
|
// Output:
|
||||||
|
// - lpc_coef : LPC coefficients in Q12
|
||||||
void WebRtcSpl_ReflCoefToLpc(G_CONST WebRtc_Word16* refl_coef,
|
void WebRtcSpl_ReflCoefToLpc(G_CONST WebRtc_Word16* refl_coef,
|
||||||
int use_order,
|
int use_order,
|
||||||
WebRtc_Word16* lpc_coef);
|
WebRtc_Word16* lpc_coef);
|
||||||
|
|
||||||
|
// Converts LPC coefficients |lpc_coef| to reflection coefficients |refl_coef|.
|
||||||
|
// This version is a 16 bit operation.
|
||||||
|
// The conversion is implemented by the step-down algorithm.
|
||||||
|
//
|
||||||
|
// Input:
|
||||||
|
// - lpc_coef : LPC coefficients in Q12, that should be converted to
|
||||||
|
// reflection coefficients
|
||||||
|
// - use_order : Number of coefficients in |lpc_coef|
|
||||||
|
//
|
||||||
|
// Output:
|
||||||
|
// - refl_coef : Reflection coefficients in Q15.
|
||||||
void WebRtcSpl_LpcToReflCoef(WebRtc_Word16* lpc_coef,
|
void WebRtcSpl_LpcToReflCoef(WebRtc_Word16* lpc_coef,
|
||||||
int use_order,
|
int use_order,
|
||||||
WebRtc_Word16* refl_coef);
|
WebRtc_Word16* refl_coef);
|
||||||
|
|
||||||
|
// Calculates reflection coefficients (16 bit) from auto-correlation values
|
||||||
|
//
|
||||||
|
// Input:
|
||||||
|
// - auto_corr : Auto-correlation values
|
||||||
|
// - use_order : Number of coefficients wanted be calculated
|
||||||
|
//
|
||||||
|
// Output:
|
||||||
|
// - refl_coef : Reflection coefficients in Q15.
|
||||||
void WebRtcSpl_AutoCorrToReflCoef(G_CONST WebRtc_Word32* auto_corr,
|
void WebRtcSpl_AutoCorrToReflCoef(G_CONST WebRtc_Word32* auto_corr,
|
||||||
int use_order,
|
int use_order,
|
||||||
WebRtc_Word16* refl_coef);
|
WebRtc_Word16* refl_coef);
|
||||||
void WebRtcSpl_CrossCorrelation(WebRtc_Word32* cross_corr,
|
|
||||||
WebRtc_Word16* vector1,
|
// Calculates the cross-correlation between two sequences |seq1| and |seq2|.
|
||||||
WebRtc_Word16* vector2,
|
// |seq1| is fixed and |seq2| slides as the pointer is increased with the
|
||||||
WebRtc_Word16 dim_vector,
|
// amount |step_seq2|. Note the arguments should obey the relationship:
|
||||||
WebRtc_Word16 dim_cross_corr,
|
// |dim_seq| - 1 + |step_seq2| * (|dim_cross_correlation| - 1) <
|
||||||
WebRtc_Word16 right_shifts,
|
// buffer size of |seq2|
|
||||||
WebRtc_Word16 step_vector2);
|
//
|
||||||
|
// Input:
|
||||||
|
// - seq1 : First sequence (fixed throughout the correlation)
|
||||||
|
// - seq2 : Second sequence (slides |step_vector2| for each
|
||||||
|
// new correlation)
|
||||||
|
// - dim_seq : Number of samples to use in the cross-correlation
|
||||||
|
// - dim_cross_correlation : Number of cross-correlations to calculate (the
|
||||||
|
// start position for |vector2| is updated for each
|
||||||
|
// new one)
|
||||||
|
// - right_shifts : Number of right bit shifts to use. This will
|
||||||
|
// become the output Q-domain.
|
||||||
|
// - step_seq2 : How many (positive or negative) steps the
|
||||||
|
// |vector2| pointer should be updated for each new
|
||||||
|
// cross-correlation value.
|
||||||
|
//
|
||||||
|
// Output:
|
||||||
|
// - cross_correlation : The cross-correlation in Q(-right_shifts)
|
||||||
|
void WebRtcSpl_CrossCorrelation(int32_t* cross_correlation,
|
||||||
|
const int16_t* seq1,
|
||||||
|
const int16_t* seq2,
|
||||||
|
int16_t dim_seq,
|
||||||
|
int16_t dim_cross_correlation,
|
||||||
|
int16_t right_shifts,
|
||||||
|
int16_t step_seq2);
|
||||||
|
|
||||||
|
// Creates (the first half of) a Hanning window. Size must be at least 1 and
|
||||||
|
// at most 512.
|
||||||
|
//
|
||||||
|
// Input:
|
||||||
|
// - size : Length of the requested Hanning window (1 to 512)
|
||||||
|
//
|
||||||
|
// Output:
|
||||||
|
// - window : Hanning vector in Q14.
|
||||||
void WebRtcSpl_GetHanningWindow(WebRtc_Word16* window, WebRtc_Word16 size);
|
void WebRtcSpl_GetHanningWindow(WebRtc_Word16* window, WebRtc_Word16 size);
|
||||||
|
|
||||||
|
// Calculates y[k] = sqrt(1 - x[k]^2) for each element of the input vector
|
||||||
|
// |in_vector|. Input and output values are in Q15.
|
||||||
|
//
|
||||||
|
// Inputs:
|
||||||
|
// - in_vector : Values to calculate sqrt(1 - x^2) of
|
||||||
|
// - vector_length : Length of vector |in_vector|
|
||||||
|
//
|
||||||
|
// Output:
|
||||||
|
// - out_vector : Output values in Q15
|
||||||
void WebRtcSpl_SqrtOfOneMinusXSquared(WebRtc_Word16* in_vector,
|
void WebRtcSpl_SqrtOfOneMinusXSquared(WebRtc_Word16* in_vector,
|
||||||
int vector_length,
|
int vector_length,
|
||||||
WebRtc_Word16* out_vector);
|
WebRtc_Word16* out_vector);
|
||||||
@ -478,10 +592,21 @@ WebRtc_Word32 WebRtcSpl_Energy(WebRtc_Word16* vector,
|
|||||||
int vector_length,
|
int vector_length,
|
||||||
int* scale_factor);
|
int* scale_factor);
|
||||||
|
|
||||||
WebRtc_Word32 WebRtcSpl_DotProductWithScale(WebRtc_Word16* vector1,
|
// Calculates the dot product between two (WebRtc_Word16) vectors.
|
||||||
WebRtc_Word16* vector2,
|
//
|
||||||
int vector_length,
|
// Input:
|
||||||
int scaling);
|
// - vector1 : Vector 1
|
||||||
|
// - vector2 : Vector 2
|
||||||
|
// - vector_length : Number of samples used in the dot product
|
||||||
|
// - scaling : The number of right bit shifts to apply on each term
|
||||||
|
// during calculation to avoid overflow, i.e., the
|
||||||
|
// output will be in Q(-|scaling|)
|
||||||
|
//
|
||||||
|
// Return value : The dot product in Q(-scaling)
|
||||||
|
int32_t WebRtcSpl_DotProductWithScale(const int16_t* vector1,
|
||||||
|
const int16_t* vector2,
|
||||||
|
int length,
|
||||||
|
int scaling);
|
||||||
|
|
||||||
// Filter operations.
|
// Filter operations.
|
||||||
int WebRtcSpl_FilterAR(G_CONST WebRtc_Word16* ar_coef, int ar_coef_length,
|
int WebRtcSpl_FilterAR(G_CONST WebRtc_Word16* ar_coef, int ar_coef_length,
|
||||||
@ -1116,147 +1241,6 @@ void WebRtcSpl_SynthesisQMF(const WebRtc_Word16* low_band,
|
|||||||
// - out_vector : Vector with the output
|
// - out_vector : Vector with the output
|
||||||
//
|
//
|
||||||
|
|
||||||
//
|
|
||||||
// WebRtcSpl_AutoCorrelation(...)
|
|
||||||
//
|
|
||||||
// A 32-bit fix-point implementation of auto-correlation computation
|
|
||||||
//
|
|
||||||
// Input:
|
|
||||||
// - vector : Vector to calculate autocorrelation upon
|
|
||||||
// - vector_length : Length (in samples) of |vector|
|
|
||||||
// - order : The order up to which the autocorrelation should be
|
|
||||||
// calculated
|
|
||||||
//
|
|
||||||
// Output:
|
|
||||||
// - result_vector : auto-correlation values (values should be seen
|
|
||||||
// relative to each other since the absolute values
|
|
||||||
// might have been down shifted to avoid overflow)
|
|
||||||
//
|
|
||||||
// - scale : The number of left shifts required to obtain the
|
|
||||||
// auto-correlation in Q0
|
|
||||||
//
|
|
||||||
// Return value : Number of samples in |result_vector|, i.e., (order+1)
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
|
||||||
// WebRtcSpl_LevinsonDurbin(...)
|
|
||||||
//
|
|
||||||
// A 32-bit fix-point implementation of the Levinson-Durbin algorithm that
|
|
||||||
// does NOT use the 64 bit class
|
|
||||||
//
|
|
||||||
// Input:
|
|
||||||
// - auto_corr : Vector with autocorrelation values of length >=
|
|
||||||
// |use_order|+1
|
|
||||||
// - use_order : The LPC filter order (support up to order 20)
|
|
||||||
//
|
|
||||||
// Output:
|
|
||||||
// - lpc_coef : lpc_coef[0..use_order] LPC coefficients in Q12
|
|
||||||
// - refl_coef : refl_coef[0...use_order-1]| Reflection coefficients in
|
|
||||||
// Q15
|
|
||||||
//
|
|
||||||
// Return value : 1 for stable 0 for unstable
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
|
||||||
// WebRtcSpl_ReflCoefToLpc(...)
|
|
||||||
//
|
|
||||||
// Converts reflection coefficients |refl_coef| to LPC coefficients |lpc_coef|.
|
|
||||||
// This version is a 16 bit operation.
|
|
||||||
//
|
|
||||||
// NOTE: The 16 bit refl_coef -> lpc_coef conversion might result in a
|
|
||||||
// "slightly unstable" filter (i.e., a pole just outside the unit circle) in
|
|
||||||
// "rare" cases even if the reflection coefficients are stable.
|
|
||||||
//
|
|
||||||
// Input:
|
|
||||||
// - refl_coef : Reflection coefficients in Q15 that should be converted
|
|
||||||
// to LPC coefficients
|
|
||||||
// - use_order : Number of coefficients in |refl_coef|
|
|
||||||
//
|
|
||||||
// Output:
|
|
||||||
// - lpc_coef : LPC coefficients in Q12
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
|
||||||
// WebRtcSpl_LpcToReflCoef(...)
|
|
||||||
//
|
|
||||||
// Converts LPC coefficients |lpc_coef| to reflection coefficients |refl_coef|.
|
|
||||||
// This version is a 16 bit operation.
|
|
||||||
// The conversion is implemented by the step-down algorithm.
|
|
||||||
//
|
|
||||||
// Input:
|
|
||||||
// - lpc_coef : LPC coefficients in Q12, that should be converted to
|
|
||||||
// reflection coefficients
|
|
||||||
// - use_order : Number of coefficients in |lpc_coef|
|
|
||||||
//
|
|
||||||
// Output:
|
|
||||||
// - refl_coef : Reflection coefficients in Q15.
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
|
||||||
// WebRtcSpl_AutoCorrToReflCoef(...)
|
|
||||||
//
|
|
||||||
// Calculates reflection coefficients (16 bit) from auto-correlation values
|
|
||||||
//
|
|
||||||
// Input:
|
|
||||||
// - auto_corr : Auto-correlation values
|
|
||||||
// - use_order : Number of coefficients wanted be calculated
|
|
||||||
//
|
|
||||||
// Output:
|
|
||||||
// - refl_coef : Reflection coefficients in Q15.
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
|
||||||
// WebRtcSpl_CrossCorrelation(...)
|
|
||||||
//
|
|
||||||
// Calculates the cross-correlation between two sequences |vector1| and
|
|
||||||
// |vector2|. |vector1| is fixed and |vector2| slides as the pointer is
|
|
||||||
// increased with the amount |step_vector2|
|
|
||||||
//
|
|
||||||
// Input:
|
|
||||||
// - vector1 : First sequence (fixed throughout the correlation)
|
|
||||||
// - vector2 : Second sequence (slides |step_vector2| for each
|
|
||||||
// new correlation)
|
|
||||||
// - dim_vector : Number of samples to use in the cross-correlation
|
|
||||||
// - dim_cross_corr : Number of cross-correlations to calculate (the
|
|
||||||
// start position for |vector2| is updated for each
|
|
||||||
// new one)
|
|
||||||
// - right_shifts : Number of right bit shifts to use. This will
|
|
||||||
// become the output Q-domain.
|
|
||||||
// - step_vector2 : How many (positive or negative) steps the
|
|
||||||
// |vector2| pointer should be updated for each new
|
|
||||||
// cross-correlation value.
|
|
||||||
//
|
|
||||||
// Output:
|
|
||||||
// - cross_corr : The cross-correlation in Q(-right_shifts)
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
|
||||||
// WebRtcSpl_GetHanningWindow(...)
|
|
||||||
//
|
|
||||||
// Creates (the first half of) a Hanning window. Size must be at least 1 and
|
|
||||||
// at most 512.
|
|
||||||
//
|
|
||||||
// Input:
|
|
||||||
// - size : Length of the requested Hanning window (1 to 512)
|
|
||||||
//
|
|
||||||
// Output:
|
|
||||||
// - window : Hanning vector in Q14.
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
|
||||||
// WebRtcSpl_SqrtOfOneMinusXSquared(...)
|
|
||||||
//
|
|
||||||
// Calculates y[k] = sqrt(1 - x[k]^2) for each element of the input vector
|
|
||||||
// |in_vector|. Input and output values are in Q15.
|
|
||||||
//
|
|
||||||
// Inputs:
|
|
||||||
// - in_vector : Values to calculate sqrt(1 - x^2) of
|
|
||||||
// - vector_length : Length of vector |in_vector|
|
|
||||||
//
|
|
||||||
// Output:
|
|
||||||
// - out_vector : Output values in Q15
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// WebRtcSpl_IncreaseSeed(...)
|
// WebRtcSpl_IncreaseSeed(...)
|
||||||
//
|
//
|
||||||
@ -1492,23 +1476,6 @@ void WebRtcSpl_SynthesisQMF(const WebRtc_Word16* low_band,
|
|||||||
// - out_vector : Filtered samples
|
// - out_vector : Filtered samples
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// WebRtcSpl_DotProductWithScale(...)
|
|
||||||
//
|
|
||||||
// Calculates the dot product between two (WebRtc_Word16) vectors
|
|
||||||
//
|
|
||||||
// Input:
|
|
||||||
// - vector1 : Vector 1
|
|
||||||
// - vector2 : Vector 2
|
|
||||||
// - vector_length : Number of samples used in the dot product
|
|
||||||
// - scaling : The number of right bit shifts to apply on each term
|
|
||||||
// during calculation to avoid overflow, i.e., the
|
|
||||||
// output will be in Q(-|scaling|)
|
|
||||||
//
|
|
||||||
// Return value : The dot product in Q(-scaling)
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// WebRtcSpl_ComplexIFFT(...)
|
// WebRtcSpl_ComplexIFFT(...)
|
||||||
//
|
//
|
||||||
|
@ -11,6 +11,10 @@
|
|||||||
#include "signal_processing_library.h"
|
#include "signal_processing_library.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
static const int kVector16Size = 9;
|
||||||
|
static const int16_t vector16[kVector16Size] = {1, -15511, 4323, 1963,
|
||||||
|
WEBRTC_SPL_WORD16_MAX, 0, WEBRTC_SPL_WORD16_MIN + 5, -3333, 345};
|
||||||
|
|
||||||
class SplTest : public testing::Test {
|
class SplTest : public testing::Test {
|
||||||
protected:
|
protected:
|
||||||
virtual ~SplTest() {
|
virtual ~SplTest() {
|
||||||
@ -253,7 +257,6 @@ TEST_F(SplTest, VectorOperationsTest) {
|
|||||||
int B[] = {4, 12, 133, 1100};
|
int B[] = {4, 12, 133, 1100};
|
||||||
WebRtc_Word16 a16[kVectorSize];
|
WebRtc_Word16 a16[kVectorSize];
|
||||||
WebRtc_Word16 b16[kVectorSize];
|
WebRtc_Word16 b16[kVectorSize];
|
||||||
WebRtc_Word32 b32[kVectorSize];
|
|
||||||
WebRtc_Word16 bTmp16[kVectorSize];
|
WebRtc_Word16 bTmp16[kVectorSize];
|
||||||
|
|
||||||
for (int kk = 0; kk < kVectorSize; ++kk) {
|
for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||||
@ -275,13 +278,6 @@ TEST_F(SplTest, VectorOperationsTest) {
|
|||||||
EXPECT_EQ(((B[kk]*3+B[kk]*2+2)>>2)+((b16[kk]*3+7)>>2), bTmp16[kk]);
|
EXPECT_EQ(((B[kk]*3+B[kk]*2+2)>>2)+((b16[kk]*3+7)>>2), bTmp16[kk]);
|
||||||
}
|
}
|
||||||
|
|
||||||
WebRtcSpl_CrossCorrelation(b32, b16, bTmp16, kVectorSize, 2, 2, 0);
|
|
||||||
for (int kk = 0; kk < 2; ++kk) {
|
|
||||||
EXPECT_EQ(614236, b32[kk]);
|
|
||||||
}
|
|
||||||
// EXPECT_EQ(, WebRtcSpl_DotProduct(b16, bTmp16, 4));
|
|
||||||
EXPECT_EQ(306962, WebRtcSpl_DotProductWithScale(b16, b16, kVectorSize, 2));
|
|
||||||
|
|
||||||
WebRtcSpl_ScaleVector(b16, bTmp16, 13, kVectorSize, 2);
|
WebRtcSpl_ScaleVector(b16, bTmp16, 13, kVectorSize, 2);
|
||||||
for (int kk = 0; kk < kVectorSize; ++kk) {
|
for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||||
EXPECT_EQ((b16[kk]*13)>>2, bTmp16[kk]);
|
EXPECT_EQ((b16[kk]*13)>>2, bTmp16[kk]);
|
||||||
@ -391,6 +387,47 @@ TEST_F(SplTest, RandTest) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(SplTest, DotProductWithScaleTest) {
|
||||||
|
EXPECT_EQ(605362796, WebRtcSpl_DotProductWithScale(vector16,
|
||||||
|
vector16, kVector16Size, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SplTest, CrossCorrelationTest) {
|
||||||
|
// Note the function arguments relation specificed by API.
|
||||||
|
const int kCrossCorrelationDimension = 3;
|
||||||
|
const int kShift = 2;
|
||||||
|
const int kStep = 1;
|
||||||
|
const int kSeqDimension = 6;
|
||||||
|
|
||||||
|
const int16_t vector16_b[kVector16Size] = {1, 4323, 1963,
|
||||||
|
WEBRTC_SPL_WORD16_MAX, WEBRTC_SPL_WORD16_MIN + 5, -3333, -876, 8483, 142};
|
||||||
|
const int32_t expected[3] = {-266947903, -15579555, -171282001};
|
||||||
|
int32_t vector32[kCrossCorrelationDimension] = {0};
|
||||||
|
|
||||||
|
WebRtcSpl_CrossCorrelation(vector32, vector16, vector16_b, kSeqDimension,
|
||||||
|
kCrossCorrelationDimension, kShift, kStep);
|
||||||
|
|
||||||
|
for (int i = 0; i < kCrossCorrelationDimension; ++i) {
|
||||||
|
EXPECT_EQ(expected[i], vector32[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SplTest, AutoCorrelationTest) {
|
||||||
|
int scale = 0;
|
||||||
|
int32_t vector32[kVector16Size];
|
||||||
|
const int32_t expected[kVector16Size] = {302681398, 14223410, -121705063,
|
||||||
|
-85221647, -17104971, 61806945, 6644603, -669329, 43};
|
||||||
|
|
||||||
|
EXPECT_EQ(-1, WebRtcSpl_AutoCorrelation(vector16,
|
||||||
|
kVector16Size, kVector16Size + 1, vector32, &scale));
|
||||||
|
EXPECT_EQ(kVector16Size, WebRtcSpl_AutoCorrelation(vector16,
|
||||||
|
kVector16Size, kVector16Size - 1, vector32, &scale));
|
||||||
|
EXPECT_EQ(3, scale);
|
||||||
|
for (int i = 0; i < kVector16Size; ++i) {
|
||||||
|
EXPECT_EQ(expected[i], vector32[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(SplTest, SignalProcessingTest) {
|
TEST_F(SplTest, SignalProcessingTest) {
|
||||||
const int kVectorSize = 4;
|
const int kVectorSize = 4;
|
||||||
int A[] = {1, 2, 33, 100};
|
int A[] = {1, 2, 33, 100};
|
||||||
@ -398,7 +435,6 @@ TEST_F(SplTest, SignalProcessingTest) {
|
|||||||
WebRtc_Word16 b16[kVectorSize];
|
WebRtc_Word16 b16[kVectorSize];
|
||||||
|
|
||||||
WebRtc_Word16 bTmp16[kVectorSize];
|
WebRtc_Word16 bTmp16[kVectorSize];
|
||||||
WebRtc_Word32 bTmp32[kVectorSize];
|
|
||||||
|
|
||||||
int bScale = 0;
|
int bScale = 0;
|
||||||
|
|
||||||
@ -406,7 +442,6 @@ TEST_F(SplTest, SignalProcessingTest) {
|
|||||||
b16[kk] = A[kk];
|
b16[kk] = A[kk];
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPECT_EQ(2, WebRtcSpl_AutoCorrelation(b16, kVectorSize, 1, bTmp32, &bScale));
|
|
||||||
// TODO(bjornv): Activate the Reflection Coefficient tests when refactoring.
|
// TODO(bjornv): Activate the Reflection Coefficient tests when refactoring.
|
||||||
// WebRtcSpl_ReflCoefToLpc(b16, kVectorSize, bTmp16);
|
// WebRtcSpl_ReflCoefToLpc(b16, kVectorSize, bTmp16);
|
||||||
//// for (int kk = 0; kk < kVectorSize; ++kk) {
|
//// for (int kk = 0; kk < kVectorSize; ++kk) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user