tor-browser

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

celt_mipsr1.h (5781B)


      1 /* Copyright (c) 2007-2008 CSIRO
      2   Copyright (c) 2007-2010 Xiph.Org Foundation
      3   Copyright (c) 2008 Gregory Maxwell
      4   Written by Jean-Marc Valin and Gregory Maxwell */
      5 /*
      6   Redistribution and use in source and binary forms, with or without
      7   modification, are permitted provided that the following conditions
      8   are met:
      9 
     10   - Redistributions of source code must retain the above copyright
     11   notice, this list of conditions and the following disclaimer.
     12 
     13   - Redistributions in binary form must reproduce the above copyright
     14   notice, this list of conditions and the following disclaimer in the
     15   documentation and/or other materials provided with the distribution.
     16 
     17   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     18   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     19   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     20   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
     21   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     22   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     23   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     24   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     25   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     26   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     27   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28 */
     29 
     30 #ifndef CELT_MIPSR1_H__
     31 #define CELT_MIPSR1_H__
     32 
     33 #ifdef HAVE_CONFIG_H
     34 #include "config.h"
     35 #endif
     36 
     37 #define CELT_C
     38 
     39 #if defined (__mips_dsp) && __mips == 32
     40 
     41 #define OVERRIDE_COMB_FILTER_CONST
     42 #define OVERRIDE_comb_filter
     43 #elif defined(__mips_isa_rev) && __mips_isa_rev < 6
     44 
     45 #define OVERRIDE_COMB_FILTER_CONST
     46 #define OVERRIDE_comb_filter
     47 #endif
     48 
     49 #include "os_support.h"
     50 #include "mdct.h"
     51 #include <math.h>
     52 #include "celt.h"
     53 #include "pitch.h"
     54 #include "bands.h"
     55 #include "modes.h"
     56 #include "entcode.h"
     57 #include "quant_bands.h"
     58 #include "rate.h"
     59 #include "stack_alloc.h"
     60 #include "mathops.h"
     61 #include "float_cast.h"
     62 #include <stdarg.h>
     63 #include "celt_lpc.h"
     64 #include "vq.h"
     65 
     66 #if defined (__mips_dsp) && __mips == 32
     67 
     68 #define MIPS_MULT __builtin_mips_mult
     69 #define MIPS_MADD __builtin_mips_madd
     70 #define MIPS_EXTR __builtin_mips_extr_w
     71 
     72 #elif defined(__mips_isa_rev) && __mips_isa_rev < 6
     73 
     74 static inline long long MIPS_MULT(int a, int b) {
     75    long long acc;
     76 
     77    asm volatile (
     78            "mult %[a], %[b]  \n"
     79        : [acc] "=x"(acc)
     80        : [a] "r"(a), [b] "r"(b)
     81        :
     82    );
     83    return acc;
     84 }
     85 
     86 static inline long long MIPS_MADD(long long acc, int a, int b) {
     87    asm volatile (
     88            "madd %[a], %[b]  \n"
     89        : [acc] "+x"(acc)
     90        : [a] "r"(a), [b] "r"(b)
     91        :
     92    );
     93    return acc;
     94 }
     95 
     96 static inline opus_val32 MIPS_EXTR(long long acc, int shift) {
     97    return (opus_val32)(acc >> shift);
     98 }
     99 
    100 #endif
    101 
    102 #if defined (OVERRIDE_comb_filter)
    103 void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,
    104      opus_val16 g0, opus_val16 g1, int tapset0, int tapset1,
    105      const opus_val16 *window, int overlap, int arch)
    106 {
    107   int i;
    108   opus_val32 x0, x1, x2, x3, x4;
    109 
    110   (void)arch;
    111 
    112   /* printf ("%d %d %f %f\n", T0, T1, g0, g1); */
    113   opus_val16 g00, g01, g02, g10, g11, g12;
    114   static const opus_val16 gains[3][3] = {
    115         {QCONST16(0.3066406250f, 15), QCONST16(0.2170410156f, 15), QCONST16(0.1296386719f, 15)},
    116         {QCONST16(0.4638671875f, 15), QCONST16(0.2680664062f, 15), QCONST16(0.f, 15)},
    117         {QCONST16(0.7998046875f, 15), QCONST16(0.1000976562f, 15), QCONST16(0.f, 15)}};
    118 
    119   if (g0==0 && g1==0)
    120   {
    121      /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
    122      if (x!=y)
    123         OPUS_MOVE(y, x, N);
    124      return;
    125   }
    126 
    127   g00 = MULT16_16_P15(g0, gains[tapset0][0]);
    128   g01 = MULT16_16_P15(g0, gains[tapset0][1]);
    129   g02 = MULT16_16_P15(g0, gains[tapset0][2]);
    130   g10 = MULT16_16_P15(g1, gains[tapset1][0]);
    131   g11 = MULT16_16_P15(g1, gains[tapset1][1]);
    132   g12 = MULT16_16_P15(g1, gains[tapset1][2]);
    133   x1 = x[-T1+1];
    134   x2 = x[-T1  ];
    135   x3 = x[-T1-1];
    136   x4 = x[-T1-2];
    137   /* If the filter didn't change, we don't need the overlap */
    138   if (g0==g1 && T0==T1 && tapset0==tapset1)
    139      overlap=0;
    140 
    141   for (i=0;i<overlap;i++)
    142   {
    143      opus_val16 f;
    144      opus_val32 res;
    145      long long acc;
    146      f = MULT16_16_Q15(window[i],window[i]);
    147      x0= x[i-T1+2];
    148 
    149      acc = MIPS_MULT((int)MULT16_16_Q15((Q15ONE-f),g00), (int)x[i-T0]);
    150      acc = MIPS_MADD(acc, (int)MULT16_16_Q15((Q15ONE-f),g01), (int)ADD32(x[i-T0-1],x[i-T0+1]));
    151      acc = MIPS_MADD(acc, (int)MULT16_16_Q15((Q15ONE-f),g02), (int)ADD32(x[i-T0-2],x[i-T0+2]));
    152      acc = MIPS_MADD(acc, (int)MULT16_16_Q15(f,g10), (int)x2);
    153      acc = MIPS_MADD(acc, (int)MULT16_16_Q15(f,g11), (int)ADD32(x3,x1));
    154      acc = MIPS_MADD(acc, (int)MULT16_16_Q15(f,g12), (int)ADD32(x4,x0));
    155      res = MIPS_EXTR(acc, 15);
    156 
    157      y[i] = x[i] + res;
    158 
    159      x4=x3;
    160      x3=x2;
    161      x2=x1;
    162      x1=x0;
    163   }
    164 
    165   x4 = x[i-T1-2];
    166   x3 = x[i-T1-1];
    167   x2 = x[i-T1];
    168   x1 = x[i-T1+1];
    169 
    170   if (g1==0)
    171   {
    172      /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
    173      if (x!=y)
    174         OPUS_MOVE(y+overlap, x+overlap, N-overlap);
    175      return;
    176   }
    177 
    178   for (i=overlap;i<N;i++)
    179   {
    180      opus_val32 res;
    181      long long acc;
    182      x0=x[i-T1+2];
    183 
    184      acc = MIPS_MULT((int)g10, (int)x2);
    185      acc = MIPS_MADD(acc, (int)g11, (int)ADD32(x3,x1));
    186      acc = MIPS_MADD(acc, (int)g12, (int)ADD32(x4,x0));
    187      res = MIPS_EXTR(acc, 15);
    188 
    189      y[i] = x[i] + res;
    190      x4=x3;
    191      x3=x2;
    192      x2=x1;
    193      x1=x0;
    194   }
    195 }
    196 #endif /* OVERRIDE_comb_filter */
    197 
    198 #endif /* CELT_MIPSR1_H__ */