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

📄 celp_decode.c

📁 由HawK提供的语音压缩软件
💻 C
字号:
/*
  CELP voice codec, part of the HawkVoice Direct Interface (HVDI)
  cross platform network voice library
  Copyright (C) 2001-2003 Phil Frisbie, Jr. (phil@hawksoft.com)

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Library General Public
  License as published by the Free Software Foundation; either
  version 2 of the License, or (at your option) any later version.
  
  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Library General Public License for more details.
    
  You should have received a copy of the GNU Library General Public
  License along with this library; if not, write to the
  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  Boston, MA  02111-1307, USA.
      
  Or go to http://www.gnu.org/copyleft/lgpl.html
*/
/**************************************************************************
*                                                                         *
*	CELP Voice Coder                                                      *
*	Version 3.2c	                                                      *
*									                                      *
*	The U.S. Government shall not be held liable for any damages          *
*	resulting from this code.  Further reproduction or distribution       *
*	of this code without prior written permission of the U.S.             *
*	Government is prohibited.  	                                          *
*                                                                         *
***************************************************************************
*
* ROUTINE
*		celp_decode
*
* FUNCTION
*		Codebook excited linear predictor (main routine)
*
***************************************************************************/

#ifdef _MSC_VER
#pragma warning (disable:4305) /* to disable const double to float warning */
#endif

#include <stdlib.h>
#ifndef MACOSX
#include <malloc.h>
#endif
#include <memory.h>
#include "celpint.h"
#include "ftol.h"

extern void zerofilt10(float *b, float *z, float *xy, int len);

extern void zerofilt2(float *b, float *z, float *xy, int len);
extern void polefilt10(float *a, float *z, float *xy, int len);
extern void polefilt2(float *a, float *z, float *xy, int len);
extern void ham(float *win, int n);
extern void lspdecode34(int *findex, int no, float *freq);
extern void lsptopc(float *f, float *pc);
extern void pitchvql(float *rar, int idim, float *buf, int idimb, float *b);
extern void gaindecode(int gindex, int bits, float *gain);
extern void pitchdecode(int pindex, float *pitch);

/* defined in celp_encode.c */
extern int pbits[MAXNP + 2];
extern float pdelay[MAXPD];
extern int sbits[MAXNO];
extern float w[2][4];
extern float bhpf[3];
extern float ahpf[3];

/***************** Decoding routines start here ****************/
#define TC          0.01f
#define ALPHA		0.8f  /* Bandwidth expansion for postfilter */
#define BETA		0.5f  /* Bandwidth expansion for postfilter */

/* *load stochastic code book vector file			*/
float x[MAXCODE] = 
{
#include "codebook.h"
};

static void bwexp(float alpha, float *pc, float *pcexp, int n)
{
    int i;
    float temp = 1.0f;

    for (i = 0; i <= n; i++)
    {
        pcexp[i] = pc[i] * temp;
        temp *= alpha;
    }
}

static void unpack(int *array, int bits, int *value, int *pointer)
{
    int i;
    
    for (i = 0, *value = 0; i < bits; i++, (*pointer)++)
        *value |= array[*pointer+1] << i;
}

static void pctorc(float *lpc, float *rc)
{
    float t[MAXNO+1], a[MAXNO+1];
    int i, j;
    
    for (i = 0; i <= 10; i++)
        a[i] = lpc[i];
    for (i = 10; i > 1; i--)
    {
        rc[i-1] = -a[i];
        for (j = 1; j < i; j++)
            t[i-j] = (a[i-j] + rc[i-1] * a[j]) / (1.0f - rc[i-1] * rc[i-1]);
        for (j = 1; j < i; j++)
            a[j] = t[j];
    }
    rc[0] = -a[1];
}

static int clip(float *s, int l)
{
    int i, count;
    float sum;
    
    /*	Count number of clippings and sum their magnitudes		*/
    
    count = 0;
    sum = 0.0;
    for (i = 0; i < l; i++)
    {
        if (fabs(s[i]) > 32768.0f)
        {
            count++;
            sum += (float)fabs(s[i]);
        }
    }
    
    /*	Clipping heuristics (could also use energy, delta energy, etc.)	*/
    
    return(((count >= 10) || (count >= 5 && sum > 1.e6)) ? TRUE : FALSE);
}

static void dcodcbg(int cbgbits, int bitsum1, int bitsum2, int *bitpointer,
                    int *stream, float *cbg)
{
    int i, pointer, index;
    
    pointer = *bitpointer;
    for (i = 0; i < NSUBFRAMES; i++)
    {
        unpack(stream, cbgbits, &index, &pointer);
        gaindecode(index, cbgbits, &cbg[i]);
        if (i == 0 || i == 2 || i == 4)
            pointer += bitsum2 - cbgbits;
        else
            pointer += bitsum1 - cbgbits;
    }
    *bitpointer += cbgbits;
}

static void dcodcbi(int cbbits, int bitsum1, int bitsum2, int *bitpointer,
                    int *stream, int *cbi)
{
    int i, pointer;
    
    pointer = *bitpointer;
    for (i = 0; i < NSUBFRAMES; i++)
    {
        unpack(stream, cbbits, &cbi[i], &pointer);
        cbi[i]++;
        if (i == 0 || i == 2 || i == 4)
            pointer += bitsum2 - cbbits;
        else
            pointer += bitsum1 - cbbits;
    }
    *bitpointer += cbbits;
}

static void dcodpg(int pgbits, int bitsum1, int bitsum2, int *bitpointer,
                   int *stream, float *pgs)
{
    int i, pointer, index;
    
    pointer = *bitpointer;
    for (i = 0; i < NSUBFRAMES; i++)
    {
        unpack(stream, pgbits, &index, &pointer);
        pitchdecode(index, &pgs[i]);
        if (i == 0 || i == 2 || i == 4)
            pointer += bitsum2 - pgbits;
        else
            pointer += bitsum1 - pgbits;
    }
    *bitpointer += pgbits;
}

static void dcodtau(int taubits, int taudelta, int bitsum1, int bitsum2, int *bitpointer,
                    int *stream, float *taus, celp_decoder_state *st)
{
    int i, pointer, tptr, mxptr, mnptr;
    static int lptr = 0;
    
    pointer = *bitpointer;
    for (i = 0; i < NSUBFRAMES; i++)
    {
        if (((i + 1) % 2) != 0)
        {
            unpack(stream, taubits, &tptr, &pointer);
            taus[i] = pdelay[tptr];
            pointer += bitsum1 - taubits;
        }
        else
        {
            unpack(stream, taudelta, &tptr, &pointer);
            pointer += bitsum2 - taudelta;
            mnptr = lptr - (st->plevel2 / 2 - 1);
            mxptr = lptr + (st->plevel2 / 2);
            if (mnptr < 0)
                mnptr = 0;
            if (mxptr > st->plevel1 - 1)
                mnptr = st->plevel1 - st->plevel2;
            taus[i] = pdelay[tptr + mnptr];
        }
        lptr = tptr;
    }
    *bitpointer += taubits;
}

static void intsynth(float *lspnew, float lsp[][MAXNO], celp_decoder_state *st)
{
    int i, j;
    
    /* *interpolate lsp's						 */
    for (i = 0; i < NSUBFRAMES; i++)
    {
        for (j = 0; j < 10; j++)
            lsp[i][j] = w[0][i] * st->lspold[j] + w[1][i] * lspnew[j];
    }
    
    /* 		*update lsp history					 */
    
    for (i = 0; i < 10; i++)
        st->lspold[i] = lspnew[i];
}

static void zerofilt1(float *b, float *z, float *xy, int len)
{
    register float ar;
    int t;
    
    for (t = 0; t < len; t++)
    {
        z[0] = xy[t];
        ar   = 0.0;

        ar  += z[1] * b[1];
        z[1] = z[0];

        xy[t] = ar + z[0] * b[0];
    }
}

static void postfilt(float *s, int l, float *fci, celp_decoder_state *st)
{
    int n;
    float ast[2];
    float pcexp1[MAXNO + 1], pcexp2[MAXNO + 1], rcexp2[MAXNO];
    float powerin = st->ip;
    float powerout = st->op;
    float *dp1 = st->dp1, *dp2 = st->dp2, *dp3 = st->dp3;
    
#ifdef POSTFIL2
    float scale;
#else
    float newpowerin[MAXL + 1], newpowerout[MAXL + 1];
#endif
    
    /*			*estimate input power				*/
    
#ifdef POSTFIL2
    for (n = 0; n < l; n++)
        powerin = powerin * (1.0f - TC) + TC * s[n] * s[n];
#else
    newpowerin[0] = powerin;
    for (n = 0; n < l; n++)
        newpowerin[n + 1] = (1.0f - TC) * newpowerin[n] + TC * s[n] * s[n];
    powerin = newpowerin[l];
#endif
    
    /* *BW expansion							*/
    bwexp(BETA, fci, pcexp1, 10);
    bwexp(ALPHA, fci, pcexp2, 10);
    
    /* *pole-zero postfilter						*/
    zerofilt10(pcexp1, dp1, s, l);
    polefilt10(pcexp2, dp2, s, l);
    
    /* *find spectral tilt (1st order fit) of postfilter
    *(denominator dominates the tilt)					*/
    pctorc(pcexp2, rcexp2);
    
    /* *tilt compensation by a scaled zero
    *(don't allow hF roll-off)						*/
    ast[0] = 1.0;
    ast[1] = (rcexp2[0] > 0.f) ? -0.5f * rcexp2[0] : 0.f;
    zerofilt1(ast, dp3, s, l);
    
    /* *estimate output power						*/
    
#ifdef POSTFIL2
    for (n = 0; n < l; n++)
        powerout = powerout * (1.0f - TC) + TC * s[n] * s[n];
    
    /* *block wise automatic gain control					*/
    
    if (powerout > 0.0)
        for (scale = (float)sqrt(powerin / powerout), n = 0; n < l; n++)
            s[n] *= scale;
#else
        newpowerout[0] = powerout;
        for (n = 0; n < l; n++)
            newpowerout[n + 1] = (1.0f - TC) * newpowerout[n] + TC * s[n] * s[n];
        powerout = newpowerout[l];
        
        /* *sample wise automatic gain control				*/
        
        for (n = 0; n < l; n++)
        {
            if (newpowerout[n + 1] > 0.0f)
                s[n] *= (float)sqrt(newpowerin[n + 1] / newpowerout[n + 1]);
        }
#endif
        st->ip = powerin;
        st->op = powerout;
}

static void vdecode(float decodedgain, int l, float *vdecoded, int cbindex)
{
    int i, codeword;
    
    /* *copy selected vector to excitation array	 		 	 */
    
    codeword = 2 * (MAXNCSIZE - cbindex);
    if (codeword < 0)
    {
        codeword = 0;
    }
    for (i = 0; i < l; i++)
        vdecoded[i] = x[i + codeword] * decodedgain;
}

int celp_decode(const unsigned char *in, short *out, celp_decoder_state *st)
{
    int cbindex;
    float bbd[MAXNP + 1];
    float fci[MAXNO + 1];
    int cbi[MAXLL / MAXL];
    int i, j, k, l = 60;
    int findex[MAXNO];
    float cbg[MAXLL / MAXL], pgs[MAXLL / MAXL];
    float vdecoded[MAXLL];
    float decodedgain, taus[4];
    float newfreq[MAXNO], lsp[MAXLL / MAXL][MAXNO];
    int pointer, bitpointer;
    int stream[STREAMBITS];
    
    /* *number of codewords/LPC frame				 */
    
    l = st->framesize / NSUBFRAMES;
    
    /* unpack bits into array */
    for (i = 0; i < STREAMBITS; i++)
    {
        stream[i] = (int)((in[i >> 3] & (1 << (i & 7))) != 0 ? 1 : 0);
    }
    
    /* *** SYNTHESIS ..........................................		 */
    
    /* *unpack data stream						 */
    pointer = -1; 
    
    /* stream is the encoded bits in */
    for (i = 0; i < 10; i++)
        unpack(stream, sbits[i], &findex[i], &pointer);
    
    /* *decode lsp's							 */
    
    lspdecode34(findex, 10, newfreq);
    
    /* *interpolate spectrum lsp's for subframes			 */
    
    intsynth(newfreq, lsp, st);
    
    
    /* *decode all code book and pitch parameters			 */
    
    bitpointer = pointer;
    dcodtau(pbits[0], pbits[1], st->bitsum1, st->bitsum2, &bitpointer, stream, taus, st);
    dcodpg(pbits[2], st->bitsum1, st->bitsum2, &bitpointer, stream, pgs);
    dcodcbi(pbits[3], st->bitsum1, st->bitsum2, &bitpointer, stream, cbi);
    dcodcbg(pbits[4], st->bitsum1, st->bitsum2, &bitpointer, stream, cbg);
    
    /* *** synthesize each subframe					 */
    
    k = 0;
    for (i = 0; i < NSUBFRAMES; i++)
    {
        /* *decode values for subframe					 */
        
        cbindex = cbi[i];
        decodedgain = cbg[i];
        
        /* *code book synthesis						 */
        
        vdecode(decodedgain, l, &vdecoded[k], cbindex);
        
        bbd[0] = taus[i];
        bbd[2] = pgs[i];
        
        /* *pitch synthesis						 */
        
        pitchvql(&vdecoded[k], l, st->dps, st->idb, bbd);
        
        /* convert lsp's to pc's 						 */
        
        lsptopc(&lsp[i][0], fci);	
        
        /* lpc synthesis	 						 */ 
        
        polefilt10(fci, st->dss, &vdecoded[k], l);	
        
        /* *** post filtering						 */
        
        postfilt(&vdecoded[k], l, fci, st);
        
        /* *** test for output speech clipping				 */
        
        while (clip(&vdecoded[k], l))
        {
            for (j = 0; j < l; j++)
                vdecoded[k + j] = 0.05f * vdecoded[k + j];
        }
#ifdef HIGHPASS_OUT
        /* *high pass filter						 */

        zerofilt2(ahpf, st->dhpf1, &vdecoded[k], l);
        polefilt2(bhpf, st->dhpf2, &vdecoded[k], l);
#endif
        /* *** write postfiltered output  */
        
        for (j = 0; j < l; j++)
            *out++ = (short)mmax(-32768, mmin(32767, lrintf(vdecoded[k + j])));
        
        k += l;
    }
    
    return st->framesize;
}

celp_decoder_state *create_celp_decoder_state()
{
    celp_decoder_state *st;
    
    st = (celp_decoder_state *)calloc(1, sizeof(celp_decoder_state));

    return st;
}

void init_celp_decoder_state(celp_decoder_state *st, int framesize)
{
    float lspold[MAXNO] = {.03f, .05f, .09f, .13f, .19f, .23f, .29f, .33f, .39f, .44f};
    int i;
    
    if(framesize > MAXFRAME || framesize < CELP_4_5_FRAMESIZE)
    {
        st->framesize = CELP_4_5_FRAMESIZE;
    }
    else
    {
        st->framesize = framesize;
    }
    st->framesize = framesize;
    st->plevel1 = 1 << pbits[0];
    st->plevel2 = 1 << pbits[1];
    for(i=0;i<MAXNO;i++)
        st->lspold[i] = lspold[i];
    st->idb =  MMAX + MAXNP + framesize/NSUBFRAMES - 1;
    /* *number of bits per subframe				 */
    st->bitsum1 =  pbits[0] + pbits[2] + pbits[3] + pbits[4];
    st->bitsum2 =  pbits[1] + pbits[2] + pbits[3] + pbits[4];
}

void destroy_celp_decoder_state(celp_decoder_state *st)
{
    free(st);
}

⌨️ 快捷键说明

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