tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

resample_by_2_mips.c (10705B)


      1 /*
      2 *  Copyright (c) 2013 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 * This file contains the resampling by two functions.
     13 * The description header can be found in signal_processing_library.h
     14 *
     15 */
     16 
     17 #if defined(MIPS32_LE)
     18 
     19 #include "common_audio/signal_processing/include/signal_processing_library.h"
     20 
     21 #if !defined(MIPS_DSP_R2_LE)
     22 // allpass filter coefficients.
     23 static const uint16_t kResampleAllpass1[3] = {3284, 24441, 49528};
     24 static const uint16_t kResampleAllpass2[3] = {12199, 37471, 60255};
     25 #endif
     26 
     27 // Multiply a 32-bit value with a 16-bit value and accumulate to another input:
     28 #define MUL_ACCUM_1(a, b, c) WEBRTC_SPL_SCALEDIFF32(a, b, c)
     29 #define MUL_ACCUM_2(a, b, c) WEBRTC_SPL_SCALEDIFF32(a, b, c)
     30 
     31 // decimator
     32 void WebRtcSpl_DownsampleBy2(const int16_t* in,
     33                             size_t len,
     34                             int16_t* out,
     35                             int32_t* filtState) {
     36  int32_t out32;
     37  size_t i, len1;
     38 
     39  register int32_t state0 = filtState[0];
     40  register int32_t state1 = filtState[1];
     41  register int32_t state2 = filtState[2];
     42  register int32_t state3 = filtState[3];
     43  register int32_t state4 = filtState[4];
     44  register int32_t state5 = filtState[5];
     45  register int32_t state6 = filtState[6];
     46  register int32_t state7 = filtState[7];
     47 
     48 #if defined(MIPS_DSP_R2_LE)
     49  int32_t k1Res0, k1Res1, k1Res2, k2Res0, k2Res1, k2Res2;
     50 
     51  k1Res0 = 3284;
     52  k1Res1 = 24441;
     53  k1Res2 = 49528;
     54  k2Res0 = 12199;
     55  k2Res1 = 37471;
     56  k2Res2 = 60255;
     57  len1 = (len >> 1);
     58 
     59  const int32_t* inw = (int32_t*)in;
     60  int32_t tmp11, tmp12, tmp21, tmp22;
     61  int32_t in322, in321;
     62  int32_t diff1, diff2;
     63  for (i = len1; i > 0; i--) {
     64    __asm__ volatile(
     65        "lh         %[in321],    0(%[inw])                  \n\t"
     66        "lh         %[in322],    2(%[inw])                  \n\t"
     67 
     68        "sll        %[in321],    %[in321],      10          \n\t"
     69        "sll        %[in322],    %[in322],      10          \n\t"
     70 
     71        "addiu      %[inw],      %[inw],        4           \n\t"
     72 
     73        "subu       %[diff1],    %[in321],      %[state1]   \n\t"
     74        "subu       %[diff2],    %[in322],      %[state5]   \n\t"
     75 
     76        : [in322] "=&r"(in322), [in321] "=&r"(in321), [diff1] "=&r"(diff1),
     77          [diff2] "=r"(diff2), [inw] "+r"(inw)
     78        : [state1] "r"(state1), [state5] "r"(state5)
     79        : "memory");
     80 
     81    __asm__ volatile(
     82        "mult       $ac0,       %[diff1],       %[k2Res0]   \n\t"
     83        "mult       $ac1,       %[diff2],       %[k1Res0]   \n\t"
     84 
     85        "extr.w     %[tmp11],   $ac0,           16          \n\t"
     86        "extr.w     %[tmp12],   $ac1,           16          \n\t"
     87 
     88        "addu       %[tmp11],   %[state0],      %[tmp11]    \n\t"
     89        "addu       %[tmp12],   %[state4],      %[tmp12]    \n\t"
     90 
     91        "addiu      %[state0],  %[in321],       0           \n\t"
     92        "addiu      %[state4],  %[in322],       0           \n\t"
     93 
     94        "subu       %[diff1],   %[tmp11],       %[state2]   \n\t"
     95        "subu       %[diff2],   %[tmp12],       %[state6]   \n\t"
     96 
     97        "mult       $ac0,       %[diff1],       %[k2Res1]   \n\t"
     98        "mult       $ac1,       %[diff2],       %[k1Res1]   \n\t"
     99 
    100        "extr.w     %[tmp21],   $ac0,           16          \n\t"
    101        "extr.w     %[tmp22],   $ac1,           16          \n\t"
    102 
    103        "addu       %[tmp21],   %[state1],      %[tmp21]    \n\t"
    104        "addu       %[tmp22],   %[state5],      %[tmp22]    \n\t"
    105 
    106        "addiu      %[state1],  %[tmp11],       0           \n\t"
    107        "addiu      %[state5],  %[tmp12],       0           \n\t"
    108        : [tmp22] "=r"(tmp22), [tmp21] "=&r"(tmp21), [tmp11] "=&r"(tmp11),
    109          [state0] "+r"(state0), [state1] "+r"(state1), [state2] "+r"(state2),
    110          [state4] "+r"(state4), [tmp12] "=&r"(tmp12), [state6] "+r"(state6),
    111          [state5] "+r"(state5)
    112        : [k1Res1] "r"(k1Res1), [k2Res1] "r"(k2Res1), [k2Res0] "r"(k2Res0),
    113          [diff2] "r"(diff2), [diff1] "r"(diff1), [in322] "r"(in322),
    114          [in321] "r"(in321), [k1Res0] "r"(k1Res0)
    115        : "hi", "lo", "$ac1hi", "$ac1lo");
    116 
    117    // upper allpass filter
    118    __asm__ volatile(
    119        "subu       %[diff1],   %[tmp21],       %[state3]   \n\t"
    120        "subu       %[diff2],   %[tmp22],       %[state7]   \n\t"
    121 
    122        "mult       $ac0,       %[diff1],       %[k2Res2]   \n\t"
    123        "mult       $ac1,       %[diff2],       %[k1Res2]   \n\t"
    124        "extr.w     %[state3],  $ac0,           16          \n\t"
    125        "extr.w     %[state7],  $ac1,           16          \n\t"
    126        "addu       %[state3],  %[state2],      %[state3]   \n\t"
    127        "addu       %[state7],  %[state6],      %[state7]   \n\t"
    128 
    129        "addiu      %[state2],  %[tmp21],       0           \n\t"
    130        "addiu      %[state6],  %[tmp22],       0           \n\t"
    131 
    132        // add two allpass outputs, divide by two and round
    133        "addu       %[out32],   %[state3],      %[state7]   \n\t"
    134        "addiu      %[out32],   %[out32],       1024        \n\t"
    135        "sra        %[out32],   %[out32],       11          \n\t"
    136        : [state3] "+r"(state3), [state6] "+r"(state6), [state2] "+r"(state2),
    137          [diff2] "=&r"(diff2), [out32] "=r"(out32), [diff1] "=&r"(diff1),
    138          [state7] "+r"(state7)
    139        : [tmp22] "r"(tmp22), [tmp21] "r"(tmp21), [k1Res2] "r"(k1Res2),
    140          [k2Res2] "r"(k2Res2)
    141        : "hi", "lo", "$ac1hi", "$ac1lo");
    142 
    143    // limit amplitude to prevent wrap-around, and write to output array
    144    *out++ = WebRtcSpl_SatW32ToW16(out32);
    145  }
    146 #else   // #if defined(MIPS_DSP_R2_LE)
    147  int32_t tmp1, tmp2, diff;
    148  int32_t in32;
    149  len1 = (len >> 1) / 4;
    150  for (i = len1; i > 0; i--) {
    151    // lower allpass filter
    152    in32 = (int32_t)(*in++) << 10;
    153    diff = in32 - state1;
    154    tmp1 = MUL_ACCUM_1(kResampleAllpass2[0], diff, state0);
    155    state0 = in32;
    156    diff = tmp1 - state2;
    157    tmp2 = MUL_ACCUM_2(kResampleAllpass2[1], diff, state1);
    158    state1 = tmp1;
    159    diff = tmp2 - state3;
    160    state3 = MUL_ACCUM_2(kResampleAllpass2[2], diff, state2);
    161    state2 = tmp2;
    162 
    163    // upper allpass filter
    164    in32 = (int32_t)(*in++) << 10;
    165    diff = in32 - state5;
    166    tmp1 = MUL_ACCUM_1(kResampleAllpass1[0], diff, state4);
    167    state4 = in32;
    168    diff = tmp1 - state6;
    169    tmp2 = MUL_ACCUM_1(kResampleAllpass1[1], diff, state5);
    170    state5 = tmp1;
    171    diff = tmp2 - state7;
    172    state7 = MUL_ACCUM_2(kResampleAllpass1[2], diff, state6);
    173    state6 = tmp2;
    174 
    175    // add two allpass outputs, divide by two and round
    176    out32 = (state3 + state7 + 1024) >> 11;
    177 
    178    // limit amplitude to prevent wrap-around, and write to output array
    179    *out++ = WebRtcSpl_SatW32ToW16(out32);
    180    // lower allpass filter
    181    in32 = (int32_t)(*in++) << 10;
    182    diff = in32 - state1;
    183    tmp1 = MUL_ACCUM_1(kResampleAllpass2[0], diff, state0);
    184    state0 = in32;
    185    diff = tmp1 - state2;
    186    tmp2 = MUL_ACCUM_2(kResampleAllpass2[1], diff, state1);
    187    state1 = tmp1;
    188    diff = tmp2 - state3;
    189    state3 = MUL_ACCUM_2(kResampleAllpass2[2], diff, state2);
    190    state2 = tmp2;
    191 
    192    // upper allpass filter
    193    in32 = (int32_t)(*in++) << 10;
    194    diff = in32 - state5;
    195    tmp1 = MUL_ACCUM_1(kResampleAllpass1[0], diff, state4);
    196    state4 = in32;
    197    diff = tmp1 - state6;
    198    tmp2 = MUL_ACCUM_1(kResampleAllpass1[1], diff, state5);
    199    state5 = tmp1;
    200    diff = tmp2 - state7;
    201    state7 = MUL_ACCUM_2(kResampleAllpass1[2], diff, state6);
    202    state6 = tmp2;
    203 
    204    // add two allpass outputs, divide by two and round
    205    out32 = (state3 + state7 + 1024) >> 11;
    206 
    207    // limit amplitude to prevent wrap-around, and write to output array
    208    *out++ = WebRtcSpl_SatW32ToW16(out32);
    209    // lower allpass filter
    210    in32 = (int32_t)(*in++) << 10;
    211    diff = in32 - state1;
    212    tmp1 = MUL_ACCUM_1(kResampleAllpass2[0], diff, state0);
    213    state0 = in32;
    214    diff = tmp1 - state2;
    215    tmp2 = MUL_ACCUM_2(kResampleAllpass2[1], diff, state1);
    216    state1 = tmp1;
    217    diff = tmp2 - state3;
    218    state3 = MUL_ACCUM_2(kResampleAllpass2[2], diff, state2);
    219    state2 = tmp2;
    220 
    221    // upper allpass filter
    222    in32 = (int32_t)(*in++) << 10;
    223    diff = in32 - state5;
    224    tmp1 = MUL_ACCUM_1(kResampleAllpass1[0], diff, state4);
    225    state4 = in32;
    226    diff = tmp1 - state6;
    227    tmp2 = MUL_ACCUM_1(kResampleAllpass1[1], diff, state5);
    228    state5 = tmp1;
    229    diff = tmp2 - state7;
    230    state7 = MUL_ACCUM_2(kResampleAllpass1[2], diff, state6);
    231    state6 = tmp2;
    232 
    233    // add two allpass outputs, divide by two and round
    234    out32 = (state3 + state7 + 1024) >> 11;
    235 
    236    // limit amplitude to prevent wrap-around, and write to output array
    237    *out++ = WebRtcSpl_SatW32ToW16(out32);
    238    // lower allpass filter
    239    in32 = (int32_t)(*in++) << 10;
    240    diff = in32 - state1;
    241    tmp1 = MUL_ACCUM_1(kResampleAllpass2[0], diff, state0);
    242    state0 = in32;
    243    diff = tmp1 - state2;
    244    tmp2 = MUL_ACCUM_2(kResampleAllpass2[1], diff, state1);
    245    state1 = tmp1;
    246    diff = tmp2 - state3;
    247    state3 = MUL_ACCUM_2(kResampleAllpass2[2], diff, state2);
    248    state2 = tmp2;
    249 
    250    // upper allpass filter
    251    in32 = (int32_t)(*in++) << 10;
    252    diff = in32 - state5;
    253    tmp1 = MUL_ACCUM_1(kResampleAllpass1[0], diff, state4);
    254    state4 = in32;
    255    diff = tmp1 - state6;
    256    tmp2 = MUL_ACCUM_1(kResampleAllpass1[1], diff, state5);
    257    state5 = tmp1;
    258    diff = tmp2 - state7;
    259    state7 = MUL_ACCUM_2(kResampleAllpass1[2], diff, state6);
    260    state6 = tmp2;
    261 
    262    // add two allpass outputs, divide by two and round
    263    out32 = (state3 + state7 + 1024) >> 11;
    264 
    265    // limit amplitude to prevent wrap-around, and write to output array
    266    *out++ = WebRtcSpl_SatW32ToW16(out32);
    267  }
    268 #endif  // #if defined(MIPS_DSP_R2_LE)
    269  __asm__ volatile(
    270      "sw       %[state0],      0(%[filtState])     \n\t"
    271      "sw       %[state1],      4(%[filtState])     \n\t"
    272      "sw       %[state2],      8(%[filtState])     \n\t"
    273      "sw       %[state3],      12(%[filtState])    \n\t"
    274      "sw       %[state4],      16(%[filtState])    \n\t"
    275      "sw       %[state5],      20(%[filtState])    \n\t"
    276      "sw       %[state6],      24(%[filtState])    \n\t"
    277      "sw       %[state7],      28(%[filtState])    \n\t"
    278      :
    279      : [state0] "r"(state0), [state1] "r"(state1), [state2] "r"(state2),
    280        [state3] "r"(state3), [state4] "r"(state4), [state5] "r"(state5),
    281        [state6] "r"(state6), [state7] "r"(state7), [filtState] "r"(filtState)
    282      : "memory");
    283 }
    284 
    285 #endif  // #if defined(MIPS32_LE)