Home | History | Annotate | Download | only in signal_processing
      1 /*
      2  *  Copyright (c) 2012 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 functions
     14  * WebRtcSpl_VectorBitShiftW16()
     15  * WebRtcSpl_VectorBitShiftW32()
     16  * WebRtcSpl_VectorBitShiftW32ToW16()
     17  * WebRtcSpl_ScaleVector()
     18  * WebRtcSpl_ScaleVectorWithSat()
     19  * WebRtcSpl_ScaleAndAddVectors()
     20  * WebRtcSpl_ScaleAndAddVectorsWithRoundC()
     21  */
     22 
     23 #include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
     24 
     25 void WebRtcSpl_VectorBitShiftW16(int16_t *res, int16_t length,
     26                                  const int16_t *in, int16_t right_shifts)
     27 {
     28     int i;
     29 
     30     if (right_shifts > 0)
     31     {
     32         for (i = length; i > 0; i--)
     33         {
     34             (*res++) = ((*in++) >> right_shifts);
     35         }
     36     } else
     37     {
     38         for (i = length; i > 0; i--)
     39         {
     40             (*res++) = ((*in++) << (-right_shifts));
     41         }
     42     }
     43 }
     44 
     45 void WebRtcSpl_VectorBitShiftW32(int32_t *out_vector,
     46                                  int16_t vector_length,
     47                                  const int32_t *in_vector,
     48                                  int16_t right_shifts)
     49 {
     50     int i;
     51 
     52     if (right_shifts > 0)
     53     {
     54         for (i = vector_length; i > 0; i--)
     55         {
     56             (*out_vector++) = ((*in_vector++) >> right_shifts);
     57         }
     58     } else
     59     {
     60         for (i = vector_length; i > 0; i--)
     61         {
     62             (*out_vector++) = ((*in_vector++) << (-right_shifts));
     63         }
     64     }
     65 }
     66 
     67 void WebRtcSpl_VectorBitShiftW32ToW16(int16_t* out, int length,
     68                                       const int32_t* in, int right_shifts) {
     69   int i;
     70   int32_t tmp_w32;
     71 
     72   if (right_shifts >= 0) {
     73     for (i = length; i > 0; i--) {
     74       tmp_w32 = (*in++) >> right_shifts;
     75       (*out++) = WebRtcSpl_SatW32ToW16(tmp_w32);
     76     }
     77   } else {
     78     int left_shifts = -right_shifts;
     79     for (i = length; i > 0; i--) {
     80       tmp_w32 = (*in++) << left_shifts;
     81       (*out++) = WebRtcSpl_SatW32ToW16(tmp_w32);
     82     }
     83   }
     84 }
     85 
     86 void WebRtcSpl_ScaleVector(const int16_t *in_vector, int16_t *out_vector,
     87                            int16_t gain, int16_t in_vector_length,
     88                            int16_t right_shifts)
     89 {
     90     // Performs vector operation: out_vector = (gain*in_vector)>>right_shifts
     91     int i;
     92     const int16_t *inptr;
     93     int16_t *outptr;
     94 
     95     inptr = in_vector;
     96     outptr = out_vector;
     97 
     98     for (i = 0; i < in_vector_length; i++)
     99     {
    100         (*outptr++) = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(*inptr++, gain, right_shifts);
    101     }
    102 }
    103 
    104 void WebRtcSpl_ScaleVectorWithSat(const int16_t *in_vector, int16_t *out_vector,
    105                                  int16_t gain, int16_t in_vector_length,
    106                                  int16_t right_shifts)
    107 {
    108     // Performs vector operation: out_vector = (gain*in_vector)>>right_shifts
    109     int i;
    110     int32_t tmpW32;
    111     const int16_t *inptr;
    112     int16_t *outptr;
    113 
    114     inptr = in_vector;
    115     outptr = out_vector;
    116 
    117     for (i = 0; i < in_vector_length; i++)
    118     {
    119         tmpW32 = WEBRTC_SPL_MUL_16_16_RSFT(*inptr++, gain, right_shifts);
    120         (*outptr++) = WebRtcSpl_SatW32ToW16(tmpW32);
    121     }
    122 }
    123 
    124 void WebRtcSpl_ScaleAndAddVectors(const int16_t *in1, int16_t gain1, int shift1,
    125                                   const int16_t *in2, int16_t gain2, int shift2,
    126                                   int16_t *out, int vector_length)
    127 {
    128     // Performs vector operation: out = (gain1*in1)>>shift1 + (gain2*in2)>>shift2
    129     int i;
    130     const int16_t *in1ptr;
    131     const int16_t *in2ptr;
    132     int16_t *outptr;
    133 
    134     in1ptr = in1;
    135     in2ptr = in2;
    136     outptr = out;
    137 
    138     for (i = 0; i < vector_length; i++)
    139     {
    140         (*outptr++) = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(gain1, *in1ptr++, shift1)
    141                 + (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(gain2, *in2ptr++, shift2);
    142     }
    143 }
    144 
    145 // C version of WebRtcSpl_ScaleAndAddVectorsWithRound() for generic platforms.
    146 int WebRtcSpl_ScaleAndAddVectorsWithRoundC(const int16_t* in_vector1,
    147                                            int16_t in_vector1_scale,
    148                                            const int16_t* in_vector2,
    149                                            int16_t in_vector2_scale,
    150                                            int right_shifts,
    151                                            int16_t* out_vector,
    152                                            int length) {
    153   int i = 0;
    154   int round_value = (1 << right_shifts) >> 1;
    155 
    156   if (in_vector1 == NULL || in_vector2 == NULL || out_vector == NULL ||
    157       length <= 0 || right_shifts < 0) {
    158     return -1;
    159   }
    160 
    161   for (i = 0; i < length; i++) {
    162     out_vector[i] = (int16_t)((
    163         WEBRTC_SPL_MUL_16_16(in_vector1[i], in_vector1_scale)
    164         + WEBRTC_SPL_MUL_16_16(in_vector2[i], in_vector2_scale)
    165         + round_value) >> right_shifts);
    166   }
    167 
    168   return 0;
    169 }
    170