📄 lpc10enc.c
字号:
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 + -