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__ */