Home | History | Annotate | Download | only in signal_processing
      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 #include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
     12 
     13 // Version of WebRtcSpl_DownsampleFast() for MIPS platforms.
     14 int WebRtcSpl_DownsampleFast_mips(const int16_t* data_in,
     15                                   int data_in_length,
     16                                   int16_t* data_out,
     17                                   int data_out_length,
     18                                   const int16_t* __restrict coefficients,
     19                                   int coefficients_length,
     20                                   int factor,
     21                                   int delay) {
     22   int i;
     23   int j;
     24   int k;
     25   int32_t out_s32 = 0;
     26   int endpos = delay + factor * (data_out_length - 1) + 1;
     27 
     28   int32_t  tmp1, tmp2, tmp3, tmp4, factor_2;
     29   int16_t* p_coefficients;
     30   int16_t* p_data_in;
     31   int16_t* p_data_in_0 = (int16_t*)&data_in[delay];
     32   int16_t* p_coefficients_0 = (int16_t*)&coefficients[0];
     33 #if !defined(MIPS_DSP_R1_LE)
     34   int32_t max_16 = 0x7FFF;
     35   int32_t min_16 = 0xFFFF8000;
     36 #endif  // #if !defined(MIPS_DSP_R1_LE)
     37 
     38   // Return error if any of the running conditions doesn't meet.
     39   if (data_out_length <= 0 || coefficients_length <= 0
     40                            || data_in_length < endpos) {
     41     return -1;
     42   }
     43 #if defined(MIPS_DSP_R2_LE)
     44   __asm __volatile (
     45     ".set        push                                                \n\t"
     46     ".set        noreorder                                           \n\t"
     47     "subu        %[i],            %[endpos],       %[delay]          \n\t"
     48     "sll         %[factor_2],     %[factor],       1                 \n\t"
     49    "1:                                                               \n\t"
     50     "move        %[p_data_in],    %[p_data_in_0]                     \n\t"
     51     "mult        $zero,           $zero                              \n\t"
     52     "move        %[p_coefs],      %[p_coefs_0]                       \n\t"
     53     "sra         %[j],            %[coef_length],  2                 \n\t"
     54     "beq         %[j],            $zero,           3f                \n\t"
     55     " andi       %[k],            %[coef_length],  3                 \n\t"
     56    "2:                                                               \n\t"
     57     "lwl         %[tmp1],         1(%[p_data_in])                    \n\t"
     58     "lwl         %[tmp2],         3(%[p_coefs])                      \n\t"
     59     "lwl         %[tmp3],         -3(%[p_data_in])                   \n\t"
     60     "lwl         %[tmp4],         7(%[p_coefs])                      \n\t"
     61     "lwr         %[tmp1],         -2(%[p_data_in])                   \n\t"
     62     "lwr         %[tmp2],         0(%[p_coefs])                      \n\t"
     63     "lwr         %[tmp3],         -6(%[p_data_in])                   \n\t"
     64     "lwr         %[tmp4],         4(%[p_coefs])                      \n\t"
     65     "packrl.ph   %[tmp1],         %[tmp1],         %[tmp1]           \n\t"
     66     "packrl.ph   %[tmp3],         %[tmp3],         %[tmp3]           \n\t"
     67     "dpa.w.ph    $ac0,            %[tmp1],         %[tmp2]           \n\t"
     68     "dpa.w.ph    $ac0,            %[tmp3],         %[tmp4]           \n\t"
     69     "addiu       %[j],            %[j],            -1                \n\t"
     70     "addiu       %[p_data_in],    %[p_data_in],    -8                \n\t"
     71     "bgtz        %[j],            2b                                 \n\t"
     72     " addiu      %[p_coefs],      %[p_coefs],      8                 \n\t"
     73    "3:                                                               \n\t"
     74     "beq         %[k],            $zero,           5f                \n\t"
     75     " nop                                                            \n\t"
     76    "4:                                                               \n\t"
     77     "lhu         %[tmp1],         0(%[p_data_in])                    \n\t"
     78     "lhu         %[tmp2],         0(%[p_coefs])                      \n\t"
     79     "addiu       %[p_data_in],    %[p_data_in],    -2                \n\t"
     80     "addiu       %[k],            %[k],            -1                \n\t"
     81     "dpa.w.ph    $ac0,            %[tmp1],         %[tmp2]           \n\t"
     82     "bgtz        %[k],            4b                                 \n\t"
     83     " addiu      %[p_coefs],      %[p_coefs],      2                 \n\t"
     84    "5:                                                               \n\t"
     85     "extr_r.w    %[out_s32],      $ac0,            12                \n\t"
     86     "addu        %[p_data_in_0],  %[p_data_in_0],  %[factor_2]       \n\t"
     87     "subu        %[i],            %[i],            %[factor]         \n\t"
     88     "shll_s.w    %[out_s32],      %[out_s32],      16                \n\t"
     89     "sra         %[out_s32],      %[out_s32],      16                \n\t"
     90     "sh          %[out_s32],      0(%[data_out])                     \n\t"
     91     "bgtz        %[i],            1b                                 \n\t"
     92     " addiu      %[data_out],     %[data_out],     2                 \n\t"
     93     ".set        pop                                                 \n\t"
     94     : [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2), [tmp3] "=&r" (tmp3),
     95       [tmp4] "=&r" (tmp4), [p_data_in] "=&r" (p_data_in),
     96       [p_data_in_0] "+r" (p_data_in_0), [p_coefs] "=&r" (p_coefficients),
     97       [j] "=&r" (j), [out_s32] "=&r" (out_s32), [factor_2] "=&r" (factor_2),
     98       [i] "=&r" (i), [k] "=&r" (k)
     99     : [coef_length] "r" (coefficients_length), [data_out] "r" (data_out),
    100       [p_coefs_0] "r" (p_coefficients_0), [endpos] "r" (endpos),
    101       [delay] "r" (delay), [factor] "r" (factor)
    102     : "memory", "hi", "lo"
    103  );
    104 #else  // #if defined(MIPS_DSP_R2_LE)
    105   __asm __volatile (
    106     ".set        push                                                \n\t"
    107     ".set        noreorder                                           \n\t"
    108     "sll         %[factor_2],     %[factor],       1                 \n\t"
    109     "subu        %[i],            %[endpos],       %[delay]          \n\t"
    110    "1:                                                               \n\t"
    111     "move        %[p_data_in],    %[p_data_in_0]                     \n\t"
    112     "addiu       %[out_s32],      $zero,           2048              \n\t"
    113     "move        %[p_coefs],      %[p_coefs_0]                       \n\t"
    114     "sra         %[j],            %[coef_length],  1                 \n\t"
    115     "beq         %[j],            $zero,           3f                \n\t"
    116     " andi       %[k],            %[coef_length],  1                 \n\t"
    117    "2:                                                               \n\t"
    118     "lh          %[tmp1],         0(%[p_data_in])                    \n\t"
    119     "lh          %[tmp2],         0(%[p_coefs])                      \n\t"
    120     "lh          %[tmp3],         -2(%[p_data_in])                   \n\t"
    121     "lh          %[tmp4],         2(%[p_coefs])                      \n\t"
    122     "mul         %[tmp1],         %[tmp1],         %[tmp2]           \n\t"
    123     "addiu       %[p_coefs],      %[p_coefs],      4                 \n\t"
    124     "mul         %[tmp3],         %[tmp3],         %[tmp4]           \n\t"
    125     "addiu       %[j],            %[j],            -1                \n\t"
    126     "addiu       %[p_data_in],    %[p_data_in],    -4                \n\t"
    127     "addu        %[tmp1],         %[tmp1],         %[tmp3]           \n\t"
    128     "bgtz        %[j],            2b                                 \n\t"
    129     " addu       %[out_s32],      %[out_s32],      %[tmp1]           \n\t"
    130    "3:                                                               \n\t"
    131     "beq         %[k],            $zero,           4f                \n\t"
    132     " nop                                                            \n\t"
    133     "lh          %[tmp1],         0(%[p_data_in])                    \n\t"
    134     "lh          %[tmp2],         0(%[p_coefs])                      \n\t"
    135     "mul         %[tmp1],         %[tmp1],         %[tmp2]           \n\t"
    136     "addu        %[out_s32],      %[out_s32],      %[tmp1]           \n\t"
    137    "4:                                                               \n\t"
    138     "sra         %[out_s32],      %[out_s32],      12                \n\t"
    139     "addu        %[p_data_in_0],  %[p_data_in_0],  %[factor_2]       \n\t"
    140 #if defined(MIPS_DSP_R1_LE)
    141     "shll_s.w    %[out_s32],      %[out_s32],      16                \n\t"
    142     "sra         %[out_s32],      %[out_s32],      16                \n\t"
    143 #else  // #if defined(MIPS_DSP_R1_LE)
    144     "slt         %[tmp1],         %[max_16],       %[out_s32]        \n\t"
    145     "movn        %[out_s32],      %[max_16],       %[tmp1]           \n\t"
    146     "slt         %[tmp1],         %[out_s32],      %[min_16]         \n\t"
    147     "movn        %[out_s32],      %[min_16],       %[tmp1]           \n\t"
    148 #endif  // #if defined(MIPS_DSP_R1_LE)
    149     "subu        %[i],            %[i],            %[factor]         \n\t"
    150     "sh          %[out_s32],      0(%[data_out])                     \n\t"
    151     "bgtz        %[i],            1b                                 \n\t"
    152     " addiu      %[data_out],     %[data_out],     2                 \n\t"
    153     ".set        pop                                                 \n\t"
    154     : [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2), [tmp3] "=&r" (tmp3),
    155       [tmp4] "=&r" (tmp4), [p_data_in] "=&r" (p_data_in), [k] "=&r" (k),
    156       [p_data_in_0] "+r" (p_data_in_0), [p_coefs] "=&r" (p_coefficients),
    157       [j] "=&r" (j), [out_s32] "=&r" (out_s32), [factor_2] "=&r" (factor_2),
    158       [i] "=&r" (i)
    159     : [coef_length] "r" (coefficients_length), [data_out] "r" (data_out),
    160       [p_coefs_0] "r" (p_coefficients_0), [endpos] "r" (endpos),
    161 #if !defined(MIPS_DSP_R1_LE)
    162       [max_16] "r" (max_16), [min_16] "r" (min_16),
    163 #endif  // #if !defined(MIPS_DSP_R1_LE)
    164       [delay] "r" (delay), [factor] "r" (factor)
    165     : "memory", "hi", "lo"
    166   );
    167 #endif  // #if defined(MIPS_DSP_R2_LE)
    168   return 0;
    169 }
    170