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

📄 lpc10enc.c

📁 本源码说明了声音压缩在工程中的使用
💻 C
📖 第 1 页 / 共 3 页
字号:
    hyst = &(st->hyst);
    
    /* Parameter adjustments */
    if (pebuf) {
        pebuf -= 181;
    }
    
    /* Function Body */
    
    if (*hyst) {
        *lasti -= LPC10_SAMPLES_PER_FRAME;
    }
    for (i = 720 - LPC10_SAMPLES_PER_FRAME + 1; i <= 720; ++i) {
    /*   Compute FPC; Use old FPC on divide by zero; Clamp FPC to +/- 1. */
        n = (pebuf[i] * pebuf[i - 1] + n * 63.f) * 0.015625f;
        /* Computing 2nd power */
        temp = pebuf[i - 1];
        d = (temp * temp + d * 63.f) * 0.015625f;
        if (d != 0.f) {
            if(n > d || n < -(d)){
                *fpc = (n<0.0f)?-1.0f:1.0f;
            } else {
                *fpc = n / d;
            }
        }
        
        l2sum2 = l2buf[*l2ptr1 - 1];
        *l2sum1 = *l2sum1 - l2buf[*l2ptr2 - 1] + *fpc;
        l2buf[*l2ptr2 - 1] = *l2sum1;
        l2buf[*l2ptr1 - 1] = *fpc;
        *l2ptr1 = *l2ptr1 % 16 + 1;
        *l2ptr2 = *l2ptr2 % 16 + 1;
        temp = *l2sum1 - l2sum2;
        if (temp > 1.7f || temp < -1.7f) {
            if (! (*hyst)) {
                /*   Ignore if buffer full */
                if (*osptr < 10) {
                    osbuf[*osptr] = i - 9;
                    ++(*osptr);
                }
                *hyst = TRUE;
            }
            *lasti = i;
            /*       After one onset detection, at least OSHYST sample times must go */
            /*       by before another is allowed to occur. */
        } else if ((*hyst) && i - *lasti >= 10) {
            *hyst = FALSE;
        }
    }
    st->n = n;
    st->d = d;
} /* onset_ */

static void analys(float *speech, long *voice, long 
            *pitch, float *rms, float *rc, lpc10_encoder_state *st)
{
    /* Initialized data */
    
    static long tau[60] = { 20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,
        35,36,37,38,39,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72,
        74,76,78,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,
        140,144,148,152,156 };
    
    /* System generated locals */
    long i1;
    
    /* Local variables */
    float amdf[60];
    long half;
    float abuf[156];
    float bias;
    long *awin;
    long midx, ewin[6]	/* was [2][3] */;
    float ivrc[2], temp;
    long *vwin;
    long i, j, lanal;
    float *inbuf, *pebuf;
    float *lpbuf, *ivbuf;
    float *rcbuf;
    long *osptr;
    long *osbuf;
    long ipitch;
    long *obound;
    long *voibuf;
    long mintau;
    float *rmsbuf;
    long minptr, maxptr;
    float phi[100]	/* was [10][10] */, psi[10];
    
    inbuf = &(st->inbuf[0]);
    pebuf = &(st->pebuf[0]);
    lpbuf = &(st->lpbuf[0]);
    ivbuf = &(st->ivbuf[0]);
    bias = st->bias;
    osbuf = &(st->osbuf[0]);
    osptr = &(st->osptr);
    obound = &(st->obound[0]);
    vwin = &(st->vwin[0]);
    awin = &(st->awin[0]);
    voibuf = &(st->voibuf[0]);
    rmsbuf = &(st->rmsbuf[0]);
    rcbuf = &(st->rcbuf[0]);
    
    i1 = 720 - LPC10_SAMPLES_PER_FRAME;
    for (i = LPC10_SAMPLES_PER_FRAME; i < i1; ++i) {
        inbuf[i - LPC10_SAMPLES_PER_FRAME] = inbuf[i];
        pebuf[i - LPC10_SAMPLES_PER_FRAME] = pebuf[i];
    }
    i1 = 540 - LPC10_SAMPLES_PER_FRAME - 229;
    for (i = 0; i <= i1; ++i) {
        ivbuf[i] = ivbuf[LPC10_SAMPLES_PER_FRAME + i];
    }
    i1 = 720 - LPC10_SAMPLES_PER_FRAME - 25;
    for (i = 0; i <= i1; ++i) {
        lpbuf[i] = lpbuf[LPC10_SAMPLES_PER_FRAME + i];
    }
    j = 0;
    for (i = 0; i < *osptr; ++i) {
        if (osbuf[i] > LPC10_SAMPLES_PER_FRAME) {
            osbuf[j] = osbuf[i] - LPC10_SAMPLES_PER_FRAME;
            ++j;
        }
    }
    *osptr = j;
    voibuf[0] = voibuf[2];
    voibuf[1] = voibuf[3];
    for (i = 1; i <= 2; ++i) {
        vwin[(i << 1) - 2] = vwin[((i + 1) << 1) - 2] - LPC10_SAMPLES_PER_FRAME;
        vwin[(i << 1) - 1] = vwin[((i + 1) << 1) - 1] - LPC10_SAMPLES_PER_FRAME;
        awin[(i << 1) - 2] = awin[((i + 1) << 1) - 2] - LPC10_SAMPLES_PER_FRAME;
        awin[(i << 1) - 1] = awin[((i + 1) << 1) - 1] - LPC10_SAMPLES_PER_FRAME;
        obound[i - 1] = obound[i];
        voibuf[i << 1] = voibuf[(i + 1) << 1];
        voibuf[(i << 1) + 1] = voibuf[((i + 1) << 1) + 1];
        rmsbuf[i - 1] = rmsbuf[i];
        for (j = 1; j <= 10; ++j) {
            rcbuf[j + i * 10 - 11] = rcbuf[j + (i + 1) * 10 - 11];
        }
    }
    temp = 0.f;
    for (i = 0; i < LPC10_SAMPLES_PER_FRAME; ++i) {
        inbuf[720 - LPC10_SAMPLES_PER_FRAME + i - 180] = speech[i] * 4096.f - bias;
        temp += inbuf[720 - LPC10_SAMPLES_PER_FRAME + i - 180];
    }
    if (temp > (float) LPC10_SAMPLES_PER_FRAME) {
        st->bias += 1;
    }
    if (temp < (float) (-LPC10_SAMPLES_PER_FRAME)) {
        st->bias += -1;
    }
    /*   Place Voicing Window */
    i = 720 - LPC10_SAMPLES_PER_FRAME;
    preemp(&inbuf[i - 180], &pebuf[i - 180], LPC10_SAMPLES_PER_FRAME, &(st->zpre));
    onset(pebuf, osbuf, osptr, st);
    
    placev(osbuf, *osptr, &obound[2], vwin);
    lpfilt(&inbuf[228], &lpbuf[384], LPC10_SAMPLES_PER_FRAME);
    ivfilt(&lpbuf[204], ivbuf, LPC10_SAMPLES_PER_FRAME, ivrc);
    tbdm(ivbuf, tau, amdf, &minptr, &maxptr, &mintau);
    /*   voicing decisions. */
    for (half = 1; half <= 2; ++half) {
        voicin(&vwin[4], inbuf, lpbuf, half, &amdf[minptr - 1],
                &amdf[maxptr - 1], &mintau, ivrc, obound, voibuf, st);
    }
    dyptrk(amdf, &minptr, &voibuf[7], pitch, &midx, st);
    ipitch = tau[midx - 1];
    placea(ipitch, voibuf, obound[2], vwin, awin, ewin);
    lanal = awin[5] + 1 - awin[4];
    dcbias(lanal, &pebuf[awin[4] - 181], abuf);
    i1 = ewin[5] - ewin[4] + 1;
    energy(i1, &abuf[ewin[4] - awin[4]], &rmsbuf[2]);
    /*   Matrix load and invert, check RC's for stability */
    mload(lanal, abuf, phi, psi);
    invert(phi, psi, &rcbuf[20]);
    rcchk(&rcbuf[10], &rcbuf[20]);
    /*   Set return parameters */
    voice[0] = voibuf[2];
    voice[1] = voibuf[3];
    *rms = rmsbuf[0];
    for (i = 0; i < 10; ++i) {
        rc[i] = rcbuf[i];
    }
} /* analys_ */

static void encode(long *voice, long pitch, float rms, float *rc, long *ipitch,
            long *irms, long *irc)
{
    /* Local variables */
    long idel, nbit, i, j, i2, i3, mrk;
    
    /* Function Body */
    /*  Scale RMS and RC's to integers */
    *irms = lrintf(rms);
    for (i = 0; i < 10; ++i) {
        irc[i] = lrintf(rc[i] * 32768.f);
    }
    /*  Encode pitch and voicing */
    if (voice[0] != 0 && voice[1] != 0) {
        *ipitch = entau[pitch - 1];
    } else {
        *ipitch = (voice[0] << 1) + voice[1];
    }
    /*  Encode RMS by binary table search */
    j = 32;
    idel = 16;
    *irms = min(*irms,1023);
    while(idel > 0) {
        if (*irms > rmst[j - 1]) {
            j -= idel;
        }
        if (*irms < rmst[j - 1]) {
            j += idel;
        }
        idel /= 2;
    }
    if (*irms > rmst[j - 1]) {
        --j;
    }
    *irms = 31 - j / 2;
    /*  Encode RC(1) and (2) as log-area-ratios */
    for (i = 0; i < 2; ++i) {
        i2 = irc[i];
        mrk = 0;
        if (i2 < 0) {
            i2 = -i2;
            mrk = 1;
        }
        i2 /= 512;
        i2 = min(i2,63);
        i2 = entab6[i2];
        if (mrk != 0) {
            i2 = -i2;
        }
        irc[i] = i2;
    }
    /*  Encode RC(3) - (10) linearly, remove bias then scale */
    for (i = 2; i < 10; ++i) {
        i2 = irc[i] / 2;
        i2 = lrintf((i2 + enadd[10 + 1 - i - 2]) * enscl[10 + 1 - i - 2]);
        /* Computing MIN */
        i2 = min(max(i2,-127),127);
        nbit = enbits[10 + 1 - i - 2];
        i3 = 0;
        if (i2 < 0) {
            i3 = -1;
        }
        i2 = i2 / (2 << (nbit-1));
        if (i3 == -1) {
            --i2;
        }
        irc[i] = i2;
    }
/*    printf("%d,\t%d,\t%d,\t%d,\t%d,\t%d,\t%d,\t%d,\t%d,\t%d,\t%d,\t%d\n",irc[0],irc[1],irc[2],irc[3],irc[4],irc[5]
        ,irc[6],irc[7],irc[8],irc[9], *ipitch, *irms);
*/
} /* encode_ */

static void hp100(float *speech, long end, lpc10_encoder_state *st)
{
    float z11;
    float z21;
    float z12;
    float z22;

    /* Local variables */
    long i;
    float si, err;

    /* Function Body */

    z11 = st->z11;
    z21 = st->z21;
    z12 = st->z12;
    z22 = st->z22;

    for (i = 0; i<end; ++i) {
	    err = *speech + z11 * 1.859076f - z21 * .8648249f;
	    si = err - z11 * 2.f + z21;
	    z21 = z11;
	    z11 = err;
	    err = si + z12 * 1.935715f - z22 * .9417004f;
	    si = err - z12 * 2.f + z22;
	    z22 = z12;
	    z12 = err;
	    *speech++ = si * .902428f;
    }

    st->z11 = z11;
    st->z21 = z21;
    st->z12 = z12;
    st->z22 = z22;

} /* hp100_ */

static void pack(long value, long bits, long *array, long *pointer)
{
    int i;
    
    for (i = 0; i < bits; (*pointer)++, i++)
        array[*pointer] = (long)((value & 1 << i) >> i);
}

static long chanwr(long ipitv, long irms, long *irc, long *ibits, int vbr)
{
    long i;
    long pointer;

    pointer = 0;

    if(vbr == TRUE)
    {
        /* test for silence */
        if(irms < 10) {
            pack(127, 7, ibits, &pointer);
            return 1;
        }
    }

    pack(ipitv, 7, ibits, &pointer);
    pack(irms, 5, ibits, &pointer);

    for (i = 0; i < 4; ++i) {
        pack(irc[i], lpcbits[i], ibits, &pointer);
    }
    /* test for unvoiced */
    if((ipitv != 0 && ipitv != 126) || vbr == FALSE) {
        for (i = 4; i < 10; ++i) {
            pack(irc[i], lpcbits[i], ibits, &pointer);
        }
        return 7;
    }
    return 4;
}

int lpc10_encode_int(short *in, unsigned char *out, lpc10_encoder_state *st, int vbr)
{
    float   speech[LPC10_SAMPLES_PER_FRAME];
    float   *sp = speech;
    long bits[LPC10_BITS_IN_COMPRESSED_FRAME];
    int     i;
    long irms, voice[2], pitch, ipitv;
    float rc[10];
    long irc[10];
    float rms;
    long framesize;

    /* convert sound from short to float */
    for(i=LPC10_SAMPLES_PER_FRAME;i--;)
    {
        *sp++ = (float)(*in++ / 32768.0f);
    }

    /* encode it */
    memset(bits, 0, sizeof(bits));
    hp100(speech, LPC10_SAMPLES_PER_FRAME, st);
    analys(speech, voice, &pitch, &rms, rc, st);
    encode(voice, pitch, rms, rc, &ipitv, &irms, irc);
    framesize = chanwr(ipitv, irms, irc, bits, vbr);

    /* pack the bits */
    memset(out, 0, 7);
	for (i = 0; i < 54; i++)
    {
        out[i >> 3] |= ((bits[i] != 0)? 1 : 0) << (i & 7);
	}

    /* return number of bytes encoded*/
    return framesize;
}

int lpc10_encode(short *in, unsigned char *out, lpc10_encoder_state *st)
{
    return lpc10_encode_int(in, out, st, FALSE);

}

int vbr_lpc10_encode(short *in, unsigned char *out, lpc10_encoder_state *st)
{
    return lpc10_encode_int(in, out, st, TRUE);

}

/* Allocate memory for, and initialize, the state that needs to be
   kept from encoding one frame to the next for a single
   LPC-10-compressed audio stream.  Return 0 if malloc fails,
   otherwise return pointer to new structure. */

lpc10_encoder_state *create_lpc10_encoder_state(void)
{
    lpc10_encoder_state *st;

    st = (lpc10_encoder_state *)malloc((unsigned) sizeof (lpc10_encoder_state));
    return (st);
}

void init_lpc10_encoder_state(lpc10_encoder_state *st)
{
    int i;

    /* State used only by function hp100 */
    st->z11 = 0.0f;
    st->z21 = 0.0f;
    st->z12 = 0.0f;
    st->z22 = 0.0f;
    
    /* State used by function analys */
    for (i = 0; i < 540; i++) {
	st->inbuf[i] = 0.0f;
	st->pebuf[i] = 0.0f;
    }
    for (i = 0; i < 696; i++) {
	st->lpbuf[i] = 0.0f;
    }
    for (i = 0; i < 312; i++) {
	st->ivbuf[i] = 0.0f;
    }
    st->bias = 0.0f;
    st->osptr = 0;
    for (i = 0; i < 3; i++) {
	st->obound[i] = 0;
    }
    st->vwin[4] = 307;
    st->vwin[5] = 462;
    st->awin[4] = 307;
    st->awin[5] = 462;
    for (i = 0; i < 8; i++) {
	st->voibuf[i] = 0;
    }
    for (i = 0; i < 3; i++) {
	st->rmsbuf[i] = 0.0f;
    }
    for (i = 0; i < 30; i++) {
	st->rcbuf[i] = 0.0f;
    }
    st->zpre = 0.0f;


    /* State used by function onset */
    st->n = 0.0f;
    st->d = 1.0f;
    for (i = 0; i < 16; i++) {
	st->l2buf[i] = 0.0f;
    }
    st->l2sum1 = 0.0f;
    st->l2ptr1 = 1;
    st->l2ptr2 = 9;
    st->hyst = FALSE;

    /* State used by function voicin */
    st->dither = 20.0f;
    st->maxmin = 0.0f;
    for (i = 0; i < 6; i++) {
	st->voice[i] = 0.0f;
    }
    st->lbve = 3000;
    st->fbve = 3000;
    st->fbue = 187;
    st->ofbue = 187;
    st->sfbue = 187;
    st->lbue = 93;
    st->olbue = 93;
    st->slbue = 93;
    st->snr = (float) (st->fbve / st->fbue << 6);

    /* State used by function dyptrk */
    for (i = 0; i < 60; i++) {
	st->s[i] = 0.0f;
    }
    for (i = 0; i < 120; i++) {
	st->p[i] = 0;
    }
    st->ipoint = 0;
    st->alphax = 0.0f;

    /* State used by function chanwr */
    st->isync = 0;
}

/* free the memory */
void destroy_lpc10_encoder_state (lpc10_encoder_state *st)
{
    if(st != NULL)
    {
        free(st);
        st = NULL;
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -