xref: /aosp_15_r20/external/rnnoise/src/pitch.h (revision 1295d6828459cc82c3c29cc5d7d297215250a74b)
1*1295d682SXin Li /* Copyright (c) 2007-2008 CSIRO
2*1295d682SXin Li    Copyright (c) 2007-2009 Xiph.Org Foundation
3*1295d682SXin Li    Written by Jean-Marc Valin */
4*1295d682SXin Li /**
5*1295d682SXin Li    @file pitch.h
6*1295d682SXin Li    @brief Pitch analysis
7*1295d682SXin Li  */
8*1295d682SXin Li 
9*1295d682SXin Li /*
10*1295d682SXin Li    Redistribution and use in source and binary forms, with or without
11*1295d682SXin Li    modification, are permitted provided that the following conditions
12*1295d682SXin Li    are met:
13*1295d682SXin Li 
14*1295d682SXin Li    - Redistributions of source code must retain the above copyright
15*1295d682SXin Li    notice, this list of conditions and the following disclaimer.
16*1295d682SXin Li 
17*1295d682SXin Li    - Redistributions in binary form must reproduce the above copyright
18*1295d682SXin Li    notice, this list of conditions and the following disclaimer in the
19*1295d682SXin Li    documentation and/or other materials provided with the distribution.
20*1295d682SXin Li 
21*1295d682SXin Li    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22*1295d682SXin Li    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23*1295d682SXin Li    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24*1295d682SXin Li    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
25*1295d682SXin Li    OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26*1295d682SXin Li    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27*1295d682SXin Li    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28*1295d682SXin Li    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29*1295d682SXin Li    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30*1295d682SXin Li    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31*1295d682SXin Li    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32*1295d682SXin Li */
33*1295d682SXin Li 
34*1295d682SXin Li #ifndef PITCH_H
35*1295d682SXin Li #define PITCH_H
36*1295d682SXin Li 
37*1295d682SXin Li //#include "modes.h"
38*1295d682SXin Li //#include "cpu_support.h"
39*1295d682SXin Li #include "arch.h"
40*1295d682SXin Li 
41*1295d682SXin Li void pitch_downsample(celt_sig *x[], opus_val16 *x_lp,
42*1295d682SXin Li       int len, int C);
43*1295d682SXin Li 
44*1295d682SXin Li void pitch_search(const opus_val16 *x_lp, opus_val16 *y,
45*1295d682SXin Li                   int len, int max_pitch, int *pitch);
46*1295d682SXin Li 
47*1295d682SXin Li opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod,
48*1295d682SXin Li       int N, int *T0, int prev_period, opus_val16 prev_gain);
49*1295d682SXin Li 
50*1295d682SXin Li 
51*1295d682SXin Li /* OPT: This is the kernel you really want to optimize. It gets used a lot
52*1295d682SXin Li    by the prefilter and by the PLC. */
xcorr_kernel(const opus_val16 * x,const opus_val16 * y,opus_val32 sum[4],int len)53*1295d682SXin Li static OPUS_INLINE void xcorr_kernel(const opus_val16 * x, const opus_val16 * y, opus_val32 sum[4], int len)
54*1295d682SXin Li {
55*1295d682SXin Li    int j;
56*1295d682SXin Li    opus_val16 y_0, y_1, y_2, y_3;
57*1295d682SXin Li    celt_assert(len>=3);
58*1295d682SXin Li    y_3=0; /* gcc doesn't realize that y_3 can't be used uninitialized */
59*1295d682SXin Li    y_0=*y++;
60*1295d682SXin Li    y_1=*y++;
61*1295d682SXin Li    y_2=*y++;
62*1295d682SXin Li    for (j=0;j<len-3;j+=4)
63*1295d682SXin Li    {
64*1295d682SXin Li       opus_val16 tmp;
65*1295d682SXin Li       tmp = *x++;
66*1295d682SXin Li       y_3=*y++;
67*1295d682SXin Li       sum[0] = MAC16_16(sum[0],tmp,y_0);
68*1295d682SXin Li       sum[1] = MAC16_16(sum[1],tmp,y_1);
69*1295d682SXin Li       sum[2] = MAC16_16(sum[2],tmp,y_2);
70*1295d682SXin Li       sum[3] = MAC16_16(sum[3],tmp,y_3);
71*1295d682SXin Li       tmp=*x++;
72*1295d682SXin Li       y_0=*y++;
73*1295d682SXin Li       sum[0] = MAC16_16(sum[0],tmp,y_1);
74*1295d682SXin Li       sum[1] = MAC16_16(sum[1],tmp,y_2);
75*1295d682SXin Li       sum[2] = MAC16_16(sum[2],tmp,y_3);
76*1295d682SXin Li       sum[3] = MAC16_16(sum[3],tmp,y_0);
77*1295d682SXin Li       tmp=*x++;
78*1295d682SXin Li       y_1=*y++;
79*1295d682SXin Li       sum[0] = MAC16_16(sum[0],tmp,y_2);
80*1295d682SXin Li       sum[1] = MAC16_16(sum[1],tmp,y_3);
81*1295d682SXin Li       sum[2] = MAC16_16(sum[2],tmp,y_0);
82*1295d682SXin Li       sum[3] = MAC16_16(sum[3],tmp,y_1);
83*1295d682SXin Li       tmp=*x++;
84*1295d682SXin Li       y_2=*y++;
85*1295d682SXin Li       sum[0] = MAC16_16(sum[0],tmp,y_3);
86*1295d682SXin Li       sum[1] = MAC16_16(sum[1],tmp,y_0);
87*1295d682SXin Li       sum[2] = MAC16_16(sum[2],tmp,y_1);
88*1295d682SXin Li       sum[3] = MAC16_16(sum[3],tmp,y_2);
89*1295d682SXin Li    }
90*1295d682SXin Li    if (j++<len)
91*1295d682SXin Li    {
92*1295d682SXin Li       opus_val16 tmp = *x++;
93*1295d682SXin Li       y_3=*y++;
94*1295d682SXin Li       sum[0] = MAC16_16(sum[0],tmp,y_0);
95*1295d682SXin Li       sum[1] = MAC16_16(sum[1],tmp,y_1);
96*1295d682SXin Li       sum[2] = MAC16_16(sum[2],tmp,y_2);
97*1295d682SXin Li       sum[3] = MAC16_16(sum[3],tmp,y_3);
98*1295d682SXin Li    }
99*1295d682SXin Li    if (j++<len)
100*1295d682SXin Li    {
101*1295d682SXin Li       opus_val16 tmp=*x++;
102*1295d682SXin Li       y_0=*y++;
103*1295d682SXin Li       sum[0] = MAC16_16(sum[0],tmp,y_1);
104*1295d682SXin Li       sum[1] = MAC16_16(sum[1],tmp,y_2);
105*1295d682SXin Li       sum[2] = MAC16_16(sum[2],tmp,y_3);
106*1295d682SXin Li       sum[3] = MAC16_16(sum[3],tmp,y_0);
107*1295d682SXin Li    }
108*1295d682SXin Li    if (j<len)
109*1295d682SXin Li    {
110*1295d682SXin Li       opus_val16 tmp=*x++;
111*1295d682SXin Li       y_1=*y++;
112*1295d682SXin Li       sum[0] = MAC16_16(sum[0],tmp,y_2);
113*1295d682SXin Li       sum[1] = MAC16_16(sum[1],tmp,y_3);
114*1295d682SXin Li       sum[2] = MAC16_16(sum[2],tmp,y_0);
115*1295d682SXin Li       sum[3] = MAC16_16(sum[3],tmp,y_1);
116*1295d682SXin Li    }
117*1295d682SXin Li }
118*1295d682SXin Li 
dual_inner_prod(const opus_val16 * x,const opus_val16 * y01,const opus_val16 * y02,int N,opus_val32 * xy1,opus_val32 * xy2)119*1295d682SXin Li static OPUS_INLINE void dual_inner_prod(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02,
120*1295d682SXin Li       int N, opus_val32 *xy1, opus_val32 *xy2)
121*1295d682SXin Li {
122*1295d682SXin Li    int i;
123*1295d682SXin Li    opus_val32 xy01=0;
124*1295d682SXin Li    opus_val32 xy02=0;
125*1295d682SXin Li    for (i=0;i<N;i++)
126*1295d682SXin Li    {
127*1295d682SXin Li       xy01 = MAC16_16(xy01, x[i], y01[i]);
128*1295d682SXin Li       xy02 = MAC16_16(xy02, x[i], y02[i]);
129*1295d682SXin Li    }
130*1295d682SXin Li    *xy1 = xy01;
131*1295d682SXin Li    *xy2 = xy02;
132*1295d682SXin Li }
133*1295d682SXin Li 
134*1295d682SXin Li /*We make sure a C version is always available for cases where the overhead of
135*1295d682SXin Li   vectorization and passing around an arch flag aren't worth it.*/
celt_inner_prod(const opus_val16 * x,const opus_val16 * y,int N)136*1295d682SXin Li static OPUS_INLINE opus_val32 celt_inner_prod(const opus_val16 *x,
137*1295d682SXin Li       const opus_val16 *y, int N)
138*1295d682SXin Li {
139*1295d682SXin Li    int i;
140*1295d682SXin Li    opus_val32 xy=0;
141*1295d682SXin Li    for (i=0;i<N;i++)
142*1295d682SXin Li       xy = MAC16_16(xy, x[i], y[i]);
143*1295d682SXin Li    return xy;
144*1295d682SXin Li }
145*1295d682SXin Li 
146*1295d682SXin Li void celt_pitch_xcorr(const opus_val16 *_x, const opus_val16 *_y,
147*1295d682SXin Li       opus_val32 *xcorr, int len, int max_pitch);
148*1295d682SXin Li 
149*1295d682SXin Li #endif
150