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, size_t length,
     26                                  const int16_t *in, int16_t right_shifts)
     27 {
     28     size_t 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                                  size_t vector_length,
     47                                  const int32_t *in_vector,
     48                                  int16_t right_shifts)
     49 {
     50     size_t 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, size_t length,
     68                                       const int32_t* in, int right_shifts) {
     69   size_t 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, size_t in_vector_length,
     88                            int16_t right_shifts)
     89 {
     90     // Performs vector operation: out_vector = (gain*in_vector)>>right_shifts
     91     size_t 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)((*inptr++ * gain) >> right_shifts);
    101     }
    102 }
    103 
    104 void WebRtcSpl_ScaleVectorWithSat(const int16_t *in_vector, int16_t *out_vector,
    105                                  int16_t gain, size_t in_vector_length,
    106                                  int16_t right_shifts)
    107 {
    108     // Performs vector operation: out_vector = (gain*in_vector)>>right_shifts
    109     size_t i;
    110     const int16_t *inptr;
    111     int16_t *outptr;
    112 
    113     inptr = in_vector;
    114     outptr = out_vector;
    115 
    116     for (i = 0; i < in_vector_length; i++) {
    117       *outptr++ = WebRtcSpl_SatW32ToW16((*inptr++ * gain) >> right_shifts);
    118     }
    119 }
    120 
    121 void WebRtcSpl_ScaleAndAddVectors(const int16_t *in1, int16_t gain1, int shift1,
    122                                   const int16_t *in2, int16_t gain2, int shift2,
    123                                   int16_t *out, size_t vector_length)
    124 {
    125     // Performs vector operation: out = (gain1*in1)>>shift1 + (gain2*in2)>>shift2
    126     size_t i;
    127     const int16_t *in1ptr;
    128     const int16_t *in2ptr;
    129     int16_t *outptr;
    130 
    131     in1ptr = in1;
    132     in2ptr = in2;
    133     outptr = out;
    134 
    135     for (i = 0; i < vector_length; i++)
    136     {
    137       *outptr++ = (int16_t)((gain1 * *in1ptr++) >> shift1) +
    138           (int16_t)((gain2 * *in2ptr++) >> shift2);
    139     }
    140 }
    141 
    142 // C version of WebRtcSpl_ScaleAndAddVectorsWithRound() for generic platforms.
    143 int WebRtcSpl_ScaleAndAddVectorsWithRoundC(const int16_t* in_vector1,
    144                                            int16_t in_vector1_scale,
    145                                            const int16_t* in_vector2,
    146                                            int16_t in_vector2_scale,
    147                                            int right_shifts,
    148                                            int16_t* out_vector,
    149                                            size_t length) {
    150   size_t i = 0;
    151   int round_value = (1 << right_shifts) >> 1;
    152 
    153   if (in_vector1 == NULL || in_vector2 == NULL || out_vector == NULL ||
    154       length == 0 || right_shifts < 0) {
    155     return -1;
    156   }
    157 
    158   for (i = 0; i < length; i++) {
    159     out_vector[i] = (int16_t)((
    160         in_vector1[i] * in_vector1_scale + in_vector2[i] * in_vector2_scale +
    161         round_value) >> right_shifts);
    162   }
    163 
    164   return 0;
    165 }
    166