1 /* 2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 12 /* 13 * This file contains implementations of the divisions 14 * WebRtcSpl_DivU32U16() 15 * WebRtcSpl_DivW32W16() 16 * WebRtcSpl_DivW32W16ResW16() 17 * WebRtcSpl_DivResultInQ31() 18 * WebRtcSpl_DivW32HiLow() 19 * 20 * The description header can be found in signal_processing_library.h 21 * 22 */ 23 24 #include "signal_processing_library.h" 25 26 WebRtc_UWord32 WebRtcSpl_DivU32U16(WebRtc_UWord32 num, WebRtc_UWord16 den) 27 { 28 // Guard against division with 0 29 if (den != 0) 30 { 31 return (WebRtc_UWord32)(num / den); 32 } else 33 { 34 return (WebRtc_UWord32)0xFFFFFFFF; 35 } 36 } 37 38 WebRtc_Word32 WebRtcSpl_DivW32W16(WebRtc_Word32 num, WebRtc_Word16 den) 39 { 40 // Guard against division with 0 41 if (den != 0) 42 { 43 return (WebRtc_Word32)(num / den); 44 } else 45 { 46 return (WebRtc_Word32)0x7FFFFFFF; 47 } 48 } 49 50 WebRtc_Word16 WebRtcSpl_DivW32W16ResW16(WebRtc_Word32 num, WebRtc_Word16 den) 51 { 52 // Guard against division with 0 53 if (den != 0) 54 { 55 return (WebRtc_Word16)(num / den); 56 } else 57 { 58 return (WebRtc_Word16)0x7FFF; 59 } 60 } 61 62 WebRtc_Word32 WebRtcSpl_DivResultInQ31(WebRtc_Word32 num, WebRtc_Word32 den) 63 { 64 WebRtc_Word32 L_num = num; 65 WebRtc_Word32 L_den = den; 66 WebRtc_Word32 div = 0; 67 int k = 31; 68 int change_sign = 0; 69 70 if (num == 0) 71 return 0; 72 73 if (num < 0) 74 { 75 change_sign++; 76 L_num = -num; 77 } 78 if (den < 0) 79 { 80 change_sign++; 81 L_den = -den; 82 } 83 while (k--) 84 { 85 div <<= 1; 86 L_num <<= 1; 87 if (L_num >= L_den) 88 { 89 L_num -= L_den; 90 div++; 91 } 92 } 93 if (change_sign == 1) 94 { 95 div = -div; 96 } 97 return div; 98 } 99 100 WebRtc_Word32 WebRtcSpl_DivW32HiLow(WebRtc_Word32 num, WebRtc_Word16 den_hi, 101 WebRtc_Word16 den_low) 102 { 103 WebRtc_Word16 approx, tmp_hi, tmp_low, num_hi, num_low; 104 WebRtc_Word32 tmpW32; 105 106 approx = (WebRtc_Word16)WebRtcSpl_DivW32W16((WebRtc_Word32)0x1FFFFFFF, den_hi); 107 // result in Q14 (Note: 3FFFFFFF = 0.5 in Q30) 108 109 // tmpW32 = 1/den = approx * (2.0 - den * approx) (in Q30) 110 tmpW32 = (WEBRTC_SPL_MUL_16_16(den_hi, approx) << 1) 111 + ((WEBRTC_SPL_MUL_16_16(den_low, approx) >> 15) << 1); 112 // tmpW32 = den * approx 113 114 tmpW32 = (WebRtc_Word32)0x7fffffffL - tmpW32; // result in Q30 (tmpW32 = 2.0-(den*approx)) 115 116 // Store tmpW32 in hi and low format 117 tmp_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32, 16); 118 tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((tmpW32 119 - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1); 120 121 // tmpW32 = 1/den in Q29 122 tmpW32 = ((WEBRTC_SPL_MUL_16_16(tmp_hi, approx) + (WEBRTC_SPL_MUL_16_16(tmp_low, approx) 123 >> 15)) << 1); 124 125 // 1/den in hi and low format 126 tmp_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32, 16); 127 tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((tmpW32 128 - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1); 129 130 // Store num in hi and low format 131 num_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(num, 16); 132 num_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((num 133 - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)num_hi, 16)), 1); 134 135 // num * (1/den) by 32 bit multiplication (result in Q28) 136 137 tmpW32 = (WEBRTC_SPL_MUL_16_16(num_hi, tmp_hi) + (WEBRTC_SPL_MUL_16_16(num_hi, tmp_low) 138 >> 15) + (WEBRTC_SPL_MUL_16_16(num_low, tmp_hi) >> 15)); 139 140 // Put result in Q31 (convert from Q28) 141 tmpW32 = WEBRTC_SPL_LSHIFT_W32(tmpW32, 3); 142 143 return tmpW32; 144 } 145