Home | History | Annotate | Download | only in source
      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