diff options
Diffstat (limited to 'lib/rbcodec/codecs/libopus/celt/mips')
-rw-r--r-- | lib/rbcodec/codecs/libopus/celt/mips/celt_mipsr1.h | 151 | ||||
-rw-r--r-- | lib/rbcodec/codecs/libopus/celt/mips/fixed_generic_mipsr1.h | 126 | ||||
-rw-r--r-- | lib/rbcodec/codecs/libopus/celt/mips/kiss_fft_mipsr1.h | 167 | ||||
-rw-r--r-- | lib/rbcodec/codecs/libopus/celt/mips/mdct_mipsr1.h | 288 | ||||
-rw-r--r-- | lib/rbcodec/codecs/libopus/celt/mips/pitch_mipsr1.h | 161 | ||||
-rw-r--r-- | lib/rbcodec/codecs/libopus/celt/mips/vq_mipsr1.h | 122 |
6 files changed, 1015 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libopus/celt/mips/celt_mipsr1.h b/lib/rbcodec/codecs/libopus/celt/mips/celt_mipsr1.h new file mode 100644 index 0000000000..e85661a661 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/celt/mips/celt_mipsr1.h | |||
@@ -0,0 +1,151 @@ | |||
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 | #include "os_support.h" | ||
40 | #include "mdct.h" | ||
41 | #include <math.h> | ||
42 | #include "celt.h" | ||
43 | #include "pitch.h" | ||
44 | #include "bands.h" | ||
45 | #include "modes.h" | ||
46 | #include "entcode.h" | ||
47 | #include "quant_bands.h" | ||
48 | #include "rate.h" | ||
49 | #include "stack_alloc.h" | ||
50 | #include "mathops.h" | ||
51 | #include "float_cast.h" | ||
52 | #include <stdarg.h> | ||
53 | #include "celt_lpc.h" | ||
54 | #include "vq.h" | ||
55 | |||
56 | #define OVERRIDE_comb_filter | ||
57 | void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N, | ||
58 | opus_val16 g0, opus_val16 g1, int tapset0, int tapset1, | ||
59 | const opus_val16 *window, int overlap, int arch) | ||
60 | { | ||
61 | int i; | ||
62 | opus_val32 x0, x1, x2, x3, x4; | ||
63 | |||
64 | (void)arch; | ||
65 | |||
66 | /* printf ("%d %d %f %f\n", T0, T1, g0, g1); */ | ||
67 | opus_val16 g00, g01, g02, g10, g11, g12; | ||
68 | static const opus_val16 gains[3][3] = { | ||
69 | {QCONST16(0.3066406250f, 15), QCONST16(0.2170410156f, 15), QCONST16(0.1296386719f, 15)}, | ||
70 | {QCONST16(0.4638671875f, 15), QCONST16(0.2680664062f, 15), QCONST16(0.f, 15)}, | ||
71 | {QCONST16(0.7998046875f, 15), QCONST16(0.1000976562f, 15), QCONST16(0.f, 15)}}; | ||
72 | |||
73 | if (g0==0 && g1==0) | ||
74 | { | ||
75 | /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */ | ||
76 | if (x!=y) | ||
77 | OPUS_MOVE(y, x, N); | ||
78 | return; | ||
79 | } | ||
80 | |||
81 | g00 = MULT16_16_P15(g0, gains[tapset0][0]); | ||
82 | g01 = MULT16_16_P15(g0, gains[tapset0][1]); | ||
83 | g02 = MULT16_16_P15(g0, gains[tapset0][2]); | ||
84 | g10 = MULT16_16_P15(g1, gains[tapset1][0]); | ||
85 | g11 = MULT16_16_P15(g1, gains[tapset1][1]); | ||
86 | g12 = MULT16_16_P15(g1, gains[tapset1][2]); | ||
87 | x1 = x[-T1+1]; | ||
88 | x2 = x[-T1 ]; | ||
89 | x3 = x[-T1-1]; | ||
90 | x4 = x[-T1-2]; | ||
91 | /* If the filter didn't change, we don't need the overlap */ | ||
92 | if (g0==g1 && T0==T1 && tapset0==tapset1) | ||
93 | overlap=0; | ||
94 | |||
95 | for (i=0;i<overlap;i++) | ||
96 | { | ||
97 | opus_val16 f; | ||
98 | opus_val32 res; | ||
99 | f = MULT16_16_Q15(window[i],window[i]); | ||
100 | x0= x[i-T1+2]; | ||
101 | |||
102 | asm volatile("MULT $ac1, %0, %1" : : "r" ((int)MULT16_16_Q15((Q15ONE-f),g00)), "r" ((int)x[i-T0])); | ||
103 | |||
104 | asm volatile("MADD $ac1, %0, %1" : : "r" ((int)MULT16_16_Q15((Q15ONE-f),g01)), "r" ((int)ADD32(x[i-T0-1],x[i-T0+1]))); | ||
105 | asm volatile("MADD $ac1, %0, %1" : : "r" ((int)MULT16_16_Q15((Q15ONE-f),g02)), "r" ((int)ADD32(x[i-T0-2],x[i-T0+2]))); | ||
106 | asm volatile("MADD $ac1, %0, %1" : : "r" ((int)MULT16_16_Q15(f,g10)), "r" ((int)x2)); | ||
107 | asm volatile("MADD $ac1, %0, %1" : : "r" ((int)MULT16_16_Q15(f,g11)), "r" ((int)ADD32(x3,x1))); | ||
108 | asm volatile("MADD $ac1, %0, %1" : : "r" ((int)MULT16_16_Q15(f,g12)), "r" ((int)ADD32(x4,x0))); | ||
109 | |||
110 | asm volatile("EXTR.W %0,$ac1, %1" : "=r" (res): "i" (15)); | ||
111 | |||
112 | y[i] = x[i] + res; | ||
113 | |||
114 | x4=x3; | ||
115 | x3=x2; | ||
116 | x2=x1; | ||
117 | x1=x0; | ||
118 | } | ||
119 | |||
120 | x4 = x[i-T1-2]; | ||
121 | x3 = x[i-T1-1]; | ||
122 | x2 = x[i-T1]; | ||
123 | x1 = x[i-T1+1]; | ||
124 | |||
125 | if (g1==0) | ||
126 | { | ||
127 | /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */ | ||
128 | if (x!=y) | ||
129 | OPUS_MOVE(y+overlap, x+overlap, N-overlap); | ||
130 | return; | ||
131 | } | ||
132 | |||
133 | for (i=overlap;i<N;i++) | ||
134 | { | ||
135 | opus_val32 res; | ||
136 | x0=x[i-T1+2]; | ||
137 | |||
138 | asm volatile("MULT $ac1, %0, %1" : : "r" ((int)g10), "r" ((int)x2)); | ||
139 | |||
140 | asm volatile("MADD $ac1, %0, %1" : : "r" ((int)g11), "r" ((int)ADD32(x3,x1))); | ||
141 | asm volatile("MADD $ac1, %0, %1" : : "r" ((int)g12), "r" ((int)ADD32(x4,x0))); | ||
142 | asm volatile("EXTR.W %0,$ac1, %1" : "=r" (res): "i" (15)); | ||
143 | y[i] = x[i] + res; | ||
144 | x4=x3; | ||
145 | x3=x2; | ||
146 | x2=x1; | ||
147 | x1=x0; | ||
148 | } | ||
149 | } | ||
150 | |||
151 | #endif /* __CELT_MIPSR1_H__ */ | ||
diff --git a/lib/rbcodec/codecs/libopus/celt/mips/fixed_generic_mipsr1.h b/lib/rbcodec/codecs/libopus/celt/mips/fixed_generic_mipsr1.h new file mode 100644 index 0000000000..4a05efbf85 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/celt/mips/fixed_generic_mipsr1.h | |||
@@ -0,0 +1,126 @@ | |||
1 | /* Copyright (C) 2007-2009 Xiph.Org Foundation | ||
2 | Copyright (C) 2003-2008 Jean-Marc Valin | ||
3 | Copyright (C) 2007-2008 CSIRO */ | ||
4 | /** | ||
5 | @file fixed_generic.h | ||
6 | @brief Generic fixed-point operations | ||
7 | */ | ||
8 | /* | ||
9 | Redistribution and use in source and binary forms, with or without | ||
10 | modification, are permitted provided that the following conditions | ||
11 | are met: | ||
12 | |||
13 | - Redistributions of source code must retain the above copyright | ||
14 | notice, this list of conditions and the following disclaimer. | ||
15 | |||
16 | - Redistributions in binary form must reproduce the above copyright | ||
17 | notice, this list of conditions and the following disclaimer in the | ||
18 | documentation and/or other materials provided with the distribution. | ||
19 | |||
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
21 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER | ||
24 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
25 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
26 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
27 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
28 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
29 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
30 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
31 | */ | ||
32 | |||
33 | #ifndef CELT_FIXED_GENERIC_MIPSR1_H | ||
34 | #define CELT_FIXED_GENERIC_MIPSR1_H | ||
35 | |||
36 | #undef MULT16_32_Q15_ADD | ||
37 | static inline int MULT16_32_Q15_ADD(int a, int b, int c, int d) { | ||
38 | int m; | ||
39 | asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a), "r" ((int)b)); | ||
40 | asm volatile("madd $ac1, %0, %1" : : "r" ((int)c), "r" ((int)d)); | ||
41 | asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m): "i" (15)); | ||
42 | return m; | ||
43 | } | ||
44 | |||
45 | #undef MULT16_32_Q15_SUB | ||
46 | static inline int MULT16_32_Q15_SUB(int a, int b, int c, int d) { | ||
47 | int m; | ||
48 | asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a), "r" ((int)b)); | ||
49 | asm volatile("msub $ac1, %0, %1" : : "r" ((int)c), "r" ((int)d)); | ||
50 | asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m): "i" (15)); | ||
51 | return m; | ||
52 | } | ||
53 | |||
54 | #undef MULT16_16_Q15_ADD | ||
55 | static inline int MULT16_16_Q15_ADD(int a, int b, int c, int d) { | ||
56 | int m; | ||
57 | asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a), "r" ((int)b)); | ||
58 | asm volatile("madd $ac1, %0, %1" : : "r" ((int)c), "r" ((int)d)); | ||
59 | asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m): "i" (15)); | ||
60 | return m; | ||
61 | } | ||
62 | |||
63 | #undef MULT16_16_Q15_SUB | ||
64 | static inline int MULT16_16_Q15_SUB(int a, int b, int c, int d) { | ||
65 | int m; | ||
66 | asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a), "r" ((int)b)); | ||
67 | asm volatile("msub $ac1, %0, %1" : : "r" ((int)c), "r" ((int)d)); | ||
68 | asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m): "i" (15)); | ||
69 | return m; | ||
70 | } | ||
71 | |||
72 | |||
73 | #undef MULT16_32_Q16 | ||
74 | static inline int MULT16_32_Q16(int a, int b) | ||
75 | { | ||
76 | int c; | ||
77 | asm volatile("MULT $ac1,%0, %1" : : "r" (a), "r" (b)); | ||
78 | asm volatile("EXTR.W %0,$ac1, %1" : "=r" (c): "i" (16)); | ||
79 | return c; | ||
80 | } | ||
81 | |||
82 | #undef MULT16_32_P16 | ||
83 | static inline int MULT16_32_P16(int a, int b) | ||
84 | { | ||
85 | int c; | ||
86 | asm volatile("MULT $ac1, %0, %1" : : "r" (a), "r" (b)); | ||
87 | asm volatile("EXTR_R.W %0,$ac1, %1" : "=r" (c): "i" (16)); | ||
88 | return c; | ||
89 | } | ||
90 | |||
91 | #undef MULT16_32_Q15 | ||
92 | static inline int MULT16_32_Q15(int a, int b) | ||
93 | { | ||
94 | int c; | ||
95 | asm volatile("MULT $ac1, %0, %1" : : "r" (a), "r" (b)); | ||
96 | asm volatile("EXTR.W %0,$ac1, %1" : "=r" (c): "i" (15)); | ||
97 | return c; | ||
98 | } | ||
99 | |||
100 | #undef MULT32_32_Q31 | ||
101 | static inline int MULT32_32_Q31(int a, int b) | ||
102 | { | ||
103 | int r; | ||
104 | asm volatile("MULT $ac1, %0, %1" : : "r" (a), "r" (b)); | ||
105 | asm volatile("EXTR.W %0,$ac1, %1" : "=r" (r): "i" (31)); | ||
106 | return r; | ||
107 | } | ||
108 | |||
109 | #undef PSHR32 | ||
110 | static inline int PSHR32(int a, int shift) | ||
111 | { | ||
112 | int r; | ||
113 | asm volatile ("SHRAV_R.W %0, %1, %2" :"=r" (r): "r" (a), "r" (shift)); | ||
114 | return r; | ||
115 | } | ||
116 | |||
117 | #undef MULT16_16_P15 | ||
118 | static inline int MULT16_16_P15(int a, int b) | ||
119 | { | ||
120 | int r; | ||
121 | asm volatile ("mul %0, %1, %2" :"=r" (r): "r" (a), "r" (b)); | ||
122 | asm volatile ("SHRA_R.W %0, %1, %2" : "+r" (r): "0" (r), "i"(15)); | ||
123 | return r; | ||
124 | } | ||
125 | |||
126 | #endif /* CELT_FIXED_GENERIC_MIPSR1_H */ | ||
diff --git a/lib/rbcodec/codecs/libopus/celt/mips/kiss_fft_mipsr1.h b/lib/rbcodec/codecs/libopus/celt/mips/kiss_fft_mipsr1.h new file mode 100644 index 0000000000..400ca4de9c --- /dev/null +++ b/lib/rbcodec/codecs/libopus/celt/mips/kiss_fft_mipsr1.h | |||
@@ -0,0 +1,167 @@ | |||
1 | /*Copyright (c) 2013, Xiph.Org Foundation and contributors. | ||
2 | |||
3 | All rights reserved. | ||
4 | |||
5 | Redistribution and use in source and binary forms, with or without | ||
6 | modification, are permitted provided that the following conditions are met: | ||
7 | |||
8 | * Redistributions of source code must retain the above copyright notice, | ||
9 | this list of conditions and the following disclaimer. | ||
10 | * Redistributions in binary form must reproduce the above copyright notice, | ||
11 | this list of conditions and the following disclaimer in the | ||
12 | documentation and/or other materials provided with the distribution. | ||
13 | |||
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
24 | POSSIBILITY OF SUCH DAMAGE.*/ | ||
25 | |||
26 | #ifndef KISS_FFT_MIPSR1_H | ||
27 | #define KISS_FFT_MIPSR1_H | ||
28 | |||
29 | #if !defined(KISS_FFT_GUTS_H) | ||
30 | #error "This file should only be included from _kiss_fft_guts.h" | ||
31 | #endif | ||
32 | |||
33 | #ifdef FIXED_POINT | ||
34 | |||
35 | #define S_MUL_ADD(a, b, c, d) (S_MUL(a,b)+S_MUL(c,d)) | ||
36 | #define S_MUL_SUB(a, b, c, d) (S_MUL(a,b)-S_MUL(c,d)) | ||
37 | |||
38 | #undef S_MUL_ADD | ||
39 | static inline int S_MUL_ADD(int a, int b, int c, int d) { | ||
40 | int m; | ||
41 | asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a), "r" ((int)b)); | ||
42 | asm volatile("madd $ac1, %0, %1" : : "r" ((int)c), "r" ((int)d)); | ||
43 | asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m): "i" (15)); | ||
44 | return m; | ||
45 | } | ||
46 | |||
47 | #undef S_MUL_SUB | ||
48 | static inline int S_MUL_SUB(int a, int b, int c, int d) { | ||
49 | int m; | ||
50 | asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a), "r" ((int)b)); | ||
51 | asm volatile("msub $ac1, %0, %1" : : "r" ((int)c), "r" ((int)d)); | ||
52 | asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m): "i" (15)); | ||
53 | return m; | ||
54 | } | ||
55 | |||
56 | #undef C_MUL | ||
57 | # define C_MUL(m,a,b) (m=C_MUL_fun(a,b)) | ||
58 | static inline kiss_fft_cpx C_MUL_fun(kiss_fft_cpx a, kiss_twiddle_cpx b) { | ||
59 | kiss_fft_cpx m; | ||
60 | |||
61 | asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a.r), "r" ((int)b.r)); | ||
62 | asm volatile("msub $ac1, %0, %1" : : "r" ((int)a.i), "r" ((int)b.i)); | ||
63 | asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m.r): "i" (15)); | ||
64 | asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a.r), "r" ((int)b.i)); | ||
65 | asm volatile("madd $ac1, %0, %1" : : "r" ((int)a.i), "r" ((int)b.r)); | ||
66 | asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m.i): "i" (15)); | ||
67 | |||
68 | return m; | ||
69 | } | ||
70 | #undef C_MULC | ||
71 | # define C_MULC(m,a,b) (m=C_MULC_fun(a,b)) | ||
72 | static inline kiss_fft_cpx C_MULC_fun(kiss_fft_cpx a, kiss_twiddle_cpx b) { | ||
73 | kiss_fft_cpx m; | ||
74 | |||
75 | asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a.r), "r" ((int)b.r)); | ||
76 | asm volatile("madd $ac1, %0, %1" : : "r" ((int)a.i), "r" ((int)b.i)); | ||
77 | asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m.r): "i" (15)); | ||
78 | asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a.i), "r" ((int)b.r)); | ||
79 | asm volatile("msub $ac1, %0, %1" : : "r" ((int)a.r), "r" ((int)b.i)); | ||
80 | asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m.i): "i" (15)); | ||
81 | |||
82 | return m; | ||
83 | } | ||
84 | |||
85 | #endif /* FIXED_POINT */ | ||
86 | |||
87 | #define OVERRIDE_kf_bfly5 | ||
88 | static void kf_bfly5( | ||
89 | kiss_fft_cpx * Fout, | ||
90 | const size_t fstride, | ||
91 | const kiss_fft_state *st, | ||
92 | int m, | ||
93 | int N, | ||
94 | int mm | ||
95 | ) | ||
96 | { | ||
97 | kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4; | ||
98 | int i, u; | ||
99 | kiss_fft_cpx scratch[13]; | ||
100 | |||
101 | const kiss_twiddle_cpx *tw; | ||
102 | kiss_twiddle_cpx ya,yb; | ||
103 | kiss_fft_cpx * Fout_beg = Fout; | ||
104 | |||
105 | #ifdef FIXED_POINT | ||
106 | ya.r = 10126; | ||
107 | ya.i = -31164; | ||
108 | yb.r = -26510; | ||
109 | yb.i = -19261; | ||
110 | #else | ||
111 | ya = st->twiddles[fstride*m]; | ||
112 | yb = st->twiddles[fstride*2*m]; | ||
113 | #endif | ||
114 | |||
115 | tw=st->twiddles; | ||
116 | |||
117 | for (i=0;i<N;i++) | ||
118 | { | ||
119 | Fout = Fout_beg + i*mm; | ||
120 | Fout0=Fout; | ||
121 | Fout1=Fout0+m; | ||
122 | Fout2=Fout0+2*m; | ||
123 | Fout3=Fout0+3*m; | ||
124 | Fout4=Fout0+4*m; | ||
125 | |||
126 | /* For non-custom modes, m is guaranteed to be a multiple of 4. */ | ||
127 | for ( u=0; u<m; ++u ) { | ||
128 | scratch[0] = *Fout0; | ||
129 | |||
130 | |||
131 | C_MUL(scratch[1] ,*Fout1, tw[u*fstride]); | ||
132 | C_MUL(scratch[2] ,*Fout2, tw[2*u*fstride]); | ||
133 | C_MUL(scratch[3] ,*Fout3, tw[3*u*fstride]); | ||
134 | C_MUL(scratch[4] ,*Fout4, tw[4*u*fstride]); | ||
135 | |||
136 | C_ADD( scratch[7],scratch[1],scratch[4]); | ||
137 | C_SUB( scratch[10],scratch[1],scratch[4]); | ||
138 | C_ADD( scratch[8],scratch[2],scratch[3]); | ||
139 | C_SUB( scratch[9],scratch[2],scratch[3]); | ||
140 | |||
141 | Fout0->r += scratch[7].r + scratch[8].r; | ||
142 | Fout0->i += scratch[7].i + scratch[8].i; | ||
143 | scratch[5].r = scratch[0].r + S_MUL_ADD(scratch[7].r,ya.r,scratch[8].r,yb.r); | ||
144 | scratch[5].i = scratch[0].i + S_MUL_ADD(scratch[7].i,ya.r,scratch[8].i,yb.r); | ||
145 | |||
146 | scratch[6].r = S_MUL_ADD(scratch[10].i,ya.i,scratch[9].i,yb.i); | ||
147 | scratch[6].i = -S_MUL_ADD(scratch[10].r,ya.i,scratch[9].r,yb.i); | ||
148 | |||
149 | C_SUB(*Fout1,scratch[5],scratch[6]); | ||
150 | C_ADD(*Fout4,scratch[5],scratch[6]); | ||
151 | |||
152 | scratch[11].r = scratch[0].r + S_MUL_ADD(scratch[7].r,yb.r,scratch[8].r,ya.r); | ||
153 | scratch[11].i = scratch[0].i + S_MUL_ADD(scratch[7].i,yb.r,scratch[8].i,ya.r); | ||
154 | |||
155 | scratch[12].r = S_MUL_SUB(scratch[9].i,ya.i,scratch[10].i,yb.i); | ||
156 | scratch[12].i = S_MUL_SUB(scratch[10].r,yb.i,scratch[9].r,ya.i); | ||
157 | |||
158 | C_ADD(*Fout2,scratch[11],scratch[12]); | ||
159 | C_SUB(*Fout3,scratch[11],scratch[12]); | ||
160 | |||
161 | ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4; | ||
162 | } | ||
163 | } | ||
164 | } | ||
165 | |||
166 | |||
167 | #endif /* KISS_FFT_MIPSR1_H */ | ||
diff --git a/lib/rbcodec/codecs/libopus/celt/mips/mdct_mipsr1.h b/lib/rbcodec/codecs/libopus/celt/mips/mdct_mipsr1.h new file mode 100644 index 0000000000..2934dab776 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/celt/mips/mdct_mipsr1.h | |||
@@ -0,0 +1,288 @@ | |||
1 | /* Copyright (c) 2007-2008 CSIRO | ||
2 | Copyright (c) 2007-2008 Xiph.Org Foundation | ||
3 | Written by Jean-Marc Valin */ | ||
4 | /* | ||
5 | Redistribution and use in source and binary forms, with or without | ||
6 | modification, are permitted provided that the following conditions | ||
7 | are met: | ||
8 | |||
9 | - Redistributions of source code must retain the above copyright | ||
10 | notice, this list of conditions and the following disclaimer. | ||
11 | |||
12 | - Redistributions in binary form must reproduce the above copyright | ||
13 | notice, this list of conditions and the following disclaimer in the | ||
14 | documentation and/or other materials provided with the distribution. | ||
15 | |||
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
17 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
18 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
19 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER | ||
20 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
21 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
22 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
23 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
24 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
25 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
26 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
27 | */ | ||
28 | |||
29 | /* This is a simple MDCT implementation that uses a N/4 complex FFT | ||
30 | to do most of the work. It should be relatively straightforward to | ||
31 | plug in pretty much and FFT here. | ||
32 | |||
33 | This replaces the Vorbis FFT (and uses the exact same API), which | ||
34 | was a bit too messy and that was ending up duplicating code | ||
35 | (might as well use the same FFT everywhere). | ||
36 | |||
37 | The algorithm is similar to (and inspired from) Fabrice Bellard's | ||
38 | MDCT implementation in FFMPEG, but has differences in signs, ordering | ||
39 | and scaling in many places. | ||
40 | */ | ||
41 | #ifndef __MDCT_MIPSR1_H__ | ||
42 | #define __MDCT_MIPSR1_H__ | ||
43 | |||
44 | #ifndef SKIP_CONFIG_H | ||
45 | #ifdef HAVE_CONFIG_H | ||
46 | #include "config.h" | ||
47 | #endif | ||
48 | #endif | ||
49 | |||
50 | #include "mdct.h" | ||
51 | #include "kiss_fft.h" | ||
52 | #include "_kiss_fft_guts.h" | ||
53 | #include <math.h> | ||
54 | #include "os_support.h" | ||
55 | #include "mathops.h" | ||
56 | #include "stack_alloc.h" | ||
57 | |||
58 | /* Forward MDCT trashes the input array */ | ||
59 | #define OVERRIDE_clt_mdct_forward | ||
60 | void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out, | ||
61 | const opus_val16 *window, int overlap, int shift, int stride, int arch) | ||
62 | { | ||
63 | int i; | ||
64 | int N, N2, N4; | ||
65 | VARDECL(kiss_fft_scalar, f); | ||
66 | VARDECL(kiss_fft_cpx, f2); | ||
67 | const kiss_fft_state *st = l->kfft[shift]; | ||
68 | const kiss_twiddle_scalar *trig; | ||
69 | opus_val16 scale; | ||
70 | #ifdef FIXED_POINT | ||
71 | /* Allows us to scale with MULT16_32_Q16(), which is faster than | ||
72 | MULT16_32_Q15() on ARM. */ | ||
73 | int scale_shift = st->scale_shift-1; | ||
74 | #endif | ||
75 | |||
76 | (void)arch; | ||
77 | |||
78 | SAVE_STACK; | ||
79 | scale = st->scale; | ||
80 | |||
81 | N = l->n; | ||
82 | trig = l->trig; | ||
83 | for (i=0;i<shift;i++) | ||
84 | { | ||
85 | N >>= 1; | ||
86 | trig += N; | ||
87 | } | ||
88 | N2 = N>>1; | ||
89 | N4 = N>>2; | ||
90 | |||
91 | ALLOC(f, N2, kiss_fft_scalar); | ||
92 | ALLOC(f2, N4, kiss_fft_cpx); | ||
93 | |||
94 | /* Consider the input to be composed of four blocks: [a, b, c, d] */ | ||
95 | /* Window, shuffle, fold */ | ||
96 | { | ||
97 | /* Temp pointers to make it really clear to the compiler what we're doing */ | ||
98 | const kiss_fft_scalar * OPUS_RESTRICT xp1 = in+(overlap>>1); | ||
99 | const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+N2-1+(overlap>>1); | ||
100 | kiss_fft_scalar * OPUS_RESTRICT yp = f; | ||
101 | const opus_val16 * OPUS_RESTRICT wp1 = window+(overlap>>1); | ||
102 | const opus_val16 * OPUS_RESTRICT wp2 = window+(overlap>>1)-1; | ||
103 | for(i=0;i<((overlap+3)>>2);i++) | ||
104 | { | ||
105 | /* Real part arranged as -d-cR, Imag part arranged as -b+aR*/ | ||
106 | *yp++ = S_MUL_ADD(*wp2, xp1[N2],*wp1,*xp2); | ||
107 | *yp++ = S_MUL_SUB(*wp1, *xp1,*wp2, xp2[-N2]); | ||
108 | xp1+=2; | ||
109 | xp2-=2; | ||
110 | wp1+=2; | ||
111 | wp2-=2; | ||
112 | } | ||
113 | wp1 = window; | ||
114 | wp2 = window+overlap-1; | ||
115 | for(;i<N4-((overlap+3)>>2);i++) | ||
116 | { | ||
117 | /* Real part arranged as a-bR, Imag part arranged as -c-dR */ | ||
118 | *yp++ = *xp2; | ||
119 | *yp++ = *xp1; | ||
120 | xp1+=2; | ||
121 | xp2-=2; | ||
122 | } | ||
123 | for(;i<N4;i++) | ||
124 | { | ||
125 | /* Real part arranged as a-bR, Imag part arranged as -c-dR */ | ||
126 | *yp++ = S_MUL_SUB(*wp2, *xp2, *wp1, xp1[-N2]); | ||
127 | *yp++ = S_MUL_ADD(*wp2, *xp1, *wp1, xp2[N2]); | ||
128 | xp1+=2; | ||
129 | xp2-=2; | ||
130 | wp1+=2; | ||
131 | wp2-=2; | ||
132 | } | ||
133 | } | ||
134 | /* Pre-rotation */ | ||
135 | { | ||
136 | kiss_fft_scalar * OPUS_RESTRICT yp = f; | ||
137 | const kiss_twiddle_scalar *t = &trig[0]; | ||
138 | for(i=0;i<N4;i++) | ||
139 | { | ||
140 | kiss_fft_cpx yc; | ||
141 | kiss_twiddle_scalar t0, t1; | ||
142 | kiss_fft_scalar re, im, yr, yi; | ||
143 | t0 = t[i]; | ||
144 | t1 = t[N4+i]; | ||
145 | re = *yp++; | ||
146 | im = *yp++; | ||
147 | |||
148 | yr = S_MUL_SUB(re,t0,im,t1); | ||
149 | yi = S_MUL_ADD(im,t0,re,t1); | ||
150 | |||
151 | yc.r = yr; | ||
152 | yc.i = yi; | ||
153 | yc.r = PSHR32(MULT16_32_Q16(scale, yc.r), scale_shift); | ||
154 | yc.i = PSHR32(MULT16_32_Q16(scale, yc.i), scale_shift); | ||
155 | f2[st->bitrev[i]] = yc; | ||
156 | } | ||
157 | } | ||
158 | |||
159 | /* N/4 complex FFT, does not downscale anymore */ | ||
160 | opus_fft_impl(st, f2); | ||
161 | |||
162 | /* Post-rotate */ | ||
163 | { | ||
164 | /* Temp pointers to make it really clear to the compiler what we're doing */ | ||
165 | const kiss_fft_cpx * OPUS_RESTRICT fp = f2; | ||
166 | kiss_fft_scalar * OPUS_RESTRICT yp1 = out; | ||
167 | kiss_fft_scalar * OPUS_RESTRICT yp2 = out+stride*(N2-1); | ||
168 | const kiss_twiddle_scalar *t = &trig[0]; | ||
169 | /* Temp pointers to make it really clear to the compiler what we're doing */ | ||
170 | for(i=0;i<N4;i++) | ||
171 | { | ||
172 | kiss_fft_scalar yr, yi; | ||
173 | yr = S_MUL_SUB(fp->i,t[N4+i] , fp->r,t[i]); | ||
174 | yi = S_MUL_ADD(fp->r,t[N4+i] ,fp->i,t[i]); | ||
175 | *yp1 = yr; | ||
176 | *yp2 = yi; | ||
177 | fp++; | ||
178 | yp1 += 2*stride; | ||
179 | yp2 -= 2*stride; | ||
180 | } | ||
181 | } | ||
182 | RESTORE_STACK; | ||
183 | } | ||
184 | |||
185 | #define OVERRIDE_clt_mdct_backward | ||
186 | void clt_mdct_backward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out, | ||
187 | const opus_val16 * OPUS_RESTRICT window, int overlap, int shift, int stride, int arch) | ||
188 | { | ||
189 | int i; | ||
190 | int N, N2, N4; | ||
191 | const kiss_twiddle_scalar *trig; | ||
192 | |||
193 | (void)arch; | ||
194 | |||
195 | N = l->n; | ||
196 | trig = l->trig; | ||
197 | for (i=0;i<shift;i++) | ||
198 | { | ||
199 | N >>= 1; | ||
200 | trig += N; | ||
201 | } | ||
202 | N2 = N>>1; | ||
203 | N4 = N>>2; | ||
204 | |||
205 | /* Pre-rotate */ | ||
206 | { | ||
207 | /* Temp pointers to make it really clear to the compiler what we're doing */ | ||
208 | const kiss_fft_scalar * OPUS_RESTRICT xp1 = in; | ||
209 | const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+stride*(N2-1); | ||
210 | kiss_fft_scalar * OPUS_RESTRICT yp = out+(overlap>>1); | ||
211 | const kiss_twiddle_scalar * OPUS_RESTRICT t = &trig[0]; | ||
212 | const opus_int16 * OPUS_RESTRICT bitrev = l->kfft[shift]->bitrev; | ||
213 | for(i=0;i<N4;i++) | ||
214 | { | ||
215 | int rev; | ||
216 | kiss_fft_scalar yr, yi; | ||
217 | rev = *bitrev++; | ||
218 | yr = S_MUL_ADD(*xp2, t[i] , *xp1, t[N4+i]); | ||
219 | yi = S_MUL_SUB(*xp1, t[i] , *xp2, t[N4+i]); | ||
220 | /* We swap real and imag because we use an FFT instead of an IFFT. */ | ||
221 | yp[2*rev+1] = yr; | ||
222 | yp[2*rev] = yi; | ||
223 | /* Storing the pre-rotation directly in the bitrev order. */ | ||
224 | xp1+=2*stride; | ||
225 | xp2-=2*stride; | ||
226 | } | ||
227 | } | ||
228 | |||
229 | opus_fft_impl(l->kfft[shift], (kiss_fft_cpx*)(out+(overlap>>1))); | ||
230 | |||
231 | /* Post-rotate and de-shuffle from both ends of the buffer at once to make | ||
232 | it in-place. */ | ||
233 | { | ||
234 | kiss_fft_scalar * OPUS_RESTRICT yp0 = out+(overlap>>1); | ||
235 | kiss_fft_scalar * OPUS_RESTRICT yp1 = out+(overlap>>1)+N2-2; | ||
236 | const kiss_twiddle_scalar *t = &trig[0]; | ||
237 | /* Loop to (N4+1)>>1 to handle odd N4. When N4 is odd, the | ||
238 | middle pair will be computed twice. */ | ||
239 | for(i=0;i<(N4+1)>>1;i++) | ||
240 | { | ||
241 | kiss_fft_scalar re, im, yr, yi; | ||
242 | kiss_twiddle_scalar t0, t1; | ||
243 | /* We swap real and imag because we're using an FFT instead of an IFFT. */ | ||
244 | re = yp0[1]; | ||
245 | im = yp0[0]; | ||
246 | t0 = t[i]; | ||
247 | t1 = t[N4+i]; | ||
248 | /* We'd scale up by 2 here, but instead it's done when mixing the windows */ | ||
249 | yr = S_MUL_ADD(re,t0 , im,t1); | ||
250 | yi = S_MUL_SUB(re,t1 , im,t0); | ||
251 | /* We swap real and imag because we're using an FFT instead of an IFFT. */ | ||
252 | re = yp1[1]; | ||
253 | im = yp1[0]; | ||
254 | yp0[0] = yr; | ||
255 | yp1[1] = yi; | ||
256 | |||
257 | t0 = t[(N4-i-1)]; | ||
258 | t1 = t[(N2-i-1)]; | ||
259 | /* We'd scale up by 2 here, but instead it's done when mixing the windows */ | ||
260 | yr = S_MUL_ADD(re,t0,im,t1); | ||
261 | yi = S_MUL_SUB(re,t1,im,t0); | ||
262 | yp1[0] = yr; | ||
263 | yp0[1] = yi; | ||
264 | yp0 += 2; | ||
265 | yp1 -= 2; | ||
266 | } | ||
267 | } | ||
268 | |||
269 | /* Mirror on both sides for TDAC */ | ||
270 | { | ||
271 | kiss_fft_scalar * OPUS_RESTRICT xp1 = out+overlap-1; | ||
272 | kiss_fft_scalar * OPUS_RESTRICT yp1 = out; | ||
273 | const opus_val16 * OPUS_RESTRICT wp1 = window; | ||
274 | const opus_val16 * OPUS_RESTRICT wp2 = window+overlap-1; | ||
275 | |||
276 | for(i = 0; i < overlap/2; i++) | ||
277 | { | ||
278 | kiss_fft_scalar x1, x2; | ||
279 | x1 = *xp1; | ||
280 | x2 = *yp1; | ||
281 | *yp1++ = MULT16_32_Q15(*wp2, x2) - MULT16_32_Q15(*wp1, x1); | ||
282 | *xp1-- = MULT16_32_Q15(*wp1, x2) + MULT16_32_Q15(*wp2, x1); | ||
283 | wp1++; | ||
284 | wp2--; | ||
285 | } | ||
286 | } | ||
287 | } | ||
288 | #endif /* __MDCT_MIPSR1_H__ */ | ||
diff --git a/lib/rbcodec/codecs/libopus/celt/mips/pitch_mipsr1.h b/lib/rbcodec/codecs/libopus/celt/mips/pitch_mipsr1.h new file mode 100644 index 0000000000..a9500aff58 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/celt/mips/pitch_mipsr1.h | |||
@@ -0,0 +1,161 @@ | |||
1 | /* Copyright (c) 2007-2008 CSIRO | ||
2 | Copyright (c) 2007-2009 Xiph.Org Foundation | ||
3 | Written by Jean-Marc Valin */ | ||
4 | /** | ||
5 | @file pitch.h | ||
6 | @brief Pitch analysis | ||
7 | */ | ||
8 | |||
9 | /* | ||
10 | Redistribution and use in source and binary forms, with or without | ||
11 | modification, are permitted provided that the following conditions | ||
12 | are met: | ||
13 | |||
14 | - Redistributions of source code must retain the above copyright | ||
15 | notice, this list of conditions and the following disclaimer. | ||
16 | |||
17 | - Redistributions in binary form must reproduce the above copyright | ||
18 | notice, this list of conditions and the following disclaimer in the | ||
19 | documentation and/or other materials provided with the distribution. | ||
20 | |||
21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
22 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
23 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
24 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER | ||
25 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
26 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
27 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
28 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
29 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
30 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
31 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
32 | */ | ||
33 | |||
34 | #ifndef PITCH_MIPSR1_H | ||
35 | #define PITCH_MIPSR1_H | ||
36 | |||
37 | #define OVERRIDE_DUAL_INNER_PROD | ||
38 | static inline void dual_inner_prod(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02, | ||
39 | int N, opus_val32 *xy1, opus_val32 *xy2, int arch) | ||
40 | { | ||
41 | int j; | ||
42 | opus_val32 xy01=0; | ||
43 | opus_val32 xy02=0; | ||
44 | |||
45 | (void)arch; | ||
46 | |||
47 | asm volatile("MULT $ac1, $0, $0"); | ||
48 | asm volatile("MULT $ac2, $0, $0"); | ||
49 | /* Compute the norm of X+Y and X-Y as |X|^2 + |Y|^2 +/- sum(xy) */ | ||
50 | for (j=0;j<N;j++) | ||
51 | { | ||
52 | asm volatile("MADD $ac1, %0, %1" : : "r" ((int)x[j]), "r" ((int)y01[j])); | ||
53 | asm volatile("MADD $ac2, %0, %1" : : "r" ((int)x[j]), "r" ((int)y02[j])); | ||
54 | ++j; | ||
55 | asm volatile("MADD $ac1, %0, %1" : : "r" ((int)x[j]), "r" ((int)y01[j])); | ||
56 | asm volatile("MADD $ac2, %0, %1" : : "r" ((int)x[j]), "r" ((int)y02[j])); | ||
57 | } | ||
58 | asm volatile ("mflo %0, $ac1": "=r"(xy01)); | ||
59 | asm volatile ("mflo %0, $ac2": "=r"(xy02)); | ||
60 | *xy1 = xy01; | ||
61 | *xy2 = xy02; | ||
62 | } | ||
63 | |||
64 | static inline void xcorr_kernel_mips(const opus_val16 * x, | ||
65 | const opus_val16 * y, opus_val32 sum[4], int len) | ||
66 | { | ||
67 | int j; | ||
68 | opus_val16 y_0, y_1, y_2, y_3; | ||
69 | |||
70 | opus_int64 sum_0, sum_1, sum_2, sum_3; | ||
71 | sum_0 = (opus_int64)sum[0]; | ||
72 | sum_1 = (opus_int64)sum[1]; | ||
73 | sum_2 = (opus_int64)sum[2]; | ||
74 | sum_3 = (opus_int64)sum[3]; | ||
75 | |||
76 | y_3=0; /* gcc doesn't realize that y_3 can't be used uninitialized */ | ||
77 | y_0=*y++; | ||
78 | y_1=*y++; | ||
79 | y_2=*y++; | ||
80 | for (j=0;j<len-3;j+=4) | ||
81 | { | ||
82 | opus_val16 tmp; | ||
83 | tmp = *x++; | ||
84 | y_3=*y++; | ||
85 | |||
86 | sum_0 = __builtin_mips_madd( sum_0, tmp, y_0); | ||
87 | sum_1 = __builtin_mips_madd( sum_1, tmp, y_1); | ||
88 | sum_2 = __builtin_mips_madd( sum_2, tmp, y_2); | ||
89 | sum_3 = __builtin_mips_madd( sum_3, tmp, y_3); | ||
90 | |||
91 | tmp=*x++; | ||
92 | y_0=*y++; | ||
93 | |||
94 | sum_0 = __builtin_mips_madd( sum_0, tmp, y_1 ); | ||
95 | sum_1 = __builtin_mips_madd( sum_1, tmp, y_2 ); | ||
96 | sum_2 = __builtin_mips_madd( sum_2, tmp, y_3); | ||
97 | sum_3 = __builtin_mips_madd( sum_3, tmp, y_0); | ||
98 | |||
99 | tmp=*x++; | ||
100 | y_1=*y++; | ||
101 | |||
102 | sum_0 = __builtin_mips_madd( sum_0, tmp, y_2 ); | ||
103 | sum_1 = __builtin_mips_madd( sum_1, tmp, y_3 ); | ||
104 | sum_2 = __builtin_mips_madd( sum_2, tmp, y_0); | ||
105 | sum_3 = __builtin_mips_madd( sum_3, tmp, y_1); | ||
106 | |||
107 | |||
108 | tmp=*x++; | ||
109 | y_2=*y++; | ||
110 | |||
111 | sum_0 = __builtin_mips_madd( sum_0, tmp, y_3 ); | ||
112 | sum_1 = __builtin_mips_madd( sum_1, tmp, y_0 ); | ||
113 | sum_2 = __builtin_mips_madd( sum_2, tmp, y_1); | ||
114 | sum_3 = __builtin_mips_madd( sum_3, tmp, y_2); | ||
115 | |||
116 | } | ||
117 | if (j++<len) | ||
118 | { | ||
119 | opus_val16 tmp = *x++; | ||
120 | y_3=*y++; | ||
121 | |||
122 | sum_0 = __builtin_mips_madd( sum_0, tmp, y_0 ); | ||
123 | sum_1 = __builtin_mips_madd( sum_1, tmp, y_1 ); | ||
124 | sum_2 = __builtin_mips_madd( sum_2, tmp, y_2); | ||
125 | sum_3 = __builtin_mips_madd( sum_3, tmp, y_3); | ||
126 | } | ||
127 | |||
128 | if (j++<len) | ||
129 | { | ||
130 | opus_val16 tmp=*x++; | ||
131 | y_0=*y++; | ||
132 | |||
133 | sum_0 = __builtin_mips_madd( sum_0, tmp, y_1 ); | ||
134 | sum_1 = __builtin_mips_madd( sum_1, tmp, y_2 ); | ||
135 | sum_2 = __builtin_mips_madd( sum_2, tmp, y_3); | ||
136 | sum_3 = __builtin_mips_madd( sum_3, tmp, y_0); | ||
137 | } | ||
138 | |||
139 | if (j<len) | ||
140 | { | ||
141 | opus_val16 tmp=*x++; | ||
142 | y_1=*y++; | ||
143 | |||
144 | sum_0 = __builtin_mips_madd( sum_0, tmp, y_2 ); | ||
145 | sum_1 = __builtin_mips_madd( sum_1, tmp, y_3 ); | ||
146 | sum_2 = __builtin_mips_madd( sum_2, tmp, y_0); | ||
147 | sum_3 = __builtin_mips_madd( sum_3, tmp, y_1); | ||
148 | |||
149 | } | ||
150 | |||
151 | sum[0] = (opus_val32)sum_0; | ||
152 | sum[1] = (opus_val32)sum_1; | ||
153 | sum[2] = (opus_val32)sum_2; | ||
154 | sum[3] = (opus_val32)sum_3; | ||
155 | } | ||
156 | |||
157 | #define OVERRIDE_XCORR_KERNEL | ||
158 | #define xcorr_kernel(x, y, sum, len, arch) \ | ||
159 | ((void)(arch), xcorr_kernel_mips(x, y, sum, len)) | ||
160 | |||
161 | #endif /* PITCH_MIPSR1_H */ | ||
diff --git a/lib/rbcodec/codecs/libopus/celt/mips/vq_mipsr1.h b/lib/rbcodec/codecs/libopus/celt/mips/vq_mipsr1.h new file mode 100644 index 0000000000..fd18eab7a9 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/celt/mips/vq_mipsr1.h | |||
@@ -0,0 +1,122 @@ | |||
1 | /* Copyright (c) 2007-2008 CSIRO | ||
2 | Copyright (c) 2007-2009 Xiph.Org Foundation | ||
3 | Written by Jean-Marc Valin */ | ||
4 | /* | ||
5 | Redistribution and use in source and binary forms, with or without | ||
6 | modification, are permitted provided that the following conditions | ||
7 | are met: | ||
8 | |||
9 | - Redistributions of source code must retain the above copyright | ||
10 | notice, this list of conditions and the following disclaimer. | ||
11 | |||
12 | - Redistributions in binary form must reproduce the above copyright | ||
13 | notice, this list of conditions and the following disclaimer in the | ||
14 | documentation and/or other materials provided with the distribution. | ||
15 | |||
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
17 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
18 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
19 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER | ||
20 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
21 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
22 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
23 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
24 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
25 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
26 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
27 | */ | ||
28 | |||
29 | #ifndef __VQ_MIPSR1_H__ | ||
30 | #define __VQ_MIPSR1_H__ | ||
31 | |||
32 | #ifdef HAVE_CONFIG_H | ||
33 | #include "config.h" | ||
34 | #endif | ||
35 | |||
36 | #include "mathops.h" | ||
37 | #include "arch.h" | ||
38 | |||
39 | static void renormalise_vector_mips(celt_norm *X, int N, opus_val16 gain, int arch); | ||
40 | |||
41 | #define OVERRIDE_vq_exp_rotation1 | ||
42 | static void exp_rotation1(celt_norm *X, int len, int stride, opus_val16 c, opus_val16 s) | ||
43 | { | ||
44 | int i; | ||
45 | opus_val16 ms; | ||
46 | celt_norm *Xptr; | ||
47 | Xptr = X; | ||
48 | ms = NEG16(s); | ||
49 | for (i=0;i<len-stride;i++) | ||
50 | { | ||
51 | celt_norm x1, x2; | ||
52 | x1 = Xptr[0]; | ||
53 | x2 = Xptr[stride]; | ||
54 | Xptr[stride] = EXTRACT16(PSHR32(MAC16_16(MULT16_16(c, x2), s, x1), 15)); | ||
55 | *Xptr++ = EXTRACT16(PSHR32(MAC16_16(MULT16_16(c, x1), ms, x2), 15)); | ||
56 | } | ||
57 | Xptr = &X[len-2*stride-1]; | ||
58 | for (i=len-2*stride-1;i>=0;i--) | ||
59 | { | ||
60 | celt_norm x1, x2; | ||
61 | x1 = Xptr[0]; | ||
62 | x2 = Xptr[stride]; | ||
63 | Xptr[stride] = EXTRACT16(PSHR32(MAC16_16(MULT16_16(c, x2), s, x1), 15)); | ||
64 | *Xptr-- = EXTRACT16(PSHR32(MAC16_16(MULT16_16(c, x1), ms, x2), 15)); | ||
65 | } | ||
66 | } | ||
67 | |||
68 | #define OVERRIDE_renormalise_vector | ||
69 | |||
70 | #define renormalise_vector(X, N, gain, arch) \ | ||
71 | (renormalise_vector_mips(X, N, gain, arch)) | ||
72 | |||
73 | void renormalise_vector_mips(celt_norm *X, int N, opus_val16 gain, int arch) | ||
74 | { | ||
75 | int i; | ||
76 | #ifdef FIXED_POINT | ||
77 | int k; | ||
78 | #endif | ||
79 | opus_val32 E = EPSILON; | ||
80 | opus_val16 g; | ||
81 | opus_val32 t; | ||
82 | celt_norm *xptr = X; | ||
83 | int X0, X1; | ||
84 | |||
85 | (void)arch; | ||
86 | |||
87 | asm volatile("mult $ac1, $0, $0"); | ||
88 | asm volatile("MTLO %0, $ac1" : :"r" (E)); | ||
89 | /*if(N %4) | ||
90 | printf("error");*/ | ||
91 | for (i=0;i<N-2;i+=2) | ||
92 | { | ||
93 | X0 = (int)*xptr++; | ||
94 | asm volatile("MADD $ac1, %0, %1" : : "r" (X0), "r" (X0)); | ||
95 | |||
96 | X1 = (int)*xptr++; | ||
97 | asm volatile("MADD $ac1, %0, %1" : : "r" (X1), "r" (X1)); | ||
98 | } | ||
99 | |||
100 | for (;i<N;i++) | ||
101 | { | ||
102 | X0 = (int)*xptr++; | ||
103 | asm volatile("MADD $ac1, %0, %1" : : "r" (X0), "r" (X0)); | ||
104 | } | ||
105 | |||
106 | asm volatile("MFLO %0, $ac1" : "=r" (E)); | ||
107 | #ifdef FIXED_POINT | ||
108 | k = celt_ilog2(E)>>1; | ||
109 | #endif | ||
110 | t = VSHR32(E, 2*(k-7)); | ||
111 | g = MULT16_16_P15(celt_rsqrt_norm(t),gain); | ||
112 | |||
113 | xptr = X; | ||
114 | for (i=0;i<N;i++) | ||
115 | { | ||
116 | *xptr = EXTRACT16(PSHR32(MULT16_16(g, *xptr), k+1)); | ||
117 | xptr++; | ||
118 | } | ||
119 | /*return celt_sqrt(E);*/ | ||
120 | } | ||
121 | |||
122 | #endif /* __VQ_MIPSR1_H__ */ | ||