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