📄 pitch_fr.c
字号:
/*********************************************************************************** GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001* R99 Version 3.3.0 * REL-4 Version 4.1.0 *********************************************************************************** File : pitch_fr.c* Purpose : Find the pitch period with 1/3 or 1/6 subsample* : resolution (closed loop).**********************************************************************************//********************************************************************************** MODULE INCLUDE FILE AND VERSION ID*********************************************************************************/#include "pitch_fr.h"const char pitch_fr_id[] = "@(#)$Id $" pitch_fr_h;/********************************************************************************** INCLUDE FILES*********************************************************************************/#include <stdlib.h>#include <stdio.h>#include "typedef.h"#include "basic_op.h"#include "oper_32b.h"#include "count.h"#include "cnst.h"#include "enc_lag3.h"#include "enc_lag6.h"#include "inter_36.h"#include "inv_sqrt.h"#include "convolve.h"/********************************************************************************** LOCAL VARIABLES AND TABLES*********************************************************************************//* * mode dependent parameters used in Pitch_fr() * Note: order of MRxx in 'enum Mode' is important! */static const struct { Word16 max_frac_lag; /* lag up to which fractional lags are used */ Word16 flag3; /* enable 1/3 instead of 1/6 fract. resolution */ Word16 first_frac; /* first fractional to check */ Word16 last_frac; /* last fractional to check */ Word16 delta_int_low; /* integer lag below TO to start search from */ Word16 delta_int_range; /* integer range around T0 */ Word16 delta_frc_low; /* fractional below T0 */ Word16 delta_frc_range; /* fractional range around T0 */ Word16 pit_min; /* minimum pitch */} mode_dep_parm[N_MODES] = { /* MR475 */ { 84, 1, -2, 2, 5, 10, 5, 9, PIT_MIN }, /* MR515 */ { 84, 1, -2, 2, 5, 10, 5, 9, PIT_MIN }, /* MR59 */ { 84, 1, -2, 2, 3, 6, 5, 9, PIT_MIN }, /* MR67 */ { 84, 1, -2, 2, 3, 6, 5, 9, PIT_MIN }, /* MR74 */ { 84, 1, -2, 2, 3, 6, 5, 9, PIT_MIN }, /* MR795 */ { 84, 1, -2, 2, 3, 6, 10, 19, PIT_MIN }, /* MR102 */ { 84, 1, -2, 2, 3, 6, 5, 9, PIT_MIN }, /* MR122 */ { 94, 0, -3, 3, 3, 6, 5, 9, PIT_MIN_MR122 }};/********************************************************************************** LOCAL PROGRAM CODE*********************************************************************************//************************************************************************* * * FUNCTION: Norm_Corr() * * PURPOSE: Find the normalized correlation between the target vector * and the filtered past excitation. * * DESCRIPTION: * The normalized correlation is given by the correlation between the * target and filtered past excitation divided by the square root of * the energy of filtered excitation. * corr[k] = <x[], y_k[]>/sqrt(y_k[],y_k[]) * where x[] is the target vector and y_k[] is the filtered past * excitation at delay k. * *************************************************************************/static void Norm_Corr (Word16 exc[], Word16 xn[], Word16 h[], Word16 L_subfr, Word16 t_min, Word16 t_max, Word16 corr_norm[]){ Word16 i, j, k; Word16 corr_h, corr_l, norm_h, norm_l; Word32 s; /* Usally dynamic allocation of (L_subfr) */ Word16 excf[L_SUBFR]; Word16 scaling, h_fac, *s_excf, scaled_excf[L_SUBFR]; k = -t_min; move16 (); /* compute the filtered excitation for the first delay t_min */ Convolve (&exc[k], h, excf, L_subfr); /* scale "excf[]" to avoid overflow */ for (j = 0; j < L_subfr; j++) { scaled_excf[j] = shr (excf[j], 2); move16 (); } /* Compute 1/sqrt(energy of excf[]) */ s = 0; move32 (); for (j = 0; j < L_subfr; j++) { s = L_mac (s, excf[j], excf[j]); } test (); if (L_sub (s, 67108864L) <= 0) { /* if (s <= 2^26) */ s_excf = excf; move16 (); h_fac = 15 - 12; move16 (); scaling = 0; move16 (); } else { /* "excf[]" is divided by 2 */ s_excf = scaled_excf; move16 (); h_fac = 15 - 12 - 2; move16 (); scaling = 2; move16 (); } /* loop for every possible period */ for (i = t_min; i <= t_max; i++) { /* Compute 1/sqrt(energy of excf[]) */ s = 0; move32 (); for (j = 0; j < L_subfr; j++) { s = L_mac (s, s_excf[j], s_excf[j]); } s = Inv_sqrt (s); L_Extract (s, &norm_h, &norm_l); /* Compute correlation between xn[] and excf[] */ s = 0; move32 (); for (j = 0; j < L_subfr; j++) { s = L_mac (s, xn[j], s_excf[j]); } L_Extract (s, &corr_h, &corr_l); /* Normalize correlation = correlation * (1/sqrt(energy)) */ s = Mpy_32 (corr_h, corr_l, norm_h, norm_l); corr_norm[i] = extract_h (L_shl (s, 16)); move16 (); /* modify the filtered excitation excf[] for the next iteration */ test (); if (sub (i, t_max) != 0) { k--; for (j = L_subfr - 1; j > 0; j--) { s = L_mult (exc[k], h[j]); s = L_shl (s, h_fac); s_excf[j] = add (extract_h (s), s_excf[j - 1]); move16 (); } s_excf[0] = shr (exc[k], scaling); move16 (); } } return;}/************************************************************************* * * FUNCTION: searchFrac() * * PURPOSE: Find fractional pitch * * DESCRIPTION: * The function interpolates the normalized correlation at the * fractional positions around lag T0. The position at which the * interpolation function reaches its maximum is the fractional pitch. * Starting point of the search is frac, end point is last_frac. * frac is overwritten with the fractional pitch. * *************************************************************************/static void searchFrac ( Word16 *lag, /* i/o : integer pitch */ Word16 *frac, /* i/o : start point of search - fractional pitch */ Word16 last_frac, /* i : endpoint of search */ Word16 corr[], /* i : normalized correlation */ Word16 flag3 /* i : subsample resolution (3: =1 / 6: =0) */){ Word16 i; Word16 max; Word16 corr_int; /* Test the fractions around T0 and choose the one which maximizes */ /* the interpolated normalized correlation. */ max = Interpol_3or6 (&corr[*lag], *frac, flag3); move16 (); /* function result */ for (i = add (*frac, 1); i <= last_frac; i++) { corr_int = Interpol_3or6 (&corr[*lag], i, flag3); move16 (); test (); if (sub (corr_int, max) > 0) { max = corr_int; move16 (); *frac = i; move16 (); } } test(); if (flag3 == 0) { /* Limit the fraction value in the interval [-2,-1,0,1,2,3] */ test (); if (sub (*frac, -3) == 0) { *frac = 3; move16 (); *lag = sub (*lag, 1); } } else { /* limit the fraction value between -1 and 1 */ test (); if (sub (*frac, -2) == 0) { *frac = 1; move16 (); *lag = sub (*lag, 1); } test (); if (sub (*frac, 2) == 0) { *frac = -1; move16 (); *lag = add (*lag, 1); } }}/************************************************************************* * * FUNCTION: getRange() * * PURPOSE: Sets range around open-loop pitch or integer pitch of last subframe * * DESCRIPTION: * Takes integer pitch T0 and calculates a range around it with * t0_min = T0-delta_low and t0_max = (T0-delta_low) + delta_range * t0_min and t0_max are bounded by pitmin and pitmax * *************************************************************************/static void getRange ( Word16 T0, /* i : integer pitch */ Word16 delta_low, /* i : search start offset */ Word16 delta_range, /* i : search range */ Word16 pitmin, /* i : minimum pitch */ Word16 pitmax, /* i : maximum pitch */ Word16 *t0_min, /* o : search range minimum */ Word16 *t0_max) /* o : search range maximum */{ *t0_min = sub(T0, delta_low); test (); if (sub(*t0_min, pitmin) < 0) { *t0_min = pitmin; move16(); } *t0_max = add(*t0_min, delta_range); test (); if (sub(*t0_max, pitmax) > 0) { *t0_max = pitmax; move16(); *t0_min = sub(*t0_max, delta_range); }}/********************************************************************************** PUBLIC PROGRAM CODE*********************************************************************************//*************************************************************************** Function: Pitch_fr_init* Purpose: Allocates state memory and initializes state memory****************************************************************************/int Pitch_fr_init (Pitch_frState **state){ Pitch_frState* s; if (state == (Pitch_frState **) NULL){ fprintf(stderr, "Pitch_fr_init: invalid parameter\n"); return -1; } *state = NULL; /* allocate memory */ if ((s= (Pitch_frState *) malloc(sizeof(Pitch_frState))) == NULL){ fprintf(stderr, "Pitch_fr_init: can not malloc state structure\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -