LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/common_audio/signal_processing - resample_by_2.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 83 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 2 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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 the resampling by two functions.
      14             :  * The description header can be found in signal_processing_library.h
      15             :  *
      16             :  */
      17             : 
      18             : #include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
      19             : 
      20             : #ifdef WEBRTC_ARCH_ARM_V7
      21             : 
      22             : // allpass filter coefficients.
      23             : static const uint32_t kResampleAllpass1[3] = {3284, 24441, 49528 << 15};
      24             : static const uint32_t kResampleAllpass2[3] =
      25             :   {12199, 37471 << 15, 60255 << 15};
      26             : 
      27             : // Multiply two 32-bit values and accumulate to another input value.
      28             : // Return: state + ((diff * tbl_value) >> 16)
      29             : 
      30             : static __inline int32_t MUL_ACCUM_1(int32_t tbl_value,
      31             :                                     int32_t diff,
      32             :                                     int32_t state) {
      33             :   int32_t result;
      34             :   __asm __volatile ("smlawb %0, %1, %2, %3": "=r"(result): "r"(diff),
      35             :                                    "r"(tbl_value), "r"(state));
      36             :   return result;
      37             : }
      38             : 
      39             : // Multiply two 32-bit values and accumulate to another input value.
      40             : // Return: Return: state + (((diff << 1) * tbl_value) >> 32)
      41             : //
      42             : // The reason to introduce this function is that, in case we can't use smlawb
      43             : // instruction (in MUL_ACCUM_1) due to input value range, we can still use 
      44             : // smmla to save some cycles.
      45             : 
      46             : static __inline int32_t MUL_ACCUM_2(int32_t tbl_value,
      47             :                                     int32_t diff,
      48             :                                     int32_t state) {
      49             :   int32_t result;
      50             :   __asm __volatile ("smmla %0, %1, %2, %3": "=r"(result): "r"(diff << 1),
      51             :                                   "r"(tbl_value), "r"(state));
      52             :   return result;
      53             : }
      54             : 
      55             : #else
      56             : 
      57             : // allpass filter coefficients.
      58             : static const uint16_t kResampleAllpass1[3] = {3284, 24441, 49528};
      59             : static const uint16_t kResampleAllpass2[3] = {12199, 37471, 60255};
      60             : 
      61             : // Multiply a 32-bit value with a 16-bit value and accumulate to another input:
      62             : #define MUL_ACCUM_1(a, b, c) WEBRTC_SPL_SCALEDIFF32(a, b, c)
      63             : #define MUL_ACCUM_2(a, b, c) WEBRTC_SPL_SCALEDIFF32(a, b, c)
      64             : 
      65             : #endif  // WEBRTC_ARCH_ARM_V7
      66             : 
      67             : 
      68             : // decimator
      69             : #if !defined(MIPS32_LE)
      70           0 : void WebRtcSpl_DownsampleBy2(const int16_t* in, size_t len,
      71             :                              int16_t* out, int32_t* filtState) {
      72             :   int32_t tmp1, tmp2, diff, in32, out32;
      73             :   size_t i;
      74             : 
      75           0 :   register int32_t state0 = filtState[0];
      76           0 :   register int32_t state1 = filtState[1];
      77           0 :   register int32_t state2 = filtState[2];
      78           0 :   register int32_t state3 = filtState[3];
      79           0 :   register int32_t state4 = filtState[4];
      80           0 :   register int32_t state5 = filtState[5];
      81           0 :   register int32_t state6 = filtState[6];
      82           0 :   register int32_t state7 = filtState[7];
      83             : 
      84           0 :   for (i = (len >> 1); i > 0; i--) {
      85             :     // lower allpass filter
      86           0 :     in32 = (int32_t)(*in++) << 10;
      87           0 :     diff = in32 - state1;
      88           0 :     tmp1 = MUL_ACCUM_1(kResampleAllpass2[0], diff, state0);
      89           0 :     state0 = in32;
      90           0 :     diff = tmp1 - state2;
      91           0 :     tmp2 = MUL_ACCUM_2(kResampleAllpass2[1], diff, state1);
      92           0 :     state1 = tmp1;
      93           0 :     diff = tmp2 - state3;
      94           0 :     state3 = MUL_ACCUM_2(kResampleAllpass2[2], diff, state2);
      95           0 :     state2 = tmp2;
      96             : 
      97             :     // upper allpass filter
      98           0 :     in32 = (int32_t)(*in++) << 10;
      99           0 :     diff = in32 - state5;
     100           0 :     tmp1 = MUL_ACCUM_1(kResampleAllpass1[0], diff, state4);
     101           0 :     state4 = in32;
     102           0 :     diff = tmp1 - state6;
     103           0 :     tmp2 = MUL_ACCUM_1(kResampleAllpass1[1], diff, state5);
     104           0 :     state5 = tmp1;
     105           0 :     diff = tmp2 - state7;
     106           0 :     state7 = MUL_ACCUM_2(kResampleAllpass1[2], diff, state6);
     107           0 :     state6 = tmp2;
     108             : 
     109             :     // add two allpass outputs, divide by two and round
     110           0 :     out32 = (state3 + state7 + 1024) >> 11;
     111             : 
     112             :     // limit amplitude to prevent wrap-around, and write to output array
     113           0 :     *out++ = WebRtcSpl_SatW32ToW16(out32);
     114             :   }
     115             : 
     116           0 :   filtState[0] = state0;
     117           0 :   filtState[1] = state1;
     118           0 :   filtState[2] = state2;
     119           0 :   filtState[3] = state3;
     120           0 :   filtState[4] = state4;
     121           0 :   filtState[5] = state5;
     122           0 :   filtState[6] = state6;
     123           0 :   filtState[7] = state7;
     124           0 : }
     125             : #endif  // #if defined(MIPS32_LE)
     126             : 
     127             : 
     128           0 : void WebRtcSpl_UpsampleBy2(const int16_t* in, size_t len,
     129             :                            int16_t* out, int32_t* filtState) {
     130             :   int32_t tmp1, tmp2, diff, in32, out32;
     131             :   size_t i;
     132             : 
     133           0 :   register int32_t state0 = filtState[0];
     134           0 :   register int32_t state1 = filtState[1];
     135           0 :   register int32_t state2 = filtState[2];
     136           0 :   register int32_t state3 = filtState[3];
     137           0 :   register int32_t state4 = filtState[4];
     138           0 :   register int32_t state5 = filtState[5];
     139           0 :   register int32_t state6 = filtState[6];
     140           0 :   register int32_t state7 = filtState[7];
     141             : 
     142           0 :   for (i = len; i > 0; i--) {
     143             :     // lower allpass filter
     144           0 :     in32 = (int32_t)(*in++) << 10;
     145           0 :     diff = in32 - state1;
     146           0 :     tmp1 = MUL_ACCUM_1(kResampleAllpass1[0], diff, state0);
     147           0 :     state0 = in32;
     148           0 :     diff = tmp1 - state2;
     149           0 :     tmp2 = MUL_ACCUM_1(kResampleAllpass1[1], diff, state1);
     150           0 :     state1 = tmp1;
     151           0 :     diff = tmp2 - state3;
     152           0 :     state3 = MUL_ACCUM_2(kResampleAllpass1[2], diff, state2);
     153           0 :     state2 = tmp2;
     154             : 
     155             :     // round; limit amplitude to prevent wrap-around; write to output array
     156           0 :     out32 = (state3 + 512) >> 10;
     157           0 :     *out++ = WebRtcSpl_SatW32ToW16(out32);
     158             : 
     159             :     // upper allpass filter
     160           0 :     diff = in32 - state5;
     161           0 :     tmp1 = MUL_ACCUM_1(kResampleAllpass2[0], diff, state4);
     162           0 :     state4 = in32;
     163           0 :     diff = tmp1 - state6;
     164           0 :     tmp2 = MUL_ACCUM_2(kResampleAllpass2[1], diff, state5);
     165           0 :     state5 = tmp1;
     166           0 :     diff = tmp2 - state7;
     167           0 :     state7 = MUL_ACCUM_2(kResampleAllpass2[2], diff, state6);
     168           0 :     state6 = tmp2;
     169             : 
     170             :     // round; limit amplitude to prevent wrap-around; write to output array
     171           0 :     out32 = (state7 + 512) >> 10;
     172           0 :     *out++ = WebRtcSpl_SatW32ToW16(out32);
     173             :   }
     174             : 
     175           0 :   filtState[0] = state0;
     176           0 :   filtState[1] = state1;
     177           0 :   filtState[2] = state2;
     178           0 :   filtState[3] = state3;
     179           0 :   filtState[4] = state4;
     180           0 :   filtState[5] = state5;
     181           0 :   filtState[6] = state6;
     182           0 :   filtState[7] = state7;
     183           0 : }

Generated by: LCOV version 1.13