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

📄 lpc10dec.c

📁 本源码说明了声音压缩在工程中的使用
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
  LPC-10 voice codec, part of the HawkVoice Direct Interface (HVDI)
  cross platform network voice library
  Copyright (C) 2001-2004 Phil Frisbie, Jr. (phil@hawksoft.com)

  The VBR algorithm was contributed by
  Ben Appleton <appleton@bigpond.net.au>

  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
*/

#ifndef MACOSX
#include <malloc.h>
#endif
#include <stdlib.h>
#include <memory.h>
#ifdef _MSC_VER
#pragma warning (disable:4711) /* to disable automatic inline warning */
#endif
#include <math.h>
#include "ftol.h"
#include "lpc10.h"

#define LPC10_BITS_IN_COMPRESSED_FRAME 54

#ifndef TRUE
#define TRUE (1)
#define FALSE (0)
#endif

#ifndef min
#define min(a,b) ((a) <= (b) ? (a) : (b))
#define max(a,b) ((a) >= (b) ? (a) : (b))
#endif

typedef struct lpc10_d_state {

    /* State used by function decode */
    long iptold;   /* initial value 60 */

    /* State used by function synths */
    float buf[360];
    long buflen;   /* initial value 180 */

    /* State used by function pitsyn */
    long ivoico;   /* no initial value necessary as long as first_pitsyn is initially TRUE_ */
    long ipito;   /* no initial value necessary as long as first_pitsyn is initially TRUE_ */
    float rmso;   /* initial value 1.f */
    float rco[10];   /* no initial value necessary as long as first_pitsyn is initially TRUE_ */
    long jsamp;   /* no initial value necessary as long as first_pitsyn is initially TRUE_ */
    int first_pitsyn;   /* initial value TRUE_ */

    /* State used by function bsynz */
    long ipo;
    float exc[166];
    float exc2[166];
    float lpi1;
    float lpi2;
    float lpi3;
    float hpi1;
    float hpi2;
    float hpi3;
    float rmso_bsynz;

    /* State used by function deemp */
    float dei1;
    float dei2;
    float deo1;
    float deo2;
    float deo3;

} lpc10_d_state_t;


extern long lpcbits[10];

/* Table of constant values */
static long detau[128] = { 0,0,0,3,0,3,3,31,0,3,3,21,3,3,29,30,0,3,3,
20,3,25,27,26,3,23,58,22,3,24,28,3,0,3,3,3,3,39,33,32,3,37,35,36,
3,38,34,3,3,42,46,44,50,40,48,3,54,3,56,3,52,3,3,1,0,3,3,108,3,78,
100,104,3,84,92,88,156,80,96,3,3,74,70,72,66,76,68,3,62,3,60,3,64,
3,3,1,3,116,132,112,148,152,3,3,140,3,136,3,144,3,3,1,124,120,128,
3,3,3,3,1,3,3,3,1,3,1,1,1 };

static long rmst[64] = { 1024,936,856,784,718,656,600,550,502,460,420,
384,352,328,294,270,246,226,206,188,172,158,144,132,120,110,102,
92,84,78,70,64,60,54,50,46,42,38,34,32,30,26,24,22,20,18,17,16,15,
14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 };

static long detab7[32] = { 4,11,18,25,32,39,46,53,60,66,72,77,82,87,92,
96,101,104,108,111,114,115,117,119,121,122,123,124,125,126,127,127 };

static float descl[8] = { .6953f,.625f,.5781f,.5469f,.5312f,.5391f,.4688f,.3828f };
static long deadd[8] = { 1152,-2816,-1536,-3584,-1280,-2432,768,-1920 };
static long qb[8] = { 511,511,1023,1023,1023,1023,2047,4095 };
static long nbit[10] = { 8,8,5,5,4,4,4,4,3,2 };
static long kexc[25] = { 8,-16,26,-48,86,-162,294,-502,718,-728,184,
672,-610,-672,184,728,718,502,294,162,86,48,26,16,8 };

static void pitsyn(long *voice, long *pitch, float *rms, float *rc,
             long *ivuv, long *ipiti, float *rmsi, float *rci, long *nout,
             float *ratio, lpc10_decoder_state *st)
{
    /* Initialized data */
    
    float *rmso;
    
    /* Local variables */
    float alrn, alro, yarc[10], prop;
    long i, j, vflag, jused, lsamp;
    long *jsamp;
    float slope;
    long *ipito;
    float uvpit;
    long ip, nl, ivoice;
    long *ivoico;
    long istart;
    float *rco;
    float xxy;
    
    
    /* Function Body */
    ivoico = &(st->ivoico);
    ipito = &(st->ipito);
    rmso = &(st->rmso);
    rco = &(st->rco[0]);
    jsamp = &(st->jsamp);
    
    if (*rms < 1.f) {
        *rms = 1.f;
    }
    if (*rmso < 1.f) {
        *rmso = 1.f;
    }
    uvpit = 0.f;
    *ratio = *rms / (*rmso + 8.f);

    if (st->first_pitsyn) {
        lsamp = 0;
        ivoice = voice[1];
        if (ivoice == 0) {
            *pitch = LPC10_SAMPLES_PER_FRAME / 4;
        }
        *nout = LPC10_SAMPLES_PER_FRAME / *pitch;
        *jsamp = LPC10_SAMPLES_PER_FRAME - *nout * *pitch;
        
        for (i = 0; i < *nout; ++i) {
            for (j = 0; j < 10; ++j) {
                rci[j + i * 10] = rc[j];
            }
            ivuv[i] = ivoice;
            ipiti[i] = *pitch;
            rmsi[i] = *rms;
        }
        st->first_pitsyn = FALSE;

    } else {
        vflag = 0;
        lsamp = LPC10_SAMPLES_PER_FRAME + *jsamp;
        slope = (*pitch - *ipito) / (float) lsamp;
        *nout = 0;
        jused = 0;
        istart = 1;
        if (voice[0] == *ivoico && voice[1] == voice[0]) {
            if (voice[1] == 0) {
                /* SSUV - -   0  ,  0  ,  0 */
                *pitch = LPC10_SAMPLES_PER_FRAME / 4;
                *ipito = *pitch;
                if (*ratio > 8.f) {
                    *rmso = *rms;
                }
            }
            /* SSVC - -   1  ,  1  ,  1 */
            slope = (*pitch - *ipito) / (float) lsamp;
            ivoice = voice[1];
        } else {
            if (*ivoico != 1) {
                if (*ivoico == voice[0]) {
                    /* UV2VC2 - -  0  ,  0  ,  1 */
                    nl = lsamp - LPC10_SAMPLES_PER_FRAME / 4;
                } else {
                    /* UV2VC1 - -  0  ,  1  ,  1 */
                    nl = lsamp - LPC10_SAMPLES_PER_FRAME * 3 / 4;
                }
                ipiti[0] = nl / 2;
                ipiti[1] = nl - ipiti[0];
                ivuv[0] = 0;
                ivuv[1] = 0;
                rmsi[0] = *rmso;
                rmsi[1] = *rmso;
                for (i = 0; i < 10; ++i) {
                    rci[i] = rco[i];
                    rci[i + 10] = rco[i];
                    rco[i] = rc[i];
                }
                slope = 0.f;
                *nout = 2;
                *ipito = *pitch;
                jused = nl;
                istart = nl + 1;
                ivoice = 1;
            } else {
                if (*ivoico != voice[0]) {
                    lsamp = LPC10_SAMPLES_PER_FRAME / 4 + *jsamp;
                } else {
                    lsamp = LPC10_SAMPLES_PER_FRAME * 3 / 4 + *jsamp;
                }
                for (i = 0; i < 10; ++i) {
                    yarc[i] = rc[i];
                    rc[i] = rco[i];
                }
                ivoice = 1;
                slope = 0.f;
                vflag = 1;
            }
        }
        for(;;) {
            
            for (i = istart; i <= lsamp; ++i) {
                if (uvpit != 0.f) {
                    ip = lrintf(uvpit);
                }
                else {
                    ip = lrintf(*ipito + slope * i + .5f);
                }
                
                if (ip <= i - jused) {
                    ipiti[*nout] = ip;
                    *pitch = ip;
                    ivuv[*nout] = ivoice;
                    jused += ip;
                    prop = (jused - ip / 2) / (float) lsamp;
                    for (j = 0; j < 10; ++j) {
                        alro = (float)log((rco[j] + 1) / (1 - rco[j]));
                        alrn = (float)log((rc[j] + 1) / (1 - rc[j]));
                        xxy = alro + prop * (alrn - alro);
                        xxy = (float)exp(xxy);
                        rci[j + *nout * 10] = (xxy - 1) / (xxy + 1);
                    }
                    rmsi[*nout] = (float)(log(*rmso) + prop * (log(*rms) - log(*rmso)));
                    rmsi[*nout] = (float)exp(rmsi[*nout]);
                    ++(*nout);
                }
            }
            if (vflag != 1) {
                break;
            }
            
            vflag = 0;
            istart = jused + 1;
            lsamp = LPC10_SAMPLES_PER_FRAME + *jsamp;
            slope = 0.f;
            ivoice = 0;
            uvpit = (float) ((lsamp - istart) / 2);
            if (uvpit > 90.f) {
                uvpit /= 2;
            }
            *rmso = *rms;
            for (i = 1; i <= 10; ++i) {
                rco[i - 1] = rc[i - 1] = yarc[i - 1];
            }
        }
       *jsamp = lsamp - jused;
    }
    if (*nout != 0) {
        *ivoico = voice[1];
        *ipito = *pitch;
        *rmso = *rms;
        for (i = 0; i < 10; ++i) {
            rco[i] = rc[i];
        }
    }
} /* pitsyn_ */

#define MIDTAP 1
#define MAXTAP 4
static short y[MAXTAP+1]={-21161, -8478, 30892,-10216, 16950};
static int j=MIDTAP, k=MAXTAP;

static int random16 (void)
{
    int the_random;
    
    /*   The following is a 16 bit 2's complement addition,
    *   with overflow checking disabled	*/
    
    y[k] = (short)(y[k] + y[j]);
    
    the_random = y[k];
    k--;
    if (k < 0) k = MAXTAP;
    j--;
    if (j < 0) j = MAXTAP;
    
    return(the_random);
}

static void bsynz(float *coef, long ip, long *iv, 
                  float *sout, float *rms, float *ratio, float *g2pass,
                  lpc10_decoder_state *st)
{
    /* Initialized data */
    
    long *ipo;
    float *rmso;
    float *exc;
    float *exc2;
    float lpi1;
    float lpi2;
    float hpi1;
    float hpi2;
    
    /* Local variables */
    float gain, xssq;
    long i, j, k;
    float pulse;
    long px;
    float sscale;
    float xy, sum, ssq;
    float lpi0, hpi0;
    
    /* Parameter adjustments */
    if (coef) {
        --coef;
    }
    
    /* Function Body */
    ipo = &(st->ipo);
    exc = &(st->exc[0]);
    exc2 = &(st->exc2[0]);
    lpi1 = st->lpi1;
    lpi2 = st->lpi2;
    hpi1 = st->hpi1;
    hpi2 = st->hpi2;
    rmso = &(st->rmso_bsynz);
    
    /*                  MAXPIT+MAXORD=166 */
    /*  Calculate history scale factor XY and scale filter state */
    /* Computing MIN */
    xy = min((*rmso / (*rms + 1e-6f)),8.f);
    *rmso = *rms;
    for (i = 0; i < 10; ++i) {
        exc2[i] = exc2[*ipo + i] * xy;
    }
    *ipo = ip;
    if (*iv == 0) {
        /*  Generate white noise for unvoiced */
        for (i = 0; i < ip; ++i) {
            exc[10 + i] = (float) (random16() >> 6);
        }
        px = ((random16() + 32768) * (ip - 1) >> 16) + 10 + 1;
        pulse = *ratio * 85.5f;
        if (pulse > 2e3f) {
            pulse = 2e3f;
        }
        exc[px - 1] += pulse;
        exc[px] -= pulse;
        /*  Load voiced excitation */
    } else {
        sscale = (float)sqrt((float) (ip)) * 0.144341801f;
        for (i = 0; i < ip; ++i) {
            float temp;
            
            if (i > 27) {
                temp = 0.f;
            }
            else if (i < 25) {

⌨️ 快捷键说明

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