aboutsummaryrefslogtreecommitdiff
path: root/src/common_audio/signal_processing_library/main/source/auto_correlation.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common_audio/signal_processing_library/main/source/auto_correlation.c')
-rw-r--r--src/common_audio/signal_processing_library/main/source/auto_correlation.c141
1 files changed, 141 insertions, 0 deletions
diff --git a/src/common_audio/signal_processing_library/main/source/auto_correlation.c b/src/common_audio/signal_processing_library/main/source/auto_correlation.c
new file mode 100644
index 0000000000..a00fde4bc3
--- /dev/null
+++ b/src/common_audio/signal_processing_library/main/source/auto_correlation.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ * 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
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * 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"
+
+int WebRtcSpl_AutoCorrelation(G_CONST WebRtc_Word16* in_vector,
+ int in_vector_length,
+ int order,
+ WebRtc_Word32* result,
+ int* scale)
+{
+ WebRtc_Word32 sum;
+ int i, j;
+ WebRtc_Word16 smax; // Sample max
+ G_CONST WebRtc_Word16* xptr1;
+ G_CONST WebRtc_Word16* xptr2;
+ WebRtc_Word32* resultptr;
+ int scaling = 0;
+
+#ifdef _ARM_OPT_
+#pragma message("NOTE: _ARM_OPT_ optimizations are used")
+ WebRtc_Word16 loops4;
+#endif
+
+ if (order < 0)
+ order = in_vector_length;
+
+ // Find the max. sample
+ smax = WebRtcSpl_MaxAbsValueW16(in_vector, in_vector_length);
+
+ // In order to avoid overflow when computing the sum we should scale the samples so that
+ // (in_vector_length * smax * smax) will not overflow.
+
+ if (smax == 0)
+ {
+ scaling = 0;
+ } 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;
+ }
+
+ }
+
+ resultptr = result;
+
+ // Perform the actual correlation calculation
+ for (i = 0; i < order + 1; i++)
+ {
+ int loops = (in_vector_length - i);
+ sum = 0;
+ xptr1 = in_vector;
+ xptr2 = &in_vector[i];
+#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;
+ }
+
+ *scale = scaling;
+
+ return order + 1;
+}