📄 lpc10dec.c
字号:
/*
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 + -