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 
     12 #include "webrtc/common_audio/signal_processing/complex_fft_tables.h"
     13 #include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
     14 
     15 #define CFFTSFT 14
     16 #define CFFTRND 1
     17 #define CFFTRND2 16384
     18 
     19 #define CIFFTSFT 14
     20 #define CIFFTRND 1
     21 
     22 int WebRtcSpl_ComplexFFT(int16_t frfi[], int stages, int mode) {
     23   int i = 0;
     24   int l = 0;
     25   int k = 0;
     26   int istep = 0;
     27   int n = 0;
     28   int m = 0;
     29   int32_t wr = 0, wi = 0;
     30   int32_t tmp1 = 0;
     31   int32_t tmp2 = 0;
     32   int32_t tmp3 = 0;
     33   int32_t tmp4 = 0;
     34   int32_t tmp5 = 0;
     35   int32_t tmp6 = 0;
     36   int32_t tmp = 0;
     37   int16_t* ptr_j = NULL;
     38   int16_t* ptr_i = NULL;
     39 
     40   n = 1 << stages;
     41   if (n > 1024) {
     42     return -1;
     43   }
     44 
     45   __asm __volatile (
     46     ".set push                                                         \n\t"
     47     ".set noreorder                                                    \n\t"
     48 
     49     "addiu      %[k],           $zero,            10                   \n\t"
     50     "addiu      %[l],           $zero,            1                    \n\t"
     51    "3:                                                                 \n\t"
     52     "sll        %[istep],       %[l],             1                    \n\t"
     53     "move       %[m],           $zero                                  \n\t"
     54     "sll        %[tmp],         %[l],             2                    \n\t"
     55     "move       %[i],           $zero                                  \n\t"
     56    "2:                                                                 \n\t"
     57 #if defined(MIPS_DSP_R1_LE)
     58     "sllv       %[tmp3],        %[m],             %[k]                 \n\t"
     59     "addiu      %[tmp2],        %[tmp3],          512                  \n\t"
     60     "addiu      %[m],           %[m],             1                    \n\t"
     61     "lhx        %[wi],          %[tmp3](%[kSinTable1024])              \n\t"
     62     "lhx        %[wr],          %[tmp2](%[kSinTable1024])              \n\t"
     63 #else  // #if defined(MIPS_DSP_R1_LE)
     64     "sllv       %[tmp3],        %[m],             %[k]                 \n\t"
     65     "addu       %[ptr_j],       %[tmp3],          %[kSinTable1024]     \n\t"
     66     "addiu      %[ptr_i],       %[ptr_j],         512                  \n\t"
     67     "addiu      %[m],           %[m],             1                    \n\t"
     68     "lh         %[wi],          0(%[ptr_j])                            \n\t"
     69     "lh         %[wr],          0(%[ptr_i])                            \n\t"
     70 #endif  // #if defined(MIPS_DSP_R1_LE)
     71    "1:                                                                 \n\t"
     72     "sll        %[tmp1],        %[i],             2                    \n\t"
     73     "addu       %[ptr_i],       %[frfi],          %[tmp1]              \n\t"
     74     "addu       %[ptr_j],       %[ptr_i],         %[tmp]               \n\t"
     75     "lh         %[tmp6],        0(%[ptr_i])                            \n\t"
     76     "lh         %[tmp5],        2(%[ptr_i])                            \n\t"
     77     "lh         %[tmp3],        0(%[ptr_j])                            \n\t"
     78     "lh         %[tmp4],        2(%[ptr_j])                            \n\t"
     79     "addu       %[i],           %[i],             %[istep]             \n\t"
     80 #if defined(MIPS_DSP_R2_LE)
     81     "mult       %[wr],          %[tmp3]                                \n\t"
     82     "madd       %[wi],          %[tmp4]                                \n\t"
     83     "mult       $ac1,           %[wr],            %[tmp4]              \n\t"
     84     "msub       $ac1,           %[wi],            %[tmp3]              \n\t"
     85     "mflo       %[tmp1]                                                \n\t"
     86     "mflo       %[tmp2],        $ac1                                   \n\t"
     87     "sll        %[tmp6],        %[tmp6],          14                   \n\t"
     88     "sll        %[tmp5],        %[tmp5],          14                   \n\t"
     89     "shra_r.w   %[tmp1],        %[tmp1],          1                    \n\t"
     90     "shra_r.w   %[tmp2],        %[tmp2],          1                    \n\t"
     91     "subu       %[tmp4],        %[tmp6],          %[tmp1]              \n\t"
     92     "addu       %[tmp1],        %[tmp6],          %[tmp1]              \n\t"
     93     "addu       %[tmp6],        %[tmp5],          %[tmp2]              \n\t"
     94     "subu       %[tmp5],        %[tmp5],          %[tmp2]              \n\t"
     95     "shra_r.w   %[tmp1],        %[tmp1],          15                   \n\t"
     96     "shra_r.w   %[tmp6],        %[tmp6],          15                   \n\t"
     97     "shra_r.w   %[tmp4],        %[tmp4],          15                   \n\t"
     98     "shra_r.w   %[tmp5],        %[tmp5],          15                   \n\t"
     99 #else  // #if defined(MIPS_DSP_R2_LE)
    100     "mul        %[tmp2],        %[wr],            %[tmp4]              \n\t"
    101     "mul        %[tmp1],        %[wr],            %[tmp3]              \n\t"
    102     "mul        %[tmp4],        %[wi],            %[tmp4]              \n\t"
    103     "mul        %[tmp3],        %[wi],            %[tmp3]              \n\t"
    104     "sll        %[tmp6],        %[tmp6],          14                   \n\t"
    105     "sll        %[tmp5],        %[tmp5],          14                   \n\t"
    106     "addiu      %[tmp6],        %[tmp6],          16384                \n\t"
    107     "addiu      %[tmp5],        %[tmp5],          16384                \n\t"
    108     "addu       %[tmp1],        %[tmp1],          %[tmp4]              \n\t"
    109     "subu       %[tmp2],        %[tmp2],          %[tmp3]              \n\t"
    110     "addiu      %[tmp1],        %[tmp1],          1                    \n\t"
    111     "addiu      %[tmp2],        %[tmp2],          1                    \n\t"
    112     "sra        %[tmp1],        %[tmp1],          1                    \n\t"
    113     "sra        %[tmp2],        %[tmp2],          1                    \n\t"
    114     "subu       %[tmp4],        %[tmp6],          %[tmp1]              \n\t"
    115     "addu       %[tmp1],        %[tmp6],          %[tmp1]              \n\t"
    116     "addu       %[tmp6],        %[tmp5],          %[tmp2]              \n\t"
    117     "subu       %[tmp5],        %[tmp5],          %[tmp2]              \n\t"
    118     "sra        %[tmp4],        %[tmp4],          15                   \n\t"
    119     "sra        %[tmp1],        %[tmp1],          15                   \n\t"
    120     "sra        %[tmp6],        %[tmp6],          15                   \n\t"
    121     "sra        %[tmp5],        %[tmp5],          15                   \n\t"
    122 #endif  // #if defined(MIPS_DSP_R2_LE)
    123     "sh         %[tmp1],        0(%[ptr_i])                            \n\t"
    124     "sh         %[tmp6],        2(%[ptr_i])                            \n\t"
    125     "sh         %[tmp4],        0(%[ptr_j])                            \n\t"
    126     "blt        %[i],           %[n],             1b                   \n\t"
    127     " sh        %[tmp5],        2(%[ptr_j])                            \n\t"
    128     "blt        %[m],           %[l],             2b                   \n\t"
    129     " addu      %[i],           $zero,            %[m]                 \n\t"
    130     "move       %[l],           %[istep]                               \n\t"
    131     "blt        %[l],           %[n],             3b                   \n\t"
    132     " addiu     %[k],           %[k],             -1                   \n\t"
    133 
    134     ".set pop                                                          \n\t"
    135 
    136     : [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2), [tmp3] "=&r" (tmp3),
    137       [tmp4] "=&r" (tmp4), [tmp5] "=&r" (tmp5), [tmp6] "=&r" (tmp6),
    138       [ptr_i] "=&r" (ptr_i), [i] "=&r" (i), [wi] "=&r" (wi), [wr] "=&r" (wr),
    139       [m] "=&r" (m), [istep] "=&r" (istep), [l] "=&r" (l), [k] "=&r" (k),
    140       [ptr_j] "=&r" (ptr_j), [tmp] "=&r" (tmp)
    141     : [n] "r" (n), [frfi] "r" (frfi), [kSinTable1024] "r" (kSinTable1024)
    142     : "hi", "lo", "memory"
    143 #if defined(MIPS_DSP_R2_LE)
    144     , "$ac1hi", "$ac1lo"
    145 #endif  // #if defined(MIPS_DSP_R2_LE)
    146   );
    147 
    148   return 0;
    149 }
    150 
    151 int WebRtcSpl_ComplexIFFT(int16_t frfi[], int stages, int mode) {
    152   int i = 0, l = 0, k = 0;
    153   int istep = 0, n = 0, m = 0;
    154   int scale = 0, shift = 0;
    155   int32_t wr = 0, wi = 0;
    156   int32_t tmp1 = 0, tmp2 = 0, tmp3 = 0, tmp4 = 0;
    157   int32_t tmp5 = 0, tmp6 = 0, tmp = 0, tempMax = 0, round2 = 0;
    158   int16_t* ptr_j = NULL;
    159   int16_t* ptr_i = NULL;
    160 
    161   n = 1 << stages;
    162   if (n > 1024) {
    163     return -1;
    164   }
    165 
    166   __asm __volatile (
    167     ".set push                                                         \n\t"
    168     ".set noreorder                                                    \n\t"
    169 
    170     "addiu      %[k],           $zero,            10                   \n\t"
    171     "addiu      %[l],           $zero,            1                    \n\t"
    172     "move       %[scale],       $zero                                  \n\t"
    173    "3:                                                                 \n\t"
    174     "addiu      %[shift],       $zero,            14                   \n\t"
    175     "addiu      %[round2],      $zero,            8192                 \n\t"
    176     "move       %[ptr_i],       %[frfi]                                \n\t"
    177     "move       %[tempMax],     $zero                                  \n\t"
    178     "addu       %[i],           %[n],             %[n]                 \n\t"
    179    "5:                                                                 \n\t"
    180     "lh         %[tmp1],        0(%[ptr_i])                            \n\t"
    181     "lh         %[tmp2],        2(%[ptr_i])                            \n\t"
    182     "lh         %[tmp3],        4(%[ptr_i])                            \n\t"
    183     "lh         %[tmp4],        6(%[ptr_i])                            \n\t"
    184 #if defined(MIPS_DSP_R1_LE)
    185     "absq_s.w   %[tmp1],        %[tmp1]                                \n\t"
    186     "absq_s.w   %[tmp2],        %[tmp2]                                \n\t"
    187     "absq_s.w   %[tmp3],        %[tmp3]                                \n\t"
    188     "absq_s.w   %[tmp4],        %[tmp4]                                \n\t"
    189 #else  // #if defined(MIPS_DSP_R1_LE)
    190     "slt        %[tmp5],        %[tmp1],          $zero                \n\t"
    191     "subu       %[tmp6],        $zero,            %[tmp1]              \n\t"
    192     "movn       %[tmp1],        %[tmp6],          %[tmp5]              \n\t"
    193     "slt        %[tmp5],        %[tmp2],          $zero                \n\t"
    194     "subu       %[tmp6],        $zero,            %[tmp2]              \n\t"
    195     "movn       %[tmp2],        %[tmp6],          %[tmp5]              \n\t"
    196     "slt        %[tmp5],        %[tmp3],          $zero                \n\t"
    197     "subu       %[tmp6],        $zero,            %[tmp3]              \n\t"
    198     "movn       %[tmp3],        %[tmp6],          %[tmp5]              \n\t"
    199     "slt        %[tmp5],        %[tmp4],          $zero                \n\t"
    200     "subu       %[tmp6],        $zero,            %[tmp4]              \n\t"
    201     "movn       %[tmp4],        %[tmp6],          %[tmp5]              \n\t"
    202 #endif  // #if defined(MIPS_DSP_R1_LE)
    203     "slt        %[tmp5],        %[tempMax],       %[tmp1]              \n\t"
    204     "movn       %[tempMax],     %[tmp1],          %[tmp5]              \n\t"
    205     "addiu      %[i],           %[i],             -4                   \n\t"
    206     "slt        %[tmp5],        %[tempMax],       %[tmp2]              \n\t"
    207     "movn       %[tempMax],     %[tmp2],          %[tmp5]              \n\t"
    208     "slt        %[tmp5],        %[tempMax],       %[tmp3]              \n\t"
    209     "movn       %[tempMax],     %[tmp3],          %[tmp5]              \n\t"
    210     "slt        %[tmp5],        %[tempMax],       %[tmp4]              \n\t"
    211     "movn       %[tempMax],     %[tmp4],          %[tmp5]              \n\t"
    212     "bgtz       %[i],                             5b                   \n\t"
    213     " addiu     %[ptr_i],       %[ptr_i],         8                    \n\t"
    214     "addiu      %[tmp1],        $zero,            13573                \n\t"
    215     "addiu      %[tmp2],        $zero,            27146                \n\t"
    216 #if !defined(MIPS32_R2_LE)
    217     "sll        %[tempMax],     %[tempMax],       16                   \n\t"
    218     "sra        %[tempMax],     %[tempMax],       16                   \n\t"
    219 #else  // #if !defined(MIPS32_R2_LE)
    220     "seh        %[tempMax]                                             \n\t"
    221 #endif  // #if !defined(MIPS32_R2_LE)
    222     "slt        %[tmp1],        %[tmp1],          %[tempMax]           \n\t"
    223     "slt        %[tmp2],        %[tmp2],          %[tempMax]           \n\t"
    224     "addu       %[tmp1],        %[tmp1],          %[tmp2]              \n\t"
    225     "addu       %[shift],       %[shift],         %[tmp1]              \n\t"
    226     "addu       %[scale],       %[scale],         %[tmp1]              \n\t"
    227     "sllv       %[round2],      %[round2],        %[tmp1]              \n\t"
    228     "sll        %[istep],       %[l],             1                    \n\t"
    229     "move       %[m],           $zero                                  \n\t"
    230     "sll        %[tmp],         %[l],             2                    \n\t"
    231    "2:                                                                 \n\t"
    232 #if defined(MIPS_DSP_R1_LE)
    233     "sllv       %[tmp3],        %[m],             %[k]                 \n\t"
    234     "addiu      %[tmp2],        %[tmp3],          512                  \n\t"
    235     "addiu      %[m],           %[m],             1                    \n\t"
    236     "lhx        %[wi],          %[tmp3](%[kSinTable1024])              \n\t"
    237     "lhx        %[wr],          %[tmp2](%[kSinTable1024])              \n\t"
    238 #else  // #if defined(MIPS_DSP_R1_LE)
    239     "sllv       %[tmp3],        %[m],             %[k]                 \n\t"
    240     "addu       %[ptr_j],       %[tmp3],          %[kSinTable1024]     \n\t"
    241     "addiu      %[ptr_i],       %[ptr_j],         512                  \n\t"
    242     "addiu      %[m],           %[m],             1                    \n\t"
    243     "lh         %[wi],          0(%[ptr_j])                            \n\t"
    244     "lh         %[wr],          0(%[ptr_i])                            \n\t"
    245 #endif  // #if defined(MIPS_DSP_R1_LE)
    246    "1:                                                                 \n\t"
    247     "sll        %[tmp1],        %[i],             2                    \n\t"
    248     "addu       %[ptr_i],       %[frfi],          %[tmp1]              \n\t"
    249     "addu       %[ptr_j],       %[ptr_i],         %[tmp]               \n\t"
    250     "lh         %[tmp3],        0(%[ptr_j])                            \n\t"
    251     "lh         %[tmp4],        2(%[ptr_j])                            \n\t"
    252     "lh         %[tmp6],        0(%[ptr_i])                            \n\t"
    253     "lh         %[tmp5],        2(%[ptr_i])                            \n\t"
    254     "addu       %[i],           %[i],             %[istep]             \n\t"
    255 #if defined(MIPS_DSP_R2_LE)
    256     "mult       %[wr],          %[tmp3]                                \n\t"
    257     "msub       %[wi],          %[tmp4]                                \n\t"
    258     "mult       $ac1,           %[wr],            %[tmp4]              \n\t"
    259     "madd       $ac1,           %[wi],            %[tmp3]              \n\t"
    260     "mflo       %[tmp1]                                                \n\t"
    261     "mflo       %[tmp2],        $ac1                                   \n\t"
    262     "sll        %[tmp6],        %[tmp6],          14                   \n\t"
    263     "sll        %[tmp5],        %[tmp5],          14                   \n\t"
    264     "shra_r.w   %[tmp1],        %[tmp1],          1                    \n\t"
    265     "shra_r.w   %[tmp2],        %[tmp2],          1                    \n\t"
    266     "addu       %[tmp6],        %[tmp6],          %[round2]            \n\t"
    267     "addu       %[tmp5],        %[tmp5],          %[round2]            \n\t"
    268     "subu       %[tmp4],        %[tmp6],          %[tmp1]              \n\t"
    269     "addu       %[tmp1],        %[tmp6],          %[tmp1]              \n\t"
    270     "addu       %[tmp6],        %[tmp5],          %[tmp2]              \n\t"
    271     "subu       %[tmp5],        %[tmp5],          %[tmp2]              \n\t"
    272     "srav       %[tmp4],        %[tmp4],          %[shift]             \n\t"
    273     "srav       %[tmp1],        %[tmp1],          %[shift]             \n\t"
    274     "srav       %[tmp6],        %[tmp6],          %[shift]             \n\t"
    275     "srav       %[tmp5],        %[tmp5],          %[shift]             \n\t"
    276 #else  // #if defined(MIPS_DSP_R2_LE)
    277     "mul        %[tmp1],        %[wr],            %[tmp3]              \n\t"
    278     "mul        %[tmp2],        %[wr],            %[tmp4]              \n\t"
    279     "mul        %[tmp4],        %[wi],            %[tmp4]              \n\t"
    280     "mul        %[tmp3],        %[wi],            %[tmp3]              \n\t"
    281     "sll        %[tmp6],        %[tmp6],          14                   \n\t"
    282     "sll        %[tmp5],        %[tmp5],          14                   \n\t"
    283     "sub        %[tmp1],        %[tmp1],          %[tmp4]              \n\t"
    284     "addu       %[tmp2],        %[tmp2],          %[tmp3]              \n\t"
    285     "addiu      %[tmp1],        %[tmp1],          1                    \n\t"
    286     "addiu      %[tmp2],        %[tmp2],          1                    \n\t"
    287     "sra        %[tmp2],        %[tmp2],          1                    \n\t"
    288     "sra        %[tmp1],        %[tmp1],          1                    \n\t"
    289     "addu       %[tmp6],        %[tmp6],          %[round2]            \n\t"
    290     "addu       %[tmp5],        %[tmp5],          %[round2]            \n\t"
    291     "subu       %[tmp4],        %[tmp6],          %[tmp1]              \n\t"
    292     "addu       %[tmp1],        %[tmp6],          %[tmp1]              \n\t"
    293     "addu       %[tmp6],        %[tmp5],          %[tmp2]              \n\t"
    294     "subu       %[tmp5],        %[tmp5],          %[tmp2]              \n\t"
    295     "sra        %[tmp4],        %[tmp4],          %[shift]             \n\t"
    296     "sra        %[tmp1],        %[tmp1],          %[shift]             \n\t"
    297     "sra        %[tmp6],        %[tmp6],          %[shift]             \n\t"
    298     "sra        %[tmp5],        %[tmp5],          %[shift]             \n\t"
    299 #endif  // #if defined(MIPS_DSP_R2_LE)
    300     "sh         %[tmp1],         0(%[ptr_i])                           \n\t"
    301     "sh         %[tmp6],         2(%[ptr_i])                           \n\t"
    302     "sh         %[tmp4],         0(%[ptr_j])                           \n\t"
    303     "blt        %[i],            %[n],            1b                   \n\t"
    304     " sh        %[tmp5],         2(%[ptr_j])                           \n\t"
    305     "blt        %[m],            %[l],            2b                   \n\t"
    306     " addu      %[i],            $zero,           %[m]                 \n\t"
    307     "move       %[l],            %[istep]                              \n\t"
    308     "blt        %[l],            %[n],            3b                   \n\t"
    309     " addiu     %[k],            %[k],            -1                   \n\t"
    310 
    311     ".set pop                                                          \n\t"
    312 
    313     : [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2), [tmp3] "=&r" (tmp3),
    314       [tmp4] "=&r" (tmp4), [tmp5] "=&r" (tmp5), [tmp6] "=&r" (tmp6),
    315       [ptr_i] "=&r" (ptr_i), [i] "=&r" (i), [m] "=&r" (m), [tmp] "=&r" (tmp),
    316       [istep] "=&r" (istep), [wi] "=&r" (wi), [wr] "=&r" (wr), [l] "=&r" (l),
    317       [k] "=&r" (k), [round2] "=&r" (round2), [ptr_j] "=&r" (ptr_j),
    318       [shift] "=&r" (shift), [scale] "=&r" (scale), [tempMax] "=&r" (tempMax)
    319     : [n] "r" (n), [frfi] "r" (frfi), [kSinTable1024] "r" (kSinTable1024)
    320     : "hi", "lo", "memory"
    321 #if defined(MIPS_DSP_R2_LE)
    322     , "$ac1hi", "$ac1lo"
    323 #endif  // #if defined(MIPS_DSP_R2_LE)
    324   );
    325 
    326   return scale;
    327 
    328 }
    329