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