summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/libopus/celt/mips
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/libopus/celt/mips')
-rw-r--r--lib/rbcodec/codecs/libopus/celt/mips/celt_mipsr1.h151
-rw-r--r--lib/rbcodec/codecs/libopus/celt/mips/fixed_generic_mipsr1.h126
-rw-r--r--lib/rbcodec/codecs/libopus/celt/mips/kiss_fft_mipsr1.h167
-rw-r--r--lib/rbcodec/codecs/libopus/celt/mips/mdct_mipsr1.h288
-rw-r--r--lib/rbcodec/codecs/libopus/celt/mips/pitch_mipsr1.h161
-rw-r--r--lib/rbcodec/codecs/libopus/celt/mips/vq_mipsr1.h122
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
57void 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
37static 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
46static 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
55static 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
64static 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
74static 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
83static 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
92static 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
101static 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
110static 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
118static 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
39static 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
48static 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))
58static 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))
72static 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
88static 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
60void 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
186void 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
38static 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
64static 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
39static void renormalise_vector_mips(celt_norm *X, int N, opus_val16 gain, int arch);
40
41#define OVERRIDE_vq_exp_rotation1
42static 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
73void 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__ */