📄 lpc10enc.c
字号:
} /* tbdm_ */
static void placev(long *osbuf, long osptr, long *obound, long *vwin)
{
/* Local variables */
int crit;
long i, q, osptr1, hrange, lrange;
/* Compute the placement range */
/* Parameter adjustments */
--osbuf;
/* Function Body */
/* Computing MAX */
lrange = max(vwin[3] + 1, LPC10_SAMPLES_PER_FRAME + 1);
hrange = 3 * LPC10_SAMPLES_PER_FRAME;
/* Compute OSPTR1, so the following code only looks at relevant onsets. */
for (osptr1 = osptr; osptr1 >= 1; --osptr1) {
if (osbuf[osptr1] <= hrange) {
break;
}
}
++osptr1;
/* Check for case 1 first (fast case): */
if (osptr1 <= 1 || osbuf[osptr1 - 1] < lrange) {
/* Computing MAX */
vwin[4] = max(vwin[3] + 1,307);
vwin[5] = vwin[4] + 156 - 1;
*obound = 0;
} else {
/* Search backward in OSBUF for first onset in range. */
/* This code relies on the above check being performed first. */
for (q = osptr1 - 1; q >= 1; --q) {
if (osbuf[q] < lrange) {
break;
}
}
++q;
/* Check for case 2 (placement before onset): */
/* Check for critical region exception: */
crit = FALSE;
for (i = q + 1; i <= (osptr1 - 1); ++i) {
if (osbuf[i] - osbuf[q] >= 90) {
crit = TRUE;
break;
}
}
/* Computing MAX */
if (! crit && osbuf[q] > max(2 * LPC10_SAMPLES_PER_FRAME, lrange + 90 - 1)) {
vwin[5] = osbuf[q] - 1;
/* Computing MAX */
vwin[4] = max(lrange, vwin[5] - 156 + 1);
*obound = 2;
/* Case 3 (placement after onset) */
} else {
vwin[4] = osbuf[q];
L110:
++q;
if (q >= osptr1) {
goto L120;
}
if (osbuf[q] > vwin[4] + 156) {
goto L120;
}
if (osbuf[q] < vwin[4] + 90) {
goto L110;
}
vwin[5] = osbuf[q] - 1;
*obound = 3;
return;
L120:
/* Computing MIN */
vwin[5] = min(vwin[4] + 156 - 1,hrange);
*obound = 1;
}
}
} /* placev_ */
static void placea(long ipitch, long *voibuf, long obound,
long *vwin, long *awin, long *ewin)
{
/* Local variables */
int allv, winv;
long i, j, k, l, hrange;
int ephase;
long lrange;
/* Function Body */
lrange = (3 - 2) * LPC10_SAMPLES_PER_FRAME + 1;
hrange = 3 * LPC10_SAMPLES_PER_FRAME;
allv = voibuf[3] == 1;
allv = allv && voibuf[4] == 1;
allv = allv && voibuf[5] == 1;
allv = allv && voibuf[6] == 1;
allv = allv && voibuf[7] == 1;
winv = voibuf[6] == 1 || voibuf[7] == 1;
if ((allv || winv) && (obound == 0)) {
/* APHASE: Phase synchronous window placement. */
/* Get minimum lower index of the window. */
i = (lrange + ipitch - 1 - awin[2]) / ipitch;
i *= ipitch;
i += awin[2];
/* L = the actual length of this frame's analysis window. */
l = 156;
/* Calculate the location where a perfectly centered window would star
t. */
k = (vwin[4] + vwin[5] + 1 - l) / 2;
/* Choose the actual location to be the pitch multiple closest to this
. */
awin[4] = i + lrintf((float) (k - i) / ipitch) * ipitch;
awin[5] = awin[4] + l - 1;
if (obound >= 2 && awin[5] > vwin[5]) {
awin[4] -= ipitch;
awin[5] -= ipitch;
}
/* Similarly for the left of the voicing window. */
if ((obound == 1 || obound == 3) && awin[4] < vwin[4]) {
awin[4] += ipitch;
awin[5] += ipitch;
}
/* If this placement puts the analysis window above HRANGE, then */
/* move it backward an integer number of pitch periods. */
while(awin[5] > hrange) {
awin[4] -= ipitch;
awin[5] -= ipitch;
}
/* Similarly if the placement puts the analysis window below LRANGE.
*/
while(awin[4] < lrange) {
awin[4] += ipitch;
awin[5] += ipitch;
}
/* Make Energy window be phase-synchronous. */
ephase = TRUE;
/* Case 3 */
} else {
awin[4] = vwin[4];
awin[5] = vwin[5];
ephase = FALSE;
}
j = (awin[5] - awin[4] + 1) / ipitch * ipitch;
if (j == 0 || ! winv) {
ewin[4] = vwin[4];
ewin[5] = vwin[5];
} else if (! ephase && obound == 2) {
ewin[4] = awin[5] - j + 1;
ewin[5] = awin[5];
} else {
ewin[4] = awin[4];
ewin[5] = awin[4] + j - 1;
}
} /* placea_ */
static void mload(long awinf, float *speech, float *phi, float *psi)
{
long c, i, r;
/* Function Body */
for (r = 0; r < 10; ++r) {
phi[r] = 0.f;
for (i = 10; i < awinf; ++i) {
phi[r] += speech[i - 1] * speech[i - r - 1];
}
}
/* Load last element of vector PSI */
psi[9] = 0.f;
for (i = 10; i < awinf; ++i) {
psi[9] += speech[i] * speech[i - 10];
}
/* End correct to get additional columns of PHI */
for (r = 1; r < 10; ++r) {
for (c = 1; c <= r; ++c) {
phi[r + (c) * 10] = phi[r + (c - 1) * 10 - 1] -
speech[awinf - r - 1] * speech[awinf - c - 1] +
speech[10 - r - 1] * speech[10 - c - 1];
}
}
/* End correct to get additional elements of PSI */
for (c = 0; c < 9; ++c) {
psi[c] = phi[c + 1] - speech[10] * speech[10 - 2 - c]
+ speech[awinf - 1] * speech[awinf - c - 2];
}
} /* mload_ */
static void rcchk(float *rc1f, float *rc2f)
{
/* Local variables */
long i;
/* Function Body */
for (i = 0; i < 10; ++i) {
if ((fabs(rc2f[i])) > .99f) {
goto L10;
}
}
return;
L10:
for (i = 0; i < 10; ++i) {
rc2f[i] = rc1f[i];
}
} /* rcchk_ */
static void dcbias(long len, float *speech, float *sigout)
{
/* Local variables */
float bias;
long i;
/* Function Body */
bias = 0.f;
for (i = 0; i < len; ++i) {
bias += speech[i];
}
bias /= len;
for (i = 0; i < len; ++i) {
*sigout++ = *speech++ - bias;
}
} /* dcbias_ */
static void preemp(float *inbuf, float *pebuf, long nsamp, float *z)
{
/* Local variables */
float temp;
long i;
/* Function Body */
for (i = 0; i< nsamp; ++i) {
temp = *inbuf - .9375f * *z;
*z = *inbuf++;
*pebuf++ = temp;
}
} /* preemp_ */
static void lpfilt(float *inbuf, float *lpbuf, long nsamp)
{
/* Local variables */
long j;
/* Function Body */
lpbuf = &lpbuf[312 - nsamp];
for (j = 312 - nsamp; j < 312; ++j) {
*lpbuf++ = (inbuf[j] + inbuf[j - 30]) * -.0097201988f
+ (inbuf[j - 1] + inbuf[j - 29]) * -.0105179986f
+ (inbuf[j - 2] + inbuf[j - 28]) * -.0083479648f
+ (inbuf[j - 3] + inbuf[j - 27]) * 5.860774e-4f
+ (inbuf[j - 4] + inbuf[j - 26]) * .0130892089f
+ (inbuf[j - 5] + inbuf[j - 25]) * .0217052232f
+ (inbuf[j - 6] + inbuf[j - 24]) * .0184161253f
+ (inbuf[j - 7] + inbuf[j - 23]) * 3.39723e-4f
+ (inbuf[j - 8] + inbuf[j - 22]) * -.0260797087f
+ (inbuf[j - 9] + inbuf[j - 21]) * -.0455563702f
+ (inbuf[j - 10] + inbuf[j - 20]) * -.040306855f
+ (inbuf[j - 11] + inbuf[j - 19]) * 5.029835e-4f
+ (inbuf[j - 12] + inbuf[j - 18]) * .0729262903f
+ (inbuf[j - 13] + inbuf[j - 17]) * .1572008878f
+ (inbuf[j - 14] + inbuf[j - 16]) * .2247288674f
+ inbuf[j - 15] * .250535965f;
}
} /* lpfilt_ */
static void ivfilt(float *lpbuf, float *ivbuf, long nsamp, float *ivrc)
{
/* Local variables */
long i, j, k;
float r[3], pc1, pc2;
/* Function Body */
for (i = 0; i < 3; ++i) {
r[i] = 0.f;
k = (i) << 2;
for (j = ((i + 1) << 2) + 312 - nsamp - 1; j < 312; j += 2) {
r[i] += lpbuf[j] * lpbuf[j - k];
}
}
/* Calculate predictor coefficients */
pc1 = 0.f;
pc2 = 0.f;
ivrc[0] = 0.f;
ivrc[1] = 0.f;
if (r[0] > 1e-10f) {
ivrc[0] = r[1] / r[0];
ivrc[1] = (r[2] - ivrc[0] * r[1]) / (r[0] - ivrc[0] * r[1]);
pc1 = ivrc[0] - ivrc[0] * ivrc[1];
pc2 = ivrc[1];
}
/* Inverse filter LPBUF into IVBUF */
for (i = 312 - nsamp; i < 312; ++i) {
ivbuf[i] = lpbuf[i] - pc1 * lpbuf[i - 4] - pc2 * lpbuf[i - 8];
}
} /* ivfilt_ */
static void invert(float *phi, float *psi, float *rc)
{
/* Local variables */
float save;
long i, j, k;
float v[100] /* was [10][10] */;
/* Function Body */
for (j = 0; j < 10; ++j) {
for (i = j; i < 10; ++i) {
v[i + j * 10] = phi[i + j * 10];
}
for (k = 0; k < j; ++k) {
save = v[j + k * 10] * v[k + k * 10];
for (i = j; i < 10; ++i) {
v[i + j * 10] -= v[i + k * 10] * save;
}
}
/* Compute intermediate results, which are similar to RC's */
if ((fabs(v[j + j * 10])) < 1e-10f) {
goto L100;
}
rc[j] = psi[j];
for (k = 0; k < j; ++k) {
rc[j] -= rc[k] * v[j + k * 10];
}
v[j + j * 10] = 1.f / v[j + j * 10];
rc[j] *= v[j + j * 10];
rc[j] = max(min(rc[j],.999f),-.999f);
}
return;
/* Zero out higher order RC's if algorithm terminated early */
L100:
for (i = j; i < 10; ++i) {
rc[i] = 0.f;
}
} /* invert_ */
static void energy(long len, float *speech, float *rms)
{
/* Local variables */
long i;
/* Function Body */
*rms = 0.f;
for (i = 0; i < len; ++i) {
*rms += speech[i] * speech[i];
}
*rms = (float)sqrt(*rms / len);
} /* energy_ */
static void dyptrk(float *amdf, long *minptr, long *voice, long *pitch,
long *midx, lpc10_encoder_state *st)
{
/* Initialized data */
float *s;
long *p;
long *ipoint;
float *alphax;
/* Local variables */
long pbar;
float sbar;
long path[2], iptr, i, j;
float alpha, minsc, maxsc;
s = &(st->s[0]);
p = &(st->p[0]);
ipoint = &(st->ipoint);
alphax = &(st->alphax);
/* Parameter adjustments */
if (amdf) {
--amdf;
}
/* Function Body */
if (*voice == 1) {
*alphax = *alphax * .75f + amdf[*minptr] / 2.f;
} else {
*alphax *= .984375f;
}
alpha = *alphax / 16;
if (*voice == 0 && *alphax < 128.f) {
alpha = 8.f;
}
/* SEESAW: Construct a pitch pointer array and intermediate winner function*/
/* Left to right pass: */
iptr = *ipoint + 1;
p[iptr * 60 - 60] = 1;
i = 1;
pbar = 1;
sbar = s[0];
for (i = 1; i <= 60; ++i) {
sbar += alpha;
if (sbar < s[i - 1]) {
s[i - 1] = sbar;
p[i + iptr * 60 - 61] = pbar;
} else {
sbar = s[i - 1];
p[i + iptr * 60 - 61] = i;
pbar = i;
}
}
/* Right to left pass: */
i = pbar - 1;
sbar = s[i];
while(i >= 1) {
sbar += alpha;
if (sbar < s[i - 1]) {
s[i - 1] = sbar;
p[i + iptr * 60 - 61] = pbar;
} else {
pbar = p[i + iptr * 60 - 61];
i = pbar;
sbar = s[i - 1];
}
--i;
}
/* Update S using AMDF */
/* Find maximum, minimum, and location of minimum */
s[0] += amdf[1] / 2;
minsc = s[0];
maxsc = minsc;
*midx = 1;
for (i = 2; i <= 60; ++i) {
s[i - 1] += amdf[i] / 2;
if (s[i - 1] > maxsc) {
maxsc = s[i - 1];
}
if (s[i - 1] < minsc) {
*midx = i;
minsc = s[i - 1];
}
}
/* Subtract MINSC from S to prevent overflow */
for (i = 1; i <= 60; ++i) {
s[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[*midx - i - 1] < maxsc / 4) {
j = i;
}
}
}
*midx -= j;
/* TRACE: look back two frames to find minimum cost pitch estimate */
j = *ipoint;
*pitch = *midx;
for (i = 1; i <= 2; ++i) {
j = j % 2 + 1;
*pitch = p[*pitch + j * 60 - 61];
path[i - 1] = *pitch;
}
*ipoint = (*ipoint + 1) % 2;
} /* dyptrk_ */
static void onset(float *pebuf, long *osbuf, long *osptr, lpc10_encoder_state *st)
{
/* Initialized data */
float n;
float d;
float *l2buf;
float *l2sum1;
long *l2ptr1;
long *l2ptr2;
int *hyst;
/* System generated locals */
float temp;
/* Local variables */
long i;
long *lasti;
float l2sum2;
float *fpc;
n = st->n;
d = st->d;
fpc = &(st->fpc);
l2buf = &(st->l2buf[0]);
l2sum1 = &(st->l2sum1);
l2ptr1 = &(st->l2ptr1);
l2ptr2 = &(st->l2ptr2);
lasti = &(st->lasti);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -