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