File: division_operations.c

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (123 lines) | stat: -rw-r--r-- 3,157 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*
 *  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 "common_audio/signal_processing/include/signal_processing_library.h"
#include "rtc_base/sanitizer.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

  // result in Q30 (tmpW32 = 2.0-(den*approx))
  tmpW32 = (int32_t)((int64_t)0x7fffffffL - tmpW32);

  // 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;
}