Line data Source code
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_H
35 : #define PITCH_H
36 :
37 : #include "modes.h"
38 : #include "cpu_support.h"
39 :
40 : #if (defined(OPUS_X86_MAY_HAVE_SSE) && !defined(FIXED_POINT)) \
41 : || ((defined(OPUS_X86_MAY_HAVE_SSE4_1) || defined(OPUS_X86_MAY_HAVE_SSE2)) && defined(FIXED_POINT))
42 : #include "x86/pitch_sse.h"
43 : #endif
44 :
45 : #if defined(MIPSr1_ASM)
46 : #include "mips/pitch_mipsr1.h"
47 : #endif
48 :
49 : #if (defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR))
50 : # include "arm/pitch_arm.h"
51 : #endif
52 :
53 : void pitch_downsample(celt_sig * OPUS_RESTRICT x[], opus_val16 * OPUS_RESTRICT x_lp,
54 : int len, int C, int arch);
55 :
56 : void pitch_search(const opus_val16 * OPUS_RESTRICT x_lp, opus_val16 * OPUS_RESTRICT y,
57 : int len, int max_pitch, int *pitch, int arch);
58 :
59 : opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod,
60 : int N, int *T0, int prev_period, opus_val16 prev_gain, int arch);
61 :
62 :
63 : /* OPT: This is the kernel you really want to optimize. It gets used a lot
64 : by the prefilter and by the PLC. */
65 0 : static OPUS_INLINE void xcorr_kernel_c(const opus_val16 * x, 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 0 : celt_assert(len>=3);
70 0 : y_3=0; /* gcc doesn't realize that y_3 can't be used uninitialized */
71 0 : y_0=*y++;
72 0 : y_1=*y++;
73 0 : y_2=*y++;
74 0 : for (j=0;j<len-3;j+=4)
75 : {
76 : opus_val16 tmp;
77 0 : tmp = *x++;
78 0 : y_3=*y++;
79 0 : sum[0] = MAC16_16(sum[0],tmp,y_0);
80 0 : sum[1] = MAC16_16(sum[1],tmp,y_1);
81 0 : sum[2] = MAC16_16(sum[2],tmp,y_2);
82 0 : sum[3] = MAC16_16(sum[3],tmp,y_3);
83 0 : tmp=*x++;
84 0 : y_0=*y++;
85 0 : sum[0] = MAC16_16(sum[0],tmp,y_1);
86 0 : sum[1] = MAC16_16(sum[1],tmp,y_2);
87 0 : sum[2] = MAC16_16(sum[2],tmp,y_3);
88 0 : sum[3] = MAC16_16(sum[3],tmp,y_0);
89 0 : tmp=*x++;
90 0 : y_1=*y++;
91 0 : sum[0] = MAC16_16(sum[0],tmp,y_2);
92 0 : sum[1] = MAC16_16(sum[1],tmp,y_3);
93 0 : sum[2] = MAC16_16(sum[2],tmp,y_0);
94 0 : sum[3] = MAC16_16(sum[3],tmp,y_1);
95 0 : tmp=*x++;
96 0 : y_2=*y++;
97 0 : sum[0] = MAC16_16(sum[0],tmp,y_3);
98 0 : sum[1] = MAC16_16(sum[1],tmp,y_0);
99 0 : sum[2] = MAC16_16(sum[2],tmp,y_1);
100 0 : sum[3] = MAC16_16(sum[3],tmp,y_2);
101 : }
102 0 : if (j++<len)
103 : {
104 0 : opus_val16 tmp = *x++;
105 0 : y_3=*y++;
106 0 : sum[0] = MAC16_16(sum[0],tmp,y_0);
107 0 : sum[1] = MAC16_16(sum[1],tmp,y_1);
108 0 : sum[2] = MAC16_16(sum[2],tmp,y_2);
109 0 : sum[3] = MAC16_16(sum[3],tmp,y_3);
110 : }
111 0 : if (j++<len)
112 : {
113 0 : opus_val16 tmp=*x++;
114 0 : y_0=*y++;
115 0 : sum[0] = MAC16_16(sum[0],tmp,y_1);
116 0 : sum[1] = MAC16_16(sum[1],tmp,y_2);
117 0 : sum[2] = MAC16_16(sum[2],tmp,y_3);
118 0 : sum[3] = MAC16_16(sum[3],tmp,y_0);
119 : }
120 0 : if (j<len)
121 : {
122 0 : opus_val16 tmp=*x++;
123 0 : y_1=*y++;
124 0 : sum[0] = MAC16_16(sum[0],tmp,y_2);
125 0 : sum[1] = MAC16_16(sum[1],tmp,y_3);
126 0 : sum[2] = MAC16_16(sum[2],tmp,y_0);
127 0 : sum[3] = MAC16_16(sum[3],tmp,y_1);
128 : }
129 0 : }
130 :
131 : #ifndef OVERRIDE_XCORR_KERNEL
132 : #define xcorr_kernel(x, y, sum, len, arch) \
133 : ((void)(arch),xcorr_kernel_c(x, y, sum, len))
134 : #endif /* OVERRIDE_XCORR_KERNEL */
135 :
136 :
137 0 : static OPUS_INLINE void dual_inner_prod_c(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02,
138 : int N, opus_val32 *xy1, opus_val32 *xy2)
139 : {
140 : int i;
141 0 : opus_val32 xy01=0;
142 0 : opus_val32 xy02=0;
143 0 : for (i=0;i<N;i++)
144 : {
145 0 : xy01 = MAC16_16(xy01, x[i], y01[i]);
146 0 : xy02 = MAC16_16(xy02, x[i], y02[i]);
147 : }
148 0 : *xy1 = xy01;
149 0 : *xy2 = xy02;
150 0 : }
151 :
152 : #ifndef OVERRIDE_DUAL_INNER_PROD
153 : # define dual_inner_prod(x, y01, y02, N, xy1, xy2, arch) \
154 : ((void)(arch),dual_inner_prod_c(x, y01, y02, N, xy1, xy2))
155 : #endif
156 :
157 : /*We make sure a C version is always available for cases where the overhead of
158 : vectorization and passing around an arch flag aren't worth it.*/
159 0 : static OPUS_INLINE opus_val32 celt_inner_prod_c(const opus_val16 *x,
160 : const opus_val16 *y, int N)
161 : {
162 : int i;
163 0 : opus_val32 xy=0;
164 0 : for (i=0;i<N;i++)
165 0 : xy = MAC16_16(xy, x[i], y[i]);
166 0 : return xy;
167 : }
168 :
169 : #if !defined(OVERRIDE_CELT_INNER_PROD)
170 : # define celt_inner_prod(x, y, N, arch) \
171 : ((void)(arch),celt_inner_prod_c(x, y, N))
172 : #endif
173 :
174 : #ifdef NON_STATIC_COMB_FILTER_CONST_C
175 : void comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N,
176 : opus_val16 g10, opus_val16 g11, opus_val16 g12);
177 : #endif
178 :
179 :
180 : #ifdef FIXED_POINT
181 : opus_val32
182 : #else
183 : void
184 : #endif
185 : celt_pitch_xcorr_c(const opus_val16 *_x, const opus_val16 *_y,
186 : opus_val32 *xcorr, int len, int max_pitch, int arch);
187 :
188 : #ifndef OVERRIDE_PITCH_XCORR
189 : # define celt_pitch_xcorr celt_pitch_xcorr_c
190 : #endif
191 :
192 : #endif
|