summaryrefslogtreecommitdiff
path: root/third_party/webrtc/src/webrtc/common_audio/signal_processing/division_operations.c
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/webrtc/src/webrtc/common_audio/signal_processing/division_operations.c')
-rw-r--r--third_party/webrtc/src/webrtc/common_audio/signal_processing/division_operations.c138
1 files changed, 138 insertions, 0 deletions
diff --git a/third_party/webrtc/src/webrtc/common_audio/signal_processing/division_operations.c b/third_party/webrtc/src/webrtc/common_audio/signal_processing/division_operations.c
new file mode 100644
index 00000000..eaa06a1f
--- /dev/null
+++ b/third_party/webrtc/src/webrtc/common_audio/signal_processing/division_operations.c
@@ -0,0 +1,138 @@
+/*
+ * 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 implementations of the divisions
+ * WebRtcSpl_DivU32U16()
+ * WebRtcSpl_DivW32W16()
+ * WebRtcSpl_DivW32W16ResW16()
+ * WebRtcSpl_DivResultInQ31()
+ * WebRtcSpl_DivW32HiLow()
+ *
+ * The description header can be found in signal_processing_library.h
+ *
+ */
+
+#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
+
+uint32_t WebRtcSpl_DivU32U16(uint32_t num, uint16_t den)
+{
+ // Guard against division with 0
+ if (den != 0)
+ {
+ return (uint32_t)(num / den);
+ } else
+ {
+ return (uint32_t)0xFFFFFFFF;
+ }
+}
+
+int32_t WebRtcSpl_DivW32W16(int32_t num, int16_t den)
+{
+ // Guard against division with 0
+ if (den != 0)
+ {
+ return (int32_t)(num / den);
+ } else
+ {
+ return (int32_t)0x7FFFFFFF;
+ }
+}
+
+int16_t WebRtcSpl_DivW32W16ResW16(int32_t num, int16_t den)
+{
+ // Guard against division with 0
+ if (den != 0)
+ {
+ return (int16_t)(num / den);
+ } else
+ {
+ return (int16_t)0x7FFF;
+ }
+}
+
+int32_t WebRtcSpl_DivResultInQ31(int32_t num, int32_t den)
+{
+ int32_t L_num = num;
+ int32_t L_den = den;
+ int32_t div = 0;
+ int k = 31;
+ int change_sign = 0;
+
+ if (num == 0)
+ return 0;
+
+ if (num < 0)
+ {
+ change_sign++;
+ L_num = -num;
+ }
+ if (den < 0)
+ {
+ change_sign++;
+ L_den = -den;
+ }
+ while (k--)
+ {
+ div <<= 1;
+ L_num <<= 1;
+ if (L_num >= L_den)
+ {
+ L_num -= L_den;
+ div++;
+ }
+ }
+ if (change_sign == 1)
+ {
+ div = -div;
+ }
+ return div;
+}
+
+int32_t WebRtcSpl_DivW32HiLow(int32_t num, int16_t den_hi, int16_t den_low)
+{
+ int16_t approx, tmp_hi, tmp_low, num_hi, num_low;
+ int32_t tmpW32;
+
+ approx = (int16_t)WebRtcSpl_DivW32W16((int32_t)0x1FFFFFFF, den_hi);
+ // result in Q14 (Note: 3FFFFFFF = 0.5 in Q30)
+
+ // tmpW32 = 1/den = approx * (2.0 - den * approx) (in Q30)
+ tmpW32 = (den_hi * approx << 1) + ((den_low * approx >> 15) << 1);
+ // tmpW32 = den * approx
+
+ tmpW32 = (int32_t)0x7fffffffL - tmpW32; // result in Q30 (tmpW32 = 2.0-(den*approx))
+
+ // Store tmpW32 in hi and low format
+ tmp_hi = (int16_t)(tmpW32 >> 16);
+ tmp_low = (int16_t)((tmpW32 - ((int32_t)tmp_hi << 16)) >> 1);
+
+ // tmpW32 = 1/den in Q29
+ tmpW32 = (tmp_hi * approx + (tmp_low * approx >> 15)) << 1;
+
+ // 1/den in hi and low format
+ tmp_hi = (int16_t)(tmpW32 >> 16);
+ tmp_low = (int16_t)((tmpW32 - ((int32_t)tmp_hi << 16)) >> 1);
+
+ // Store num in hi and low format
+ num_hi = (int16_t)(num >> 16);
+ num_low = (int16_t)((num - ((int32_t)num_hi << 16)) >> 1);
+
+ // num * (1/den) by 32 bit multiplication (result in Q28)
+
+ tmpW32 = num_hi * tmp_hi + (num_hi * tmp_low >> 15) +
+ (num_low * tmp_hi >> 15);
+
+ // Put result in Q31 (convert from Q28)
+ tmpW32 = WEBRTC_SPL_LSHIFT_W32(tmpW32, 3);
+
+ return tmpW32;
+}