www.pudn.com > lpc.zip > dyptrk_i.c
/**********************************************************************
*
* DYPTRK Version 52
*
**********************************************************************
*
* Dynamic Pitch Tracker
*
* Inputs:
* AMDF - Average Magnitude Difference Function array
* LTAU - Number of lags in AMDF
* MINPTR - Location of minimum AMDF value
* VOICE - Voicing decision
* Outputs:
* PITCH - Smoothed pitch value, 2 frames delayed
* MIDX - Initial estimate of current frame pitch
* Compile time constant:
* DEPTH - Number of frames to trace back
*/
#include "lpcdefs.h"
#include "ourstuff.h"
extern int_type s_i[60];
extern int_type p_i[60][2];
dyptrk_i( amdf, minptr, voice, pitch, midx )
int_type amdf[];
int_type minptr, voice, *pitch, *midx;
{
int_type sbar, minsc, maxsc, alpha, temp;
int_type depth=2;
int_type pbar, i, j, iptr, path[2];
static int_type alphax, ipoint=0;
/* Calculate the confidence factor ALPHA, used as a threshold slope in
* SEESAW. If unvoiced, set high slope so that every point in P array
* is marked as a potential pitch frequency. A scaled up version (ALPHAX)
* is used to maintain arithmetic precision. */
if( voice == 1 )
alphax = (((long_type)3072*(long_type)alphax)>>12) + (amdf[minptr]>>1);
else
alphax = ((long_type)4032*(long_type)alphax)>>12;
alpha = alphax>>4;
if( voice == 0 && alphax < 128 ) alpha = 8;
/* SEESAW: Construct a pitch pointer array and intermediate winner function
* Left to right pass: */
iptr = ipoint+1;
p_i[0][iptr-1] = 1;
i = 1;
pbar = 1;
temp = s_i[0]>>1;
for(i=1;i<=LTAU;i++) {
temp = (alpha>>1) + temp;
sbar = (temp >= 16383)?(32767):(temp<<1);
/* printf("i: %d temp:%d sbar_i:%d alpha:%d s[i-1]:%d\n", i,temp, sbar, alpha, s_i[i-1]);*/
if (sbar < s_i[i-1]) {
s_i[i-1] = sbar;
p_i[i-1][iptr-1] = pbar;
}
else {
temp = s_i[i-1]>>1;
p_i[i-1][iptr-1] = i;
pbar = i;
}
}
/* Right to left pass: */
i = pbar-1;
temp = s_i[i]>>1;
while (i>=1) {
temp = (alpha>>1) + temp;
sbar = (temp >= 16383)?(32767):(temp<<1);
/* printf("i:%d temp:%d sbar_i:%d alpha:%d s_i[i-1]:%d\n",i,temp, sbar, alpha, s_i[i-1]);*/
if (sbar < s_i[i-1]) {
s_i[i-1] = sbar;
p_i[i-1][iptr-1] = pbar;
}
else {
pbar = p_i[i-1][iptr-1];
i = pbar;
temp = s_i[i-1]>>1;
}
i--;
}
/* Update S using AMDF
* Find maximum, minimum, and location of minimum */
temp = (amdf[1]>>2) + (s_i[0]>>1);
s_i[0] = (temp >= 16383)?(32767):(temp<<1);
minsc = s_i[0];
maxsc = minsc;
*midx = 1;
for(i=2;i<=LTAU;i++) {
temp = (s_i[i-1]>>1) + (amdf[i]>>2);
s_i[i-1] = (temp >= 16383)?(32767):(temp<<1);
/* printf("i:%d temp:%d s_i[i-1]:%d minsc:%d\n",i,temp,s_i[i-1],minsc);*/
if(s_i[i-1] > maxsc) maxsc = s_i[i-1];
if(s_i[i-1] < minsc) *midx = i;
if(s_i[i-1] < minsc) minsc = s_i[i-1];
}
/* Subtract MINSC from S to prevent overflow */
for(i=1;i<=LTAU;i++) {
s_i[i-1] -= minsc;
/* printf("i:%d s_i:%d minsc:%d\n",i,s_i[i-1], minsc);*/
}
maxsc -= minsc;
/* Use higher octave pitch if significant null there */
j = 0;
for(i=20;i<=40;i+=10)
if (*midx > i)
if (s_i[*midx-i-1] < (maxsc>>2)) j = i;
*midx -= j;
/* TRACE: look back two frames to find minimum cost pitch estimate */
j = ipoint;
*pitch = *midx;
for(i=1;i<=depth;i++) {
j = j - depth* (j/depth) +1;
*pitch = p_i[*pitch-1][j-1];
path[i-1] = *pitch;
}
temp = ipoint + depth -1;
ipoint = temp - depth*(temp/depth);
/*printf("midx:%d pitch:%d\n",*midx, *pitch);*/
}