📄 celp.c
字号:
/**************************************************************************
* *
* CELP Voice Coder *
* Version 3.2c *
* *
***************************************************************************/
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "ccsub.h"
#define CELP_USE_CONTEXT
#define TRUE 1
#define FALSE 0
#include "celplib.h"
#include "celp.h"
#define STREAMBITS 144
#define CODELENGTH1 15
#define CODELENGTH2 11
#define PARITYLENGTH (CODELENGTH1 - CODELENGTH2)
#define SYNDRUN 100
#define OMEGA 0.994127f /* Bandwidth expansion for LPC analysis (15 Hz) */
#define ALPHA 0.8f /* Bandwidth expansion for postfilter */
#define BETA 0.5f /* Bandwidth expansion for postfilter */
#define mmax(A,B) ((A) > (B) ? (A) : (B))
#define mmin(A,B) ((A) < (B) ? (A) : (B))
#ifdef CELP_USE_CONTEXT
static struct celp_context *ctx = NULL; // Current CELP context (hidden argument to internal functions)
#endif
static const int cbgbits = 5, ncsize = 512, no = 10;
#ifdef CELP_USE_CONTEXT
#define cbindex (ctx->CELP_cbindex)
#define gindex (ctx->CELP_gindex)
#define idb (ctx->CELP_idb)
#define nseg (ctx->CELP_nseg)
#define pindex (ctx->CELP_pindex)
#define frame (ctx->CELP_frame)
#define tauptr (ctx->CELP_tauptr)
#define minptr (ctx->CELP_minptr)
#define plevel1 (ctx->CELP_plevel1)
#define plevel2 (ctx->CELP_plevel2)
#else
static int cbindex = 0, gindex = 0, idb = 0;
static int nseg = 0, pindex = 0, frame = 0, tauptr = 0, minptr = 0, plevel1 = 0;
static int plevel2 = 0;
#endif
static const int pbits[MAXNP + 2] = {8, 6, 5, 0, 0};
static const int mxsw = 1;
#ifdef CELP_USE_CONTEXT
#define bb (ctx->CELP_bb)
#define e0 (ctx->CELP_e0)
#define fc (ctx->CELP_fc)
#define fcn (ctx->CELP_fcn)
#define fci (ctx->CELP_fci)
#define h (ctx->CELP_h)
#else
static float bb[MAXNP + 1], e0[MAXLP];
static float fc[MAXNO + 1], fcn[MAXNO + 1], fci[MAXNO + 1];
static float h[MAXLP];
#endif
static const float gamma2 = 0.8f, prewt = 0.0f;
/* Adaptive code book index (pitch delay) file */
static const float pdelay[MAXPD] = {
#include "pdelay.h"
};
/* Stochastic code book vector file */
static const float x[MAXCODE] = {
#include "codebook.h"
};
/* Pitch delay coding tables for bit assignment:
pdencode.h for encoding, pddecode.h for decoding */
static const int pdencode[MAXPD] = {
#include "pdencode.h"
};
static const float pddecode[MAXPD] = {
#include "pddecode.h"
};
static const char ptype[10] = "max2", cbgtype[10] = "log";
static const char pstype[10] = "hier";
static const int ll = 240, lp = 60, l = 60;
static int i, j, k;
static int nn;
#ifdef CELP_USE_CONTEXT
#define cbi (ctx->CELP_cbi)
#define findex (ctx->CELP_findex)
#define lspflag (ctx->CELP_lspflag)
#define pdtabi (ctx->CELP_pdtabi)
#define cbg (ctx->CELP_cbg)
#define pgs (ctx->CELP_pgs)
#define sold (ctx->CELP_sold)
#define snew (ctx->CELP_snew)
#define ssub (ctx->CELP_ssub)
#define v (ctx->CELP_v)
#define vdecoded (ctx->CELP_vdecoded)
#define rcn (ctx->CELP_rcn)
#define hamw (ctx->CELP_hamw)
#define dps (ctx->CELP_dps)
#define newfreq (ctx->CELP_newfreq)
#define unqfreq (ctx->CELP_unqfreq)
#define lsp (ctx->CELP_lsp)
#define dpps (ctx->CELP_dpps)
#define decodedgain (ctx->CELP_decodedgain)
#define taus (ctx->CELP_taus)
#else
static int cbi[MAXLL / MAXL];
static int findex[MAXNO];
static int lspflag;
static int pdtabi[MAXPD];
static float cbg[MAXLL / MAXL], pgs[MAXLL / MAXL];
static float sold[MAXLL], snew[MAXLL], ssub[MAXLL], v[MAXLL];
static float vdecoded[MAXLL], rcn[MAXNO], hamw[MAXLL];
static float dps[MAXPA], newfreq[MAXNO], unqfreq[MAXNO], lsp[MAXLL / MAXL][MAXNO];
static float dpps[MAXPA];
static float decodedgain, taus[4];
#endif
static const float scale = 1.0;
/* Filter coefficients for 2nd order Butterworth 100 Hz HPF */
static const float ahpf[3] = {0.946f, -1.892f, 0.946f};
static const float bhpf[3] = {1.0f, -1.889033f, 0.8948743f};
/* Bit stream */
static const int cbbits = 9;
static const int sbits[MAXNO] = {3, 4, 4, 4, 4, 3, 3, 3, 3, 3};
#ifdef CELP_USE_CONTEXT
#define pointer (ctx->CELP_pointer)
#define bitpointer (ctx->CELP_bitpointer)
#define bitsum1 (ctx->CELP_bitsum1)
#define bitsum2 (ctx->CELP_bitsum2)
#define stream (ctx->CELP_stream)
#define savestream (ctx->CELP_savestream)
#else
static int pointer, bitpointer, bitsum1, bitsum2;
static short stream[STREAMBITS], savestream[STREAMBITS];
#endif
/* Filter memories (should be maxno+1) */
#ifdef CELP_USE_CONTEXT
#define dhpf1 (ctx->CELP_dhpf1)
#define dhpf2 (ctx->CELP_dhpf2)
#define dss (ctx->CELP_dss)
#define dp1 (ctx->CELP_dp1)
#define dp2 (ctx->CELP_dp2)
#define dp3 (ctx->CELP_dp3)
#define ip (ctx->CELP_ip)
#define op (ctx->CELP_op)
#else
static float dhpf1[3], dhpf2[3], dss[MAXNO+1];
static float dp1[MAXNO+1], dp2[MAXNO+1], dp3[2];
static float ip, op;
#endif
/* Error control coding parameters */
#ifdef CELP_USE_CONTEXT
#define syndavg (ctx->CELP_syndavg)
#define twoerror (ctx->CELP_twoerror)
#else
static float syndavg = 0.0;
static int twoerror;
#endif
#ifdef CELP_PROTECT
#ifdef CELP_USE_CONTEXT
#define snrflag (ctx->CELP_snrflag)
#define syncBit (ctx->CELP_syncBit)
#define codeword (ctx->CELP_codeword)
#define hmatrix (ctx->CELP_hmatrix)
#define syndrometable (ctx->CELP_syndrometable)
#define paritybit (ctx->CELP_paritybit)
#define protect (ctx->CELP_protect)
#define syndrome (ctx->CELP_syndrome)
#else
static int snrflag;
static int syncBit = 1;
static int codeword[CODELENGTH1], hmatrix[CODELENGTH1];
static int syndrometable[CODELENGTH1], paritybit, protect;
static int syndrome;
#endif // CELP_USE_CONTEXT
/* Bit protection vector */
static const int bitprotect[CODELENGTH2] = {
#include "bitprot.h"
};
#endif // CELP_PROTECT
static int celp_error; /* Error in encoding or decoding */
#include "celpfiles.h"
/* CELP_INIT -- Initialise CELP Codec. Set "prot" nonzero
if you wish to include bit error protection
in the encoded stream. If you're using a
transmission layer which performs its own
error detection and correction (such as Internet
TCP or UDP transmission), bit error recovery in
the CELP stream is a waste of time. */
#ifdef CELP_USE_CONTEXT
void celp_init(struct celp_context *c, int prot)
#else
void celp_init(int prot)
#endif
{
#ifdef CELP_USE_CONTEXT
ctx = c;
#endif
#ifdef CELP_PROTECT
protect = prot; /* Set bit error recovery mode */
#endif
/* Number of codewords/LPC frame */
nn = ll / l;
/* Dimension of d1a and d1b */
idb = MMAX + MAXNP - 1 + l;
plevel1 = 1 << pbits[0];
/* Levels of delta tau */
plevel2 = 1 << pbits[1];
/* number of bits per subframe */
bitsum1 = cbbits + cbgbits + pbits[0] + pbits[2];
bitsum2 = cbbits + cbgbits + pbits[1] + pbits[2];
/* For double error detecting FEC codes (NOT USED) */
#ifdef CELP_PROTECT
twoerror = FALSE;
snrflag = FALSE;
lspflag = TRUE;
#endif
/* Initialise arrays */
for (i = 0; i < MAXLP; i++) {
h[i] = e0[i] = 0.0;
}
for (i = 0; i < MAXLL; i++) {
sold[i] = 0.0;
}
for (i = 0; i < STREAMBITS; i++) {
stream[i] = savestream[i] = 0;
}
/* Start nseg at 0 to do pitch on odd segments.
(nseg is incremented before csub). */
nseg = 0;
/* Generate matrix for error control coding */
#ifdef CELP_PROTECT
matrixgen(CODELENGTH1, CODELENGTH2, hmatrix, syndrometable);
#endif
/* Generate Hamming windows */
ham(hamw, ll);
/* Generate pdtabi for delta delay coding */
for (i = 0; i < MAXPD; i++) {
pdtabi[pdencode[i]] = i;
}
}
/* CELP_ENCODE -- Encode a 240 sample frame of audio in CELP. */
#ifdef CELP_USE_CONTEXT
int celp_encode(struct celp_context *c, short iarf[MAXLL], char packedbits[STREAMBITS / 8])
#else
int celp_encode(short iarf[MAXLL], char packedbits[STREAMBITS / 8])
#endif
{
int i, l_pointer;
int i1, i2, i3;
#ifdef CELP_USE_CONTEXT
ctx = c;
#endif
frame++;
l_pointer = 0;
celp_error = CELP_OK;
/* Scale and convert to real speech.
The ssub buffer used for subframe CELP analysis is 1/2 a
frame behind the snew buffer and 1/2 a frame ahead of the
sold buffer. */
for (i = 0; i < ll; i++) {
snew[i] = mmax(-32768.0f, mmin(scale * iarf[i], 32767.0f));
}
/* High pass filter snew. */
zerofilt(ahpf, 2, dhpf1, snew, ll);
polefilt(bhpf, 2, dhpf2, snew, ll);
if (celp_error) {
return celp_error;
}
/* Make ssub vector from snew and sold. */
for (i = 0; i < ll/2; i++) {
ssub[i] = sold[i + ll/2];
ssub[i + ll/2] = snew[i];
}
autohf(snew, hamw, ll, no, OMEGA, fcn, rcn);
/* Pc -> lsp (new). */
pctolsp2(fcn, no, newfreq, &lspflag);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -