⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lpc10enc.c

📁 本源码说明了声音压缩在工程中的使用
💻 C
📖 第 1 页 / 共 3 页
字号:
} /* 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 + -