Skip to content

Latest commit

 

History

History
630 lines (561 loc) · 28.7 KB

pitch_analysis_core_FLP.c

File metadata and controls

630 lines (561 loc) · 28.7 KB
 
1
2
3
4
5
6
7
8
9
10
/***********************************************************************
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
Oct 6, 2019
Oct 6, 2019
11
- Neither the name of Internet Society, IETF or IETF Trust, nor the
12
13
14
names of specific contributors, may be used to endorse or promote
products derived from this software without specific prior written
permission.
Oct 6, 2019
Oct 6, 2019
15
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/*****************************************************************************
* Pitch analyser function
******************************************************************************/
#include "SigProc_FLP.h"
#include "SigProc_FIX.h"
#include "pitch_est_defines.h"
Oct 6, 2019
Oct 6, 2019
38
#include "pitch.h"
39
40
41
42
43
44
45
46
47
48
49
50
#define SCRATCH_SIZE 22
/************************************************************/
/* Internally used functions */
/************************************************************/
static void silk_P_Ana_calc_corr_st3(
silk_float cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */
const silk_float frame[], /* I vector to correlate */
opus_int start_lag, /* I start lag */
opus_int sf_length, /* I sub frame length */
opus_int nb_subfr, /* I number of subframes */
Oct 6, 2019
Oct 6, 2019
51
52
opus_int complexity, /* I Complexity setting */
int arch /* I Run-time architecture */
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
);
static void silk_P_Ana_calc_energy_st3(
silk_float energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */
const silk_float frame[], /* I vector to correlate */
opus_int start_lag, /* I start lag */
opus_int sf_length, /* I sub frame length */
opus_int nb_subfr, /* I number of subframes */
opus_int complexity /* I Complexity setting */
);
/************************************************************/
/* CORE PITCH ANALYSIS FUNCTION */
/************************************************************/
opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced, 1 unvoiced */
const silk_float *frame, /* I Signal of length PE_FRAME_LENGTH_MS*Fs_kHz */
opus_int *pitch_out, /* O Pitch lag values [nb_subfr] */
opus_int16 *lagIndex, /* O Lag Index */
opus_int8 *contourIndex, /* O Pitch contour Index */
silk_float *LTPCorr, /* I/O Normalized correlation; input: value from previous frame */
opus_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */
const silk_float search_thres1, /* I First stage threshold for lag candidates 0 - 1 */
const silk_float search_thres2, /* I Final threshold for lag candidates 0 - 1 */
const opus_int Fs_kHz, /* I sample frequency (kHz) */
const opus_int complexity, /* I Complexity setting, 0-2, where 2 is highest */
Oct 6, 2019
Oct 6, 2019
78
79
const opus_int nb_subfr, /* I Number of 5 ms subframes */
int arch /* I Run-time architecture */
80
81
82
83
84
85
86
87
88
89
)
{
opus_int i, k, d, j;
silk_float frame_8kHz[ PE_MAX_FRAME_LENGTH_MS * 8 ];
silk_float frame_4kHz[ PE_MAX_FRAME_LENGTH_MS * 4 ];
opus_int16 frame_8_FIX[ PE_MAX_FRAME_LENGTH_MS * 8 ];
opus_int16 frame_4_FIX[ PE_MAX_FRAME_LENGTH_MS * 4 ];
opus_int32 filt_state[ 6 ];
silk_float threshold, contour_bias;
silk_float C[ PE_MAX_NB_SUBFR][ (PE_MAX_LAG >> 1) + 5 ];
Oct 6, 2019
Oct 6, 2019
90
opus_val32 xcorr[ PE_MAX_LAG_MS * 4 - PE_MIN_LAG_MS * 4 + 1 ];
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
silk_float CC[ PE_NB_CBKS_STAGE2_EXT ];
const silk_float *target_ptr, *basis_ptr;
double cross_corr, normalizer, energy, energy_tmp;
opus_int d_srch[ PE_D_SRCH_LENGTH ];
opus_int16 d_comp[ (PE_MAX_LAG >> 1) + 5 ];
opus_int length_d_srch, length_d_comp;
silk_float Cmax, CCmax, CCmax_b, CCmax_new_b, CCmax_new;
opus_int CBimax, CBimax_new, lag, start_lag, end_lag, lag_new;
opus_int cbk_size;
silk_float lag_log2, prevLag_log2, delta_lag_log2_sqr;
silk_float energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ];
silk_float cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ];
opus_int lag_counter;
opus_int frame_length, frame_length_8kHz, frame_length_4kHz;
opus_int sf_length, sf_length_8kHz, sf_length_4kHz;
opus_int min_lag, min_lag_8kHz, min_lag_4kHz;
opus_int max_lag, max_lag_8kHz, max_lag_4kHz;
opus_int nb_cbk_search;
const opus_int8 *Lag_CB_ptr;
/* Check for valid sampling frequency */
Oct 6, 2019
Oct 6, 2019
112
celt_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 );
113
114
/* Check for valid complexity setting */
Oct 6, 2019
Oct 6, 2019
115
116
celt_assert( complexity >= SILK_PE_MIN_COMPLEX );
celt_assert( complexity <= SILK_PE_MAX_COMPLEX );
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
silk_assert( search_thres1 >= 0.0f && search_thres1 <= 1.0f );
silk_assert( search_thres2 >= 0.0f && search_thres2 <= 1.0f );
/* Set up frame lengths max / min lag for the sampling frequency */
frame_length = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * Fs_kHz;
frame_length_4kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 4;
frame_length_8kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 8;
sf_length = PE_SUBFR_LENGTH_MS * Fs_kHz;
sf_length_4kHz = PE_SUBFR_LENGTH_MS * 4;
sf_length_8kHz = PE_SUBFR_LENGTH_MS * 8;
min_lag = PE_MIN_LAG_MS * Fs_kHz;
min_lag_4kHz = PE_MIN_LAG_MS * 4;
min_lag_8kHz = PE_MIN_LAG_MS * 8;
max_lag = PE_MAX_LAG_MS * Fs_kHz - 1;
max_lag_4kHz = PE_MAX_LAG_MS * 4;
max_lag_8kHz = PE_MAX_LAG_MS * 8 - 1;
/* Resample from input sampled at Fs_kHz to 8 kHz */
if( Fs_kHz == 16 ) {
/* Resample to 16 -> 8 khz */
opus_int16 frame_16_FIX[ 16 * PE_MAX_FRAME_LENGTH_MS ];
silk_float2short_array( frame_16_FIX, frame, frame_length );
silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) );
silk_resampler_down2( filt_state, frame_8_FIX, frame_16_FIX, frame_length );
silk_short2float_array( frame_8kHz, frame_8_FIX, frame_length_8kHz );
} else if( Fs_kHz == 12 ) {
/* Resample to 12 -> 8 khz */
opus_int16 frame_12_FIX[ 12 * PE_MAX_FRAME_LENGTH_MS ];
silk_float2short_array( frame_12_FIX, frame, frame_length );
silk_memset( filt_state, 0, 6 * sizeof( opus_int32 ) );
silk_resampler_down2_3( filt_state, frame_8_FIX, frame_12_FIX, frame_length );
silk_short2float_array( frame_8kHz, frame_8_FIX, frame_length_8kHz );
} else {
Oct 6, 2019
Oct 6, 2019
151
celt_assert( Fs_kHz == 8 );
152
153
154
155
156
157
158
159
160
161
silk_float2short_array( frame_8_FIX, frame, frame_length_8kHz );
}
/* Decimate again to 4 kHz */
silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) );
silk_resampler_down2( filt_state, frame_4_FIX, frame_8_FIX, frame_length_8kHz );
silk_short2float_array( frame_4kHz, frame_4_FIX, frame_length_4kHz );
/* Low-pass filter */
for( i = frame_length_4kHz - 1; i > 0; i-- ) {
Oct 6, 2019
Oct 6, 2019
162
frame_4kHz[ i ] = silk_ADD_SAT16( frame_4kHz[ i ], frame_4kHz[ i - 1 ] );
163
164
165
166
167
}
/******************************************************************************
* FIRST STAGE, operating in 4 khz
******************************************************************************/
Oct 6, 2019
Oct 6, 2019
168
silk_memset(C, 0, sizeof(silk_float) * nb_subfr * ((PE_MAX_LAG >> 1) + 5));
169
170
171
target_ptr = &frame_4kHz[ silk_LSHIFT( sf_length_4kHz, 2 ) ];
for( k = 0; k < nb_subfr >> 1; k++ ) {
/* Check that we are within range of the array */
Oct 6, 2019
Oct 6, 2019
172
173
celt_assert( target_ptr >= frame_4kHz );
celt_assert( target_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz );
174
175
176
177
basis_ptr = target_ptr - min_lag_4kHz;
/* Check that we are within range of the array */
Oct 6, 2019
Oct 6, 2019
178
179
180
181
celt_assert( basis_ptr >= frame_4kHz );
celt_assert( basis_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz );
celt_pitch_xcorr( target_ptr, target_ptr-max_lag_4kHz, xcorr, sf_length_8kHz, max_lag_4kHz - min_lag_4kHz + 1, arch );
182
183
/* Calculate first vector products before loop */
Oct 6, 2019
Oct 6, 2019
184
185
186
187
cross_corr = xcorr[ max_lag_4kHz - min_lag_4kHz ];
normalizer = silk_energy_FLP( target_ptr, sf_length_8kHz ) +
silk_energy_FLP( basis_ptr, sf_length_8kHz ) +
sf_length_8kHz * 4000.0f;
Oct 6, 2019
Oct 6, 2019
189
C[ 0 ][ min_lag_4kHz ] += (silk_float)( 2 * cross_corr / normalizer );
190
191
/* From now on normalizer is computed recursively */
Oct 6, 2019
Oct 6, 2019
192
for( d = min_lag_4kHz + 1; d <= max_lag_4kHz; d++ ) {
193
194
195
196
197
198
basis_ptr--;
/* Check that we are within range of the array */
silk_assert( basis_ptr >= frame_4kHz );
silk_assert( basis_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz );
Oct 6, 2019
Oct 6, 2019
199
cross_corr = xcorr[ max_lag_4kHz - d ];
200
201
202
203
204
/* Add contribution of new sample and remove contribution from oldest sample */
normalizer +=
basis_ptr[ 0 ] * (double)basis_ptr[ 0 ] -
basis_ptr[ sf_length_8kHz ] * (double)basis_ptr[ sf_length_8kHz ];
Oct 6, 2019
Oct 6, 2019
205
C[ 0 ][ d ] += (silk_float)( 2 * cross_corr / normalizer );
206
207
208
209
210
211
212
213
214
215
216
217
}
/* Update target pointer */
target_ptr += sf_length_8kHz;
}
/* Apply short-lag bias */
for( i = max_lag_4kHz; i >= min_lag_4kHz; i-- ) {
C[ 0 ][ i ] -= C[ 0 ][ i ] * i / 4096.0f;
}
/* Sort */
length_d_srch = 4 + 2 * complexity;
Oct 6, 2019
Oct 6, 2019
218
celt_assert( 3 * length_d_srch <= PE_D_SRCH_LENGTH );
219
220
221
222
silk_insertion_sort_decreasing_FLP( &C[ 0 ][ min_lag_4kHz ], d_srch, max_lag_4kHz - min_lag_4kHz + 1, length_d_srch );
/* Escape if correlation is very low already here */
Cmax = C[ 0 ][ min_lag_4kHz ];
Oct 6, 2019
Oct 6, 2019
223
if( Cmax < 0.2f ) {
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) );
*LTPCorr = 0.0f;
*lagIndex = 0;
*contourIndex = 0;
return 1;
}
threshold = search_thres1 * Cmax;
for( i = 0; i < length_d_srch; i++ ) {
/* Convert to 8 kHz indices for the sorted correlation that exceeds the threshold */
if( C[ 0 ][ min_lag_4kHz + i ] > threshold ) {
d_srch[ i ] = silk_LSHIFT( d_srch[ i ] + min_lag_4kHz, 1 );
} else {
length_d_srch = i;
break;
}
}
Oct 6, 2019
Oct 6, 2019
241
celt_assert( length_d_srch > 0 );
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
for( i = min_lag_8kHz - 5; i < max_lag_8kHz + 5; i++ ) {
d_comp[ i ] = 0;
}
for( i = 0; i < length_d_srch; i++ ) {
d_comp[ d_srch[ i ] ] = 1;
}
/* Convolution */
for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) {
d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ];
}
length_d_srch = 0;
for( i = min_lag_8kHz; i < max_lag_8kHz + 1; i++ ) {
if( d_comp[ i + 1 ] > 0 ) {
d_srch[ length_d_srch ] = i;
length_d_srch++;
}
}
/* Convolution */
for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) {
d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ] + d_comp[ i - 3 ];
}
length_d_comp = 0;
for( i = min_lag_8kHz; i < max_lag_8kHz + 4; i++ ) {
if( d_comp[ i ] > 0 ) {
d_comp[ length_d_comp ] = (opus_int16)( i - 2 );
length_d_comp++;
}
}
/**********************************************************************************
** SECOND STAGE, operating at 8 kHz, on lag sections with high correlation
*************************************************************************************/
/*********************************************************************************
* Find energy of each subframe projected onto its history, for a range of delays
*********************************************************************************/
silk_memset( C, 0, PE_MAX_NB_SUBFR*((PE_MAX_LAG >> 1) + 5) * sizeof(silk_float));
if( Fs_kHz == 8 ) {
target_ptr = &frame[ PE_LTP_MEM_LENGTH_MS * 8 ];
} else {
target_ptr = &frame_8kHz[ PE_LTP_MEM_LENGTH_MS * 8 ];
}
for( k = 0; k < nb_subfr; k++ ) {
Oct 6, 2019
Oct 6, 2019
290
energy_tmp = silk_energy_FLP( target_ptr, sf_length_8kHz ) + 1.0;
291
292
293
294
295
for( j = 0; j < length_d_comp; j++ ) {
d = d_comp[ j ];
basis_ptr = target_ptr - d;
cross_corr = silk_inner_product_FLP( basis_ptr, target_ptr, sf_length_8kHz );
if( cross_corr > 0.0f ) {
Oct 6, 2019
Oct 6, 2019
296
297
energy = silk_energy_FLP( basis_ptr, sf_length_8kHz );
C[ k ][ d ] = (silk_float)( 2 * cross_corr / ( energy + energy_tmp ) );
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
} else {
C[ k ][ d ] = 0.0f;
}
}
target_ptr += sf_length_8kHz;
}
/* search over lag range and lags codebook */
/* scale factor for lag codebook, as a function of center lag */
CCmax = 0.0f; /* This value doesn't matter */
CCmax_b = -1000.0f;
CBimax = 0; /* To avoid returning undefined lag values */
lag = -1; /* To check if lag with strong enough correlation has been found */
if( prevLag > 0 ) {
if( Fs_kHz == 12 ) {
prevLag = silk_LSHIFT( prevLag, 1 ) / 3;
} else if( Fs_kHz == 16 ) {
prevLag = silk_RSHIFT( prevLag, 1 );
}
Oct 6, 2019
Oct 6, 2019
320
prevLag_log2 = silk_log2( (silk_float)prevLag );
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
} else {
prevLag_log2 = 0;
}
/* Set up stage 2 codebook based on number of subframes */
if( nb_subfr == PE_MAX_NB_SUBFR ) {
cbk_size = PE_NB_CBKS_STAGE2_EXT;
Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ];
if( Fs_kHz == 8 && complexity > SILK_PE_MIN_COMPLEX ) {
/* If input is 8 khz use a larger codebook here because it is last stage */
nb_cbk_search = PE_NB_CBKS_STAGE2_EXT;
} else {
nb_cbk_search = PE_NB_CBKS_STAGE2;
}
} else {
cbk_size = PE_NB_CBKS_STAGE2_10MS;
Lag_CB_ptr = &silk_CB_lags_stage2_10_ms[ 0 ][ 0 ];
nb_cbk_search = PE_NB_CBKS_STAGE2_10MS;
}
for( k = 0; k < length_d_srch; k++ ) {
d = d_srch[ k ];
for( j = 0; j < nb_cbk_search; j++ ) {
CC[j] = 0.0f;
for( i = 0; i < nb_subfr; i++ ) {
/* Try all codebooks */
CC[ j ] += C[ i ][ d + matrix_ptr( Lag_CB_ptr, i, j, cbk_size )];
}
}
/* Find best codebook */
CCmax_new = -1000.0f;
CBimax_new = 0;
for( i = 0; i < nb_cbk_search; i++ ) {
if( CC[ i ] > CCmax_new ) {
CCmax_new = CC[ i ];
CBimax_new = i;
}
}
/* Bias towards shorter lags */
Oct 6, 2019
Oct 6, 2019
361
362
lag_log2 = silk_log2( (silk_float)d );
CCmax_new_b = CCmax_new - PE_SHORTLAG_BIAS * nb_subfr * lag_log2;
363
364
365
366
367
/* Bias towards previous lag */
if( prevLag > 0 ) {
delta_lag_log2_sqr = lag_log2 - prevLag_log2;
delta_lag_log2_sqr *= delta_lag_log2_sqr;
Oct 6, 2019
Oct 6, 2019
368
CCmax_new_b -= PE_PREVLAG_BIAS * nb_subfr * (*LTPCorr) * delta_lag_log2_sqr / ( delta_lag_log2_sqr + 0.5f );
Oct 6, 2019
Oct 6, 2019
371
372
if( CCmax_new_b > CCmax_b && /* Find maximum biased correlation */
CCmax_new > nb_subfr * search_thres2 /* Correlation needs to be high enough to be voiced */
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
) {
CCmax_b = CCmax_new_b;
CCmax = CCmax_new;
lag = d;
CBimax = CBimax_new;
}
}
if( lag == -1 ) {
/* No suitable candidate found */
silk_memset( pitch_out, 0, PE_MAX_NB_SUBFR * sizeof(opus_int) );
*LTPCorr = 0.0f;
*lagIndex = 0;
*contourIndex = 0;
return 1;
}
Oct 6, 2019
Oct 6, 2019
390
391
392
393
/* Output normalized correlation */
*LTPCorr = (silk_float)( CCmax / nb_subfr );
silk_assert( *LTPCorr >= 0.0f );
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
if( Fs_kHz > 8 ) {
/* Search in original signal */
/* Compensate for decimation */
silk_assert( lag == silk_SAT16( lag ) );
if( Fs_kHz == 12 ) {
lag = silk_RSHIFT_ROUND( silk_SMULBB( lag, 3 ), 1 );
} else { /* Fs_kHz == 16 */
lag = silk_LSHIFT( lag, 1 );
}
lag = silk_LIMIT_int( lag, min_lag, max_lag );
start_lag = silk_max_int( lag - 2, min_lag );
end_lag = silk_min_int( lag + 2, max_lag );
lag_new = lag; /* to avoid undefined lag */
CBimax = 0; /* to avoid undefined lag */
CCmax = -1000.0f;
/* Calculate the correlations and energies needed in stage 3 */
Oct 6, 2019
Oct 6, 2019
414
silk_P_Ana_calc_corr_st3( cross_corr_st3, frame, start_lag, sf_length, nb_subfr, complexity, arch );
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
silk_P_Ana_calc_energy_st3( energies_st3, frame, start_lag, sf_length, nb_subfr, complexity );
lag_counter = 0;
silk_assert( lag == silk_SAT16( lag ) );
contour_bias = PE_FLATCONTOUR_BIAS / lag;
/* Set up cbk parameters according to complexity setting and frame length */
if( nb_subfr == PE_MAX_NB_SUBFR ) {
nb_cbk_search = (opus_int)silk_nb_cbk_searchs_stage3[ complexity ];
cbk_size = PE_NB_CBKS_STAGE3_MAX;
Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ];
} else {
nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
cbk_size = PE_NB_CBKS_STAGE3_10MS;
Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
}
Oct 6, 2019
Oct 6, 2019
432
433
target_ptr = &frame[ PE_LTP_MEM_LENGTH_MS * Fs_kHz ];
energy_tmp = silk_energy_FLP( target_ptr, nb_subfr * sf_length ) + 1.0;
434
435
436
for( d = start_lag; d <= end_lag; d++ ) {
for( j = 0; j < nb_cbk_search; j++ ) {
cross_corr = 0.0;
Oct 6, 2019
Oct 6, 2019
437
energy = energy_tmp;
438
439
for( k = 0; k < nb_subfr; k++ ) {
cross_corr += cross_corr_st3[ k ][ j ][ lag_counter ];
Oct 6, 2019
Oct 6, 2019
440
energy += energies_st3[ k ][ j ][ lag_counter ];
441
442
}
if( cross_corr > 0.0 ) {
Oct 6, 2019
Oct 6, 2019
443
CCmax_new = (silk_float)( 2 * cross_corr / energy );
444
445
446
447
448
449
/* Reduce depending on flatness of contour */
CCmax_new *= 1.0f - contour_bias * j;
} else {
CCmax_new = 0.0f;
}
Oct 6, 2019
Oct 6, 2019
450
if( CCmax_new > CCmax && ( d + (opus_int)silk_CB_lags_stage3[ 0 ][ j ] ) <= max_lag ) {
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
CCmax = CCmax_new;
lag_new = d;
CBimax = j;
}
}
lag_counter++;
}
for( k = 0; k < nb_subfr; k++ ) {
pitch_out[ k ] = lag_new + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size );
pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag, PE_MAX_LAG_MS * Fs_kHz );
}
*lagIndex = (opus_int16)( lag_new - min_lag );
*contourIndex = (opus_int8)CBimax;
} else { /* Fs_kHz == 8 */
Oct 6, 2019
Oct 6, 2019
466
/* Save Lags */
467
468
for( k = 0; k < nb_subfr; k++ ) {
pitch_out[ k ] = lag + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size );
Oct 6, 2019
Oct 6, 2019
469
pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag_8kHz, PE_MAX_LAG_MS * 8 );
470
471
472
473
}
*lagIndex = (opus_int16)( lag - min_lag_8kHz );
*contourIndex = (opus_int8)CBimax;
}
Oct 6, 2019
Oct 6, 2019
474
celt_assert( *lagIndex >= 0 );
475
476
477
478
/* return as voiced */
return 0;
}
Oct 6, 2019
Oct 6, 2019
479
480
481
482
483
484
485
486
487
488
489
490
491
/***********************************************************************
* Calculates the correlations used in stage 3 search. In order to cover
* the whole lag codebook for all the searched offset lags (lag +- 2),
* the following correlations are needed in each sub frame:
*
* sf1: lag range [-8,...,7] total 16 correlations
* sf2: lag range [-4,...,4] total 9 correlations
* sf3: lag range [-3,....4] total 8 correltions
* sf4: lag range [-6,....8] total 15 correlations
*
* In total 48 correlations. The direct implementation computed in worst
* case 4*12*5 = 240 correlations, but more likely around 120.
***********************************************************************/
492
493
494
495
496
497
static void silk_P_Ana_calc_corr_st3(
silk_float cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */
const silk_float frame[], /* I vector to correlate */
opus_int start_lag, /* I start lag */
opus_int sf_length, /* I sub frame length */
opus_int nb_subfr, /* I number of subframes */
Oct 6, 2019
Oct 6, 2019
498
499
opus_int complexity, /* I Complexity setting */
int arch /* I Run-time architecture */
Oct 6, 2019
Oct 6, 2019
502
const silk_float *target_ptr;
503
504
505
opus_int i, j, k, lag_counter, lag_low, lag_high;
opus_int nb_cbk_search, delta, idx, cbk_size;
silk_float scratch_mem[ SCRATCH_SIZE ];
Oct 6, 2019
Oct 6, 2019
506
opus_val32 xcorr[ SCRATCH_SIZE ];
507
508
const opus_int8 *Lag_range_ptr, *Lag_CB_ptr;
Oct 6, 2019
Oct 6, 2019
509
510
celt_assert( complexity >= SILK_PE_MIN_COMPLEX );
celt_assert( complexity <= SILK_PE_MAX_COMPLEX );
511
512
513
514
515
516
517
if( nb_subfr == PE_MAX_NB_SUBFR ) {
Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ];
Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ];
nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ];
cbk_size = PE_NB_CBKS_STAGE3_MAX;
} else {
Oct 6, 2019
Oct 6, 2019
518
celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);
519
520
521
522
523
524
525
526
527
528
529
530
531
Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ];
Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
cbk_size = PE_NB_CBKS_STAGE3_10MS;
}
target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ]; /* Pointer to middle of frame */
for( k = 0; k < nb_subfr; k++ ) {
lag_counter = 0;
/* Calculate the correlations for each subframe */
lag_low = matrix_ptr( Lag_range_ptr, k, 0, 2 );
lag_high = matrix_ptr( Lag_range_ptr, k, 1, 2 );
Oct 6, 2019
Oct 6, 2019
532
533
silk_assert(lag_high-lag_low+1 <= SCRATCH_SIZE);
celt_pitch_xcorr( target_ptr, target_ptr - start_lag - lag_high, xcorr, sf_length, lag_high - lag_low + 1, arch );
534
535
for( j = lag_low; j <= lag_high; j++ ) {
silk_assert( lag_counter < SCRATCH_SIZE );
Oct 6, 2019
Oct 6, 2019
536
scratch_mem[ lag_counter ] = xcorr[ lag_high - j ];
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
lag_counter++;
}
delta = matrix_ptr( Lag_range_ptr, k, 0, 2 );
for( i = 0; i < nb_cbk_search; i++ ) {
/* Fill out the 3 dim array that stores the correlations for */
/* each code_book vector for each start lag */
idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta;
for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) {
silk_assert( idx + j < SCRATCH_SIZE );
silk_assert( idx + j < lag_counter );
cross_corr_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ];
}
}
target_ptr += sf_length;
}
}
Oct 6, 2019
Oct 6, 2019
555
556
557
558
/********************************************************************/
/* Calculate the energies for first two subframes. The energies are */
/* calculated recursively. */
/********************************************************************/
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
static void silk_P_Ana_calc_energy_st3(
silk_float energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */
const silk_float frame[], /* I vector to correlate */
opus_int start_lag, /* I start lag */
opus_int sf_length, /* I sub frame length */
opus_int nb_subfr, /* I number of subframes */
opus_int complexity /* I Complexity setting */
)
{
const silk_float *target_ptr, *basis_ptr;
double energy;
opus_int k, i, j, lag_counter;
opus_int nb_cbk_search, delta, idx, cbk_size, lag_diff;
silk_float scratch_mem[ SCRATCH_SIZE ];
const opus_int8 *Lag_range_ptr, *Lag_CB_ptr;
Oct 6, 2019
Oct 6, 2019
575
576
celt_assert( complexity >= SILK_PE_MIN_COMPLEX );
celt_assert( complexity <= SILK_PE_MAX_COMPLEX );
577
578
579
580
581
582
583
if( nb_subfr == PE_MAX_NB_SUBFR ) {
Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ];
Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ];
nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ];
cbk_size = PE_NB_CBKS_STAGE3_MAX;
} else {
Oct 6, 2019
Oct 6, 2019
584
celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ];
Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
cbk_size = PE_NB_CBKS_STAGE3_10MS;
}
target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ];
for( k = 0; k < nb_subfr; k++ ) {
lag_counter = 0;
/* Calculate the energy for first lag */
basis_ptr = target_ptr - ( start_lag + matrix_ptr( Lag_range_ptr, k, 0, 2 ) );
energy = silk_energy_FLP( basis_ptr, sf_length ) + 1e-3;
silk_assert( energy >= 0.0 );
scratch_mem[lag_counter] = (silk_float)energy;
lag_counter++;
lag_diff = ( matrix_ptr( Lag_range_ptr, k, 1, 2 ) - matrix_ptr( Lag_range_ptr, k, 0, 2 ) + 1 );
for( i = 1; i < lag_diff; i++ ) {
/* remove part outside new window */
energy -= basis_ptr[sf_length - i] * (double)basis_ptr[sf_length - i];
silk_assert( energy >= 0.0 );
/* add part that comes into window */
energy += basis_ptr[ -i ] * (double)basis_ptr[ -i ];
silk_assert( energy >= 0.0 );
silk_assert( lag_counter < SCRATCH_SIZE );
scratch_mem[lag_counter] = (silk_float)energy;
lag_counter++;
}
delta = matrix_ptr( Lag_range_ptr, k, 0, 2 );
for( i = 0; i < nb_cbk_search; i++ ) {
/* Fill out the 3 dim array that stores the correlations for */
/* each code_book vector for each start lag */
idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta;
for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) {
silk_assert( idx + j < SCRATCH_SIZE );
silk_assert( idx + j < lag_counter );
energies_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ];
silk_assert( energies_st3[ k ][ i ][ j ] >= 0.0f );
}
}
target_ptr += sf_length;
}
}