celp.c
上传用户:tsjrly
上传日期:2021-02-19
资源大小:107k
文件大小:31k
- /**************************************************************************
- * *
- * 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 (main)
- *
- * FUNCTION
- * Codebook excited linear predictor (main routine)
- *
- ***************************************************************************
- *
- * REFERENCES
- *
- C National Communication System Technical Information Bulletin
- C Federal Standard 1016 (to be published 1992).
- C
- C Campbell, Joseph P. Jr., Thomas E. Tremain and Vanoy C. Welch,
- C "The Federal Standard 1016 4800 bps CELP Voice Coder," Digital
- C Signal Processing, Academic Press, Vol1, No. 3, p. 145-155.
- C
- C Kemp, David, P., Retha A. Sueda and Thomas E. Tremain, "An
- C Evaluation of 4800 bps Voice Coders," Proceedings of the IEEE
- C International Conference on Acoustics, Speech and Signal Processing
- C (ICASSP), 1989, p. 200-203.
- C
- C Fenichel, R., "Federal Standard 1016," National Communications
- C System, Office of Technology and Standards, Washington, DC 20305-2010,
- C 14 February 1991.
- C
- C Campbell, Joseph P. Jr., Thomas E. Tremain and Vanoy C. Welch,
- C "The DoD 4.8 kbps Standard (Proposed Federal Standard 1016),"
- C "Advances in Speech Coding", Kluwer Academic Publishers, 1991,
- C Chapter 12, p. 121-133.
- C
- C Tutorials:
- C Fallside, Frank and William Woods, Computer Speech Processing,
- C Prentice Hall International, 1985, Chapter 4 (by Bishnu Atal).
- *
- ***************************************************************************
- *
- * 4800 bps CELP Characteristics
- *
- * Spectrum Pitch Code Book
- * ------------- --------------- -----------------
- * Update 30 ms 30/4 = 7.5 ms 30/4 = 7.5 ms
- * ll=240 lp=60 l=60
- *
- * Order 10 256 (max) x 60 512 (max) x 60
- * 1 gain 1 gain
- *
- * Analysis Open loop Closed loop Closed loop
- * Correlation Modified MSPE MSPE VQ
- * 30 ms Hamming VQ, weight=0.8 weight=0.8
- * no preemphasis range 20 to 147 shift by 2
- * 15 Hz BW exp (w/ fractions) 77% sparsity
- *
- * Bits per 34 indep LSP index: 8+6+8+6 index: 9*4
- * Frame [3444433333] gain(-1,2): 5*4 gain(+/-): 5*4
- *
- * Bit Rate 1133.3 bps 1600 bps 1866.67 bps
- *
- * NOTE: The remaining 200 bps are used as follows: 1 bit per frame
- * for synchronization, 4 bits per frame for forward error correction
- * and 1 bit per frame to provide future expansion(s) of the coder.
- *
- ***************************************************************************
- *
- * UNPERMUTED BIT ASSIGNMENT
- *
- * lsp 1 1-3 lsp 6 20-22
- * lsp 2 4-7 lsp 7 23-25
- * lsp 3 8-11 lsp 8 26-28
- * lsp 4 12-15 lsp 9 29-31
- * lsp 5 16-19 lsp 10 32-34
- *
- * Subframe: 1 2 3 4
- * ---------- ----- ----- ----- -------
- * pitch delay 35-42 ..... 87-94 .......
- * delta delay ..... 62-67 ....... 114-119
- * pitch gain 43-47 68-72 95-99 120-124
- * cbindex 48-56 73-81 100-108 125-133
- * cbgain 57-61 82-86 109-113 134-138
- *
- * future bit 139
- * error control 140-143
- * sync 144
- *
- * FORWARD ERROR CONTROL, HAMMING (15,11):
- * bits protected allocation rate parameter
- * 0 1 LSP
- * 40,41,42,92,93,94 1st-3rd MSBs 2 Pitch delay
- * 0 2 Delta pitch delay
- * 47,72,99,124 1st MSB 4 Pitch gain
- * 0 4 CB index
- * 0 4 CB gain
- * 139 1 1 Future bit
- *
- * SYNCHRONIZATION BIT
- * The sync bit (144) begins with 0 in the first frame, then alternates
- * between 1 and 0 on successive frames.
- *
- ***************************************************************************
- *
- * INPUT FILES
- * ifile.spd speech
- * ifile.chan channel (use for synthesis only)
- * codebook.h stochastic code book
- * pdelay.h adaptive code book (pitch) delay
- * pdencode.h pitch delay bit assignment encoding table
- * pddecode.h pitch delay bit assignment decoding table
- * submult.h submultiple pitch delay pointer table
- * bitprot.h bit protection (specifies FEC bits)
- * bitperm.h bit permutation (for burst errors)
- *
- * OUTPUT FILES
- * ofile.spd speech (without high pass)
- * ofilehpf.spd speech (high pass)
- * ofilenpf.spd speech (no post filtering)
- * ofile.chan bit stream channel file
- *
- * Sungraph (tm) Files:
- * ifile_ofile.sg_data
- * channel.sg_data
- * stream_error.sg_data
- * lsp1.sg_data see sungraph_open.h
- * lsp2.sg_data
- * codebook.sg_data
- * constrain.sg_data
- * pitch.sg_data
- * error.sg_data
- * rc.sg_data
- *
- **************************************************************************
- *
- * global
- *
- *
- * SPECTRUM VARIABLES:
- * fc float LPC filter/weighting filter coefficients
- * fcn float new weighting filter coefficients
- * fci float interpolated weighting filter coefficients
- * gamma2 float weight factor
- * no int filter order predictor
- *
- * PITCH VARIABLES:
- * bb float pitch predictor coefficients
- * idb int dimension of d1a and d1b???
- * tauptr int pitch delay pointer
- * minptr int minimum delay pointer
- * pbits int pitch gain coding bit allocation
- * pindex int pitch gain index bb[2]
- * ptype char pitch gain (bb[2]) quantizer type
- * prewt real pitch prefilter weighting (0.0 = off)
- * pstype char pitch search type (hier, full, or intg)
- * pdelay float pitch delay coding table
- * plevel1 float number of full search pitch delays
- * plevel2 float number of delta search pitch delays
- *
- * CODE BOOK VARIABLES:
- * cbgbits int code book gain bit allocation
- * cbgtype char code book gain quantizer type
- * mxsw int modified excitation switch on(1) or off(0)
- * cbindex int code book index
- * e0 float initial error and updated error
- * gindex int gain index
- * h float impulse response
- * ncsize int code book size
- * nseg int segment counter
- * x float code book
- *
- *
- * MISCELLANEOUS:
- * frame int frame counter
- *
- **************************************************************************/
- #ifdef STREAMLINE
- #undef SUNGRAPH
- #endif
- #ifndef ANALY
- #undef SUNGRAPH
- #endif
- #define TRUE 1
- #define FALSE 0
- #define STREAMBITS 144
- #define CODELENGTH1 15
- #define CODELENGTH2 11
- #define PARITYLENGTH (CODELENGTH1 - CODELENGTH2)
- #define SYNDRUN 100
- #define OMEGA 0.994127 /* Bandwidth expansion for LPC analysis (15 Hz) */
- #define ALPHA 0.8 /* Bandwidth expansion for postfilter */
- #define BETA 0.5 /* Bandwidth expansion for postfilter */
- #define I2 1 /* symbolic disk_io data type */
- #define I4 2 /* symbolic disk_io data type */
- #define R4 3 /* symbolic disk_io data type */
- #define mmax(A,B) ((A)>(B)?(A):(B))
- #define mmin(A,B) ((A)<(B)?(A):(B))
- #include <stdio.h>
- #include <math.h>
- #include <strings.h>
- /* #include <floatingpoint.h> /* uncomment if you use ieee_handler below */
- #include "ccsub.h"
- int cbgbits = 5, cbindex = 0, gindex = 0, idb = 0, ncsize = 512, no = 10;
- int nseg = 0, pindex = 0, frame = 0, tauptr = 0, minptr = 0, plevel1 = 0;
- int plevel2 = 0, pbits[MAXNP + 2] = {8, 6, 5, 0, 0};
- int mxsw = 1;
- float bb[MAXNP + 1], e0[MAXLP];
- float fc[MAXNO + 1], fcn[MAXNO + 1], fci[MAXNO + 1];
- float h[MAXLP], gamma2 = 0.8, prewt = 0.0;
- /* *read adaptive code book index (pitch delay) file */
- float pdelay[MAXPD] =
- {
- #include "pdelay.h"
- };
- /* *load stochastic code book vector file */
- float x[MAXCODE] =
- {
- #include "codebook.h"
- };
- char ptype[10] = "max2", cbgtype[10] = "log";
- char pstype[10] = "hier";
- #ifdef SUNGRAPH
- int ifile_vid, ifile_hp_vid, ofile_npf_vid, ofile_pf_vid, ofile_hpf_vid;
- int channel_vid, gain_vid, ccor_vid, dbcon_vid;
- int stream_vid, stream_error_vid, stream_error_s_vid, bit_error_vid;
- int lsp_vid[MAXNO], qlsp_vid[MAXNO], lsp_analy_vid[MAXNO];
- int lsp_synth_vid[MAXNO], cb_gain_vid, cb_qgain_vid, cb_qgain_synth_vid;
- int cb_match_vid, cb_index_vid, cb_index_synth_vid, cb_exc_vid;
- int cb_ir_vid, pitch_gain_vid, pitch_qgain_vid, pitch_qgain_synth_vid;
- int pitch_match_vid, pitch_tau_vid, pitch_tau_synth_vid, pitch_ir_vid;
- int fndex_e0_vid, fndpp_e0_vid, fndpp_v0_vid, rc_vid[MAXNO];
- #endif
- main(argc, argv)
- int argc;
- char *argv[];
- {
- int cbi[MAXLL / MAXL], framesnr = 0;
- int framedm = 0, framedm2 = 0, i, j, k, l = 60, lun[10];
- int ll = 240, lp = 60, nn, np = 1, nrec1 = 1, nrec2 = 1, nrec3 = 1;
- int findex[MAXNO];
- int error = 0, total = 0, flag, snrflag, lspflag;
- int pdtabi[MAXPD], sync = 1;
- short iarf[MAXLL], npf[MAXLL], pf[MAXLL];
- float cbg[MAXLL / MAXL], pgs[MAXLL / MAXL];
- float sold[MAXLL], snew[MAXLL], ssub[MAXLL], v[MAXLL];
- float vdecoded[MAXLL], rcn[MAXNO], hamw[MAXLL], hamws[MAXL], dpa[MAXPA];
- float dps[MAXPA], newfreq[MAXNO], unqfreq[MAXNO], lsp[MAXLL / MAXL][MAXNO];
- float dppa[MAXPA], dpps[MAXPA];
- float scale = 1.0, decodedgain, dm[9], dm2[9], taus[4], descale = 1.0;
- /* *load pitch delay coding tables for bit assignment */
- /* *pdencode.h for encoding, pddecode.h for decoding */
- static int pdencode[MAXPD] =
- {
- #include "pdencode.h"
- };
- static float pddecode[MAXPD] =
- {
- #include "pddecode.h"
- };
- /* *filter coefficients for 2nd order 100 Hz HPF with 60 Hz notch: */
- /* static float ahpf[3] = {1.0, -1.99778, 1.0}; */
- /* static float bhpf[3] = {1.0, -1.88 0.89}; */
- /* *filter coefficients for 2nd order Butterworth 100 Hz HPF: */
- static float ahpf[3] = {0.946, -1.892, 0.946};
- static float bhpf[3] = {1.0, -1.889033, 0.8948743};
- /* *filter coefficients for 2nd order Butterworth 275 Hz HPF: */
- /* static float ahpfo[3] = {0.858, -1.716, 0.858}; */
- /* static float bhpfo[3] = {1.0, -1.696452, 0.7368054}; */
- static float ahpfo[3] = {0.946, -1.892, 0.946};
- static float bhpfo[3] = {1.0, -1.889033, 0.8948743};
- /*
- *bit stream
- */
- int cbbits = 9, pointer, bitpointer, bitsum1, bitsum2;
- int mask[STREAMBITS], ssum, pstream[STREAMBITS];
- static int sbits[MAXNO] = {3, 4, 4, 4, 4, 3, 3, 3, 3, 3};
- short stream[STREAMBITS], savestream[STREAMBITS];
- char line[38];
- /*
- *filter memories (should be maxno+1)
- */
- static float dhpf1[3], dhpf2[3], dsa[MAXNO+1], dss[MAXNO+1];
- static float dhpf1o[3], dhpf2o[3];
- static float dp1[MAXNO+1], dp2[MAXNO+1], dp3[2];
- static float ip, op, sumsnr, sumdm[10], sumdm2[10];
- /*
- *error control coding parameters:
- */
- float ber = 0.0, realerror, syndavg = 0.0;
- int codeword[CODELENGTH1], hmatrix[CODELENGTH1];
- int syndrometable[CODELENGTH1], paritybit, twoerror, protect;
- int syndrome, eccbits = 5;
- /* *load bit protection vector */
- static int bitprotect[CODELENGTH2] =
- {
- #include "bitprot.h"
- };
- /* *load bit permutation vector */
- static int bitpermute[STREAMBITS] =
- {
- #include "bitperm.h"
- };
- char tempstr[82];
- #ifdef ANALY
- static char ifile[82] = "dam2.spd";
- #else
- static char ifile[82] = "ofile.chan";
- #endif
- static char ofile[82] = "ofile";
- static char stype[12] = "kang";
- FILE *fopen(), *fp25;
-
- #ifdef SUNGRAPH
- /* ********************** sungraph*******************************/
-
- /* define sungraph files */
- int input_fid, ifile_ofile_fid, channel_fid, lsp1_fid, lsp2_fid;
- int cb_fid, pitch_fid, error_fid, stream_error_fid, rc_fid;
- int constrain_fid;
- char str[19];
- short s_zero = 0;
- float f_zero = 0.0;
- /* *nonhigh-passed old input speech for alignment */
- float ssubnhp[MAXLL], soldnhp[MAXLL];
- /* *sungraph variable id's */
- int status, num_read;
-
- short iint;
-
- #else
- int nrec9 = 1;
- #endif
- /* *start CELP */
- /* *set the IEEE underflow mode just like the FORTRAN */
- /* *if you uncomment the following, be sure to uncomment */
- /* *the #include <floatingpoint.h> above */
- /* ieee_handler("set","underflow", SIGFPE_DEFAULT); /* */
- #ifndef STREAMLINE
- /* *** parse the command line
-
- celp [-i ifile] [-o ofile] [-p pfile] [-q qfile] [-l lfile]
- celp [-c chan] [-o ofile]
- note: ncsize, no, and gamma2 are external variables
- note: The calls to cli & cliend may be commented out and celp will
- operate properly with default values (without bells & whistles)
- ... If synthesizer only, the celp command syntax for synthesis only
- is:
- celp -c input.chan -o ofile
- where: input.chan is a ascii hex bit stream channel file
- ofile is a ofile.spd speech file (postfiltered)
- *set analysis or synthesis only with the ANALY macro,
- *read command line,
- *and enable/disable sungraph files
- */
- /* *intialize mask */
- for (i = 0; i < STREAMBITS; i++)
- {
- mask[i] = 0;
- }
- cli(ifile, ofile, &l, &ll, &lp, &np, &scale, &descale, &ber, mask, stype,
- sbits, &eccbits, &ssum, argc, argv);
- #endif
- /* ********************* initialize******************** */
- /* *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];
- /* *enable/disable error control coding */
- protect = TRUE;
- /* *for double error detecting FEC codes (NOT USED) */
- twoerror = FALSE;
- snrflag = FALSE;
- lspflag = TRUE;
- /* *intialize 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 */
- matrixgen(CODELENGTH1, CODELENGTH2, hmatrix, syndrometable);
- /* *generate Hamming windows */
- ham(hamw, ll);
- /* *UNNECESSARY, used for distortion diagnostics */
- ham(hamws, l);
- /* *** open and define files */
- #ifdef SUNGRAPH
- /* *sungraph (tm) files */
- #include "sungraph_open.h"
- #else
- /* *input file */
- if (iodisk(3, &lun[9], ifile, &nrec9, iarf, ll) != 0)
- {
- fprintf(stderr, "*** Error opening ifile.spdn");
- exit(1);
- }
- #endif
- /* *postfiltered & nonpostfiltered output */
- if (iodisk(4, &lun[1], strcat(strcpy(tempstr, ofile), ".spd"),
- &nrec1, pf, l) != 0)
- {
- fprintf(stderr, "celp: *** Error opening ofile.spdn");
- exit(1);
- }
- #ifndef STREAMLINE
- if (iodisk(4, &lun[2], strcat(strcpy(tempstr, ofile), "npf.spd"),
- &nrec2, npf, l) != 0)
- {
- fprintf(stderr, "celp: *** Error opening ofilenpf.spdn");
- exit(1);
- }
- if (iodisk(4, &lun[3], strcat(strcpy(tempstr, ofile), "hpf.spd"),
- &nrec3, pf, l) != 0)
- {
- fprintf(stderr, "celp: *** Error opening ofilehpf.spdn");
- exit(1);
- }
- /* *bit stream channel file */
- #ifdef ANALY
- fp25 = fopen(strcat(strcpy(tempstr, ofile), ".chan"), "w");
- if (fp25 == NULL)
- {
- perror("celp: Error opening the channel file");
- exit(0);
- }
- #else
- fp25 = fopen(ifile, "r");
- if (fp25 == NULL)
- {
- perror("celp: Error opening the channel file");
- exit(0);
- }
- #endif
- #endif
- /* *generate pdtabi for delta delay coding */
- for (i = 0; i < MAXPD; i++)
- {
- pdtabi[pdencode[i]] = i;
- }
- /* ......................... m a i n l o o p ........................ */
- /* *** ANALYSIS ...................................................... */
- /* *if synthesizer only, skip analyzer >>>>>>>>>>>>>>>>>>> */
- #ifdef ANALY
- /* *** LPC spectral analysis (open loop) */
- /* NOTE: Autocorrelation was found superior to covariance analysis */
- /* *** read speech segment s of size ll, until end of file */
- #ifdef SUNGRAPH
- while ((status = read_variable(input_fid, iarf, ll, &num_read)) != -5)
- {
- if (status < 0)
- read_error(status, "read_input_fid");
- #else
- while (iodisk(1, &lun[9], ifile, &nrec9, iarf, ll) == ll)
- {
- #endif
-
- frame++;
- pointer = 0;
- /* *display a propeller (rotating bar) once per frame */
- mark(0);
- /* fprint(stderr,"frame = ",frame); */
- /* *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., mmin(scale * iarf[i], 32767.));
- #ifdef SUNGRAPH
- /* *create ssubnhp vector for sungraph */
- for (i = 0; i < ll/2; i++)
- {
- ssubnhp[i] = soldnhp[i + ll/2];
- ssubnhp[i + ll/2] = snew[i];
- }
- /* *save input speech in file 'ifile_ofile' */
- save_sg(ifile_vid, ssubnhp, ll, "save speech_in_vid");
- /* *save snew in soldnhp for sungraph in next frame */
- for (i = 0; i < ll; i++)
- soldnhp[i] = snew[i];
- #endif
-
- /* *high pass filter snew */
- zerofilt(ahpf, 2, dhpf1, snew, ll);
- polefilt(bhpf, 2, dhpf2, snew, ll);
- /* *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];
- }
- #ifdef SUNGRAPH
- /* *save high-passed future input in file 'ifile_ofile' */
- save_sg(ifile_hp_vid, ssub, ll, "save ifile_hp_vid");
- #endif
- autohf(snew, hamw, ll, no, OMEGA, fcn, rcn);
- #ifdef SUNGRAPH
- /* *save rc's in file 'rc' */
- for (i = 0; i < no; i++)
- save_sg(rc_vid[i], &rcn[i], 1, "save rc_vid");
- #endif
- /* *pc -> lsp (new) */
- pctolsp2(fcn, no, newfreq, &lspflag);
- if (lspflag)
- {
- printf("celp: Bad "new" lsp at frame: %dn", frame);
- printf("lsp: ");
- for (i = 0; i < no; i++)
- printf("%9.5f", newfreq[i]);
- printf("npc: ");
- for (i = 0; i < no + 1; i++)
- printf("%9.5f", fcn[i]);
- printf("nrc: ");
- for (i = 0; i < no; i++)
- printf("%9.5f", rcn[i]);
- printf("n");
- }
- /* *save unquantized lsp */
- for (i = 0; i < no; i++)
- unqfreq[i] = newfreq[i];
- /* *quantize lsp's */
- lsp34(newfreq, no, sbits, findex);
- #ifdef SUNGRAPH
- /* *save future lsp variables in file 'lsp1' */
- for (i = 0; i < no; i++)
- {
- save_sg(lsp_vid[i], &unqfreq[i], 1, "save lsp_vid");
- }
- /* *save future qlsp variables in file 'lsp1' */
- for (i = 0; i < no; i++)
- {
- save_sg(qlsp_vid[i], &newfreq[i], 1, "save qlsp_vid");
- }
- #endif
- #ifndef STREAMLINE
- /* *measure spectral distortion */
- /* UNNECESSARY, used for diagnostices */
- specdist(unqfreq, newfreq, dm2, sumdm2, &framedm2);
- #endif
- /* *pack lsp indices in bit stream array */
- for (i = 0; i < no; i++)
- pack(findex[i], sbits[i], stream, &pointer);
- /* *linearly interpolate LSP's for each subframe */
- intanaly(newfreq, nn, lsp);
- /* *** for each subframe, search stochastic & adaptive code books */
- k = 0;
- for (i = 0; i < nn; i++)
- {
- #ifdef SUNGRAPH
- /* *save interpolated lsp's in file 'lsp2' */
- for (j = 0; j < no; j++)
- save_sg(lsp_analy_vid[j], &lsp[i][j], 1, "save lsp_analy_vid");
- #endif
- lsptopc(&lsp[i][0], fci);
- for (j = 0; j < no + 1; j++)
- fc[j] = fci[j];
- nseg++;
- /* *** code book & pitch searches */
- csub(&ssub[k], &v[k], l, lp);
- #ifdef SUNGRAPH
- /* *save code book index in file 'cbindex' */
- save_sg(cb_index_vid, &cbindex, 1, "save cb_index_vid");
- /* *save tau in file 'pitch' */
- save_sg(pitch_tau_vid, &bb[0], 1, "save pitch_tau_vid");
- #endif
- /* *pitch quantization tau */
- /* *pack parameter indices in bit stream array */
- if (((i+1) % 2) != 0)
- packtau(tauptr-minptr, pbits[0], pdencode, stream, &pointer);
- else
- pack(tauptr-minptr, pbits[1], stream, &pointer);
- pack(pindex, pbits[2], stream, &pointer);
- cbindex--;
- pack(cbindex, cbbits, stream, &pointer);
- pack(gindex, cbgbits, stream, &pointer);
- /* *decode parameters for analysis by synthesis */
- cbindex++;
- /* *pitch synthesis (UNNECESSARY, used for diagnostics) */
- pitchvq(&v[k], l, dpa, idb, bb, "long");
- /* *pitch pre filter (UNNECESSARY, used for diagnostics) */
- if (prewt != 0.0)
- prefilt(&v[k], l, dppa);
- /* *lpc synthesis (UNNECESSARY, used for diagnostics) */
- polefilt(fci, no, dsa, &v[k], l);
- k += l;
- }
- /* *** bit error protection */
- /* *extract bits to protect from stream array */
- if (protect)
- {
- for (i = 0; i < CODELENGTH2; i++)
- codeword[i] = stream[bitprotect[i] - 1];
- /* *hamming encode */
- encodeham(CODELENGTH1, CODELENGTH2, hmatrix, &paritybit, codeword);
- /* *pack future bit */
- pack(0, 1, stream, &pointer);
- /* *pack parity bits */
- for (i = 0; i < PARITYLENGTH; i++)
- pack(codeword[CODELENGTH2 + i], 1, stream, &pointer);
- /* *toggle and pack the sync bit */
- sync = sync ^ 1;
- pack(sync, 1, stream, &pointer);
- }
- #ifdef SUNGRAPH
- /* *save stream array in channel file */
- save_sg(channel_vid, stream, STREAMBITS, "save channel_vid");
- /* *save stream array in stream_error file */
- save_sg(stream_vid, stream, STREAMBITS, "save stream_vid");
- #endif
- #ifndef STREAMLINE
- /* *save stream */
- for (i = 0; i < STREAMBITS; i++)
- savestream[i] = stream[i];
- /* *permute bitstream */
- for (i = 0; i < STREAMBITS; i++)
- pstream[i] = stream[bitpermute[i] - 1];
- /* *save stream in Dave's format */
- puthex(STREAMBITS, pstream, line);
- fprintf(fp25, "%sn", line);
- #endif
- /* *synthesizer only <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */
- #else
- /* *** CHANNEL .................................................. */
- /* *read in channel file (if synthesis only) */
- while (fscanf(fp25, "%s", line) != EOF)
- {
- pointer = -1;
- gethex(STREAMBITS, pstream, line);
- frame++;
- /* *display a propeller (rotating bar) once per frame */
- mark(0);
- #endif
- #ifndef STREAMLINE
- /* *unpermute bitstream */
- for (i = 0; i < STREAMBITS; i++)
- stream[bitpermute[i] - 1] = pstream[i];
- /* *** corrupt the channel with bit errors */
- biterror(ber, mask, stream, STREAMBITS, &error, &total);
- #endif
- #ifdef SUNGRAPH
- /* *save stream array in stream_error file */
- save_sg(stream_error_vid, stream, STREAMBITS, "save stream_error_vid");
- #endif
- /* *** SYNTHESIS .......................................... */
- /* *unpack parity bits */
- if (protect)
- {
- pointer = pointer - PARITYLENGTH - 2;
- #ifndef ANALY
- pointer = 138;
- #endif
- for (i = 0; i < PARITYLENGTH; i++)
- unpack(stream, 1, &codeword[CODELENGTH2 + i], &pointer);
- /* *extract code word from stream array */
- for (i = 0; i < CODELENGTH2; i++)
- codeword[i] = stream[bitprotect[i] - 1];
- /* repack Bisnu bit (remains constant for now) */
- codeword[10] = 0;
- /* *Hamming decode */
- decodeham(CODELENGTH1, hmatrix, syndrometable, paritybit, codeword,
- &twoerror, &syndrome);
- /* *disable parity check (if parity not used) */
- twoerror = FALSE;
- /* *bit error rate estimator (running avg of bad syndromes) */
- if (syndrome != 0)
- syndrome = 1;
- syndavg = (1.0 - (1.0 / SYNDRUN)) * syndavg + (1.0 / SYNDRUN) * (float) syndrome;
- /* *repack protected bits */
- for (i = 0; i < CODELENGTH2; i++)
- stream[bitprotect[i] - 1] = codeword[i];
- #ifdef SUNGRAPH
- /* *save stream array in stream_error file */
- save_sg(stream_error_s_vid, stream, STREAMBITS, "save stream_error_s_vid");
- /* *compare saved stream with channel stream */
- for (i = 0; i < STREAMBITS; i++)
- {
- if (savestream[i] != stream[i])
- {
- iint = 1;
- save_sg(bit_error_vid, &iint, 1, "save bit_error_vid");
- }
- else
- {
- iint = 0;
- save_sg(bit_error_vid, &iint, 1, "save bit_error_vid");
- }
- }
- #endif
- /* *frame repeat if two errors detected in code word */
- if (twoerror)
- printf("celp: two errors have occured in frame %dn", frame);
- }
- pointer = -1;
- /* *unpack data stream */
- for (i = 0; i < no; i++)
- unpack(stream, sbits[i], &findex[i], &pointer);
- /* *decode lsp's */
- lspdecode34(findex, no, newfreq);
- /* *interpolate spectrum lsp's for nn subframes */
- intsynth(newfreq, nn, lsp, twoerror, syndavg);
- /* *decode all code book and pitch parameters */
- bitpointer = pointer;
- dcodtau(pbits[0], pbits[1], bitsum1, bitsum2, &bitpointer, nn, stream, pddecode, pdtabi, taus);
- dcodpg(pbits[2], bitsum1, bitsum2, &bitpointer, nn, stream, pgs);
- dcodcbi(cbbits, bitsum1, bitsum2, &bitpointer, nn, stream, cbi);
- dcodcbg(cbgbits, bitsum1, bitsum2, &bitpointer, nn, stream, cbg);
- /* *** synthesize each subframe */
- #ifdef ANALY
- nseg -= nn;
- #endif
- k = 0;
- for (i = 0; i < nn; i++)
- {
- nseg++;
- #ifdef SUNGRAPH
- /* *save interpolated lsp's in file 'lsp2' */
- for (j = 0; j < no; j++)
- save_sg(lsp_synth_vid[j], &lsp[i][j], 1, "save lsp_synth_vid");
- #endif
- /* *decode values for subframe */
- cbindex = cbi[i];
- decodedgain = cbg[i];
- if (protect)
- smoothcbgain(&decodedgain, twoerror, syndavg, cbg, i + 1);
- /* *code book synthesis */
- vdecode(decodedgain, l, &vdecoded[k]);
- if (protect)
- smoothtau(&taus[i], twoerror, syndavg, taus[2], i + 1);
- bb[0] = taus[i];
- bb[2] = pgs[i];
- if (protect)
- smoothpgain(&bb[2], twoerror, syndavg, pgs, i + 1);
- #ifdef SUNGRAPH
- /* *save synthesis parameters in sungraph files */
- save_sg(cb_index_synth_vid, &cbindex, 1, "save cb_index_synth_vid");
- save_sg(pitch_tau_synth_vid, &bb[0], 1, "save pitch_tau_synth_vid");
- save_sg(cb_qgain_synth_vid, &decodedgain, 1, "save cb_qgain_synth_vid");
- save_sg(pitch_qgain_synth_vid, &bb[2], 1, "save pitch_qgain_synth_vid");
- #endif
- /* *pitch synthesis */
- pitchvq(&vdecoded[k], l, dps, idb, bb, "long");
- /* *pitch pre filter (synthesis) */
- if (prewt != 0.0)
- prefilt(&vdecoded[k], l, dpps);
- /* convert lsp's to pc's */
- lsptopc(&lsp[i][0], fci);
- /* lpc synthesis */
- polefilt(fci, no, dss, &vdecoded[k], l);
- #ifndef STREAMLINE
- /* *** check analysis versus synthesis speech */
- #ifdef ANALY
- flag = FALSE;
- for (j = 0; j < l; j++)
- {
- if (fabs(v[k + j] - vdecoded[k + j]) > 1.e-6)
- flag = TRUE;
- }
- if (flag)
- printf("celp: Speech mismatch at frame %dn", frame);
- #endif
- /* *** write nonpostfiltered output speech disk files */
- for (j = 0; j < l; j++)
- {
- vdecoded[k + j] = descale * vdecoded[k + j];
- npf[k + j] = nint(mmax(-32768., mmin(32767., vdecoded[k + j])));
- }
- /* *write npf output speech file "ofilenpf" */
- if (iodisk(2, &lun[2], strcat(strcpy(tempstr, ofile), "npf.spd"),
- &nrec2, &npf[k], l) != l)
- {
- fprintf(stderr, "celp: *** Error writing ofilenpf.spdn");
- exit(1);
- }
- #ifdef SUNGRAPH
- /* *sungraph's npf output speech file 'ifile_ofile' */
- save_sg(ofile_npf_vid, &npf[k], l, "save ofile_npf_vid");
- #endif
- /* *** calculate the average segmental SNR */
- /* *UNNECESSARY, used for diagnostics */
- #ifdef ANALY
- segsnr(&ssub[k], &npf[k], l, &sumsnr, &framesnr, &snrflag);
- /* *** calculate distortions/distances (log spectral error, etc.) */
- /* *UNNECESSARY, used for diagnostics */
- if (snrflag)
- distortion(&ssub[k], &npf[k], hamws, l, no, dm, sumdm, &framedm);
- #endif
- #endif
- /* *** post filtering */
- postfilt(&vdecoded[k], l, ALPHA, BETA, &ip, &op, dp1, dp2, dp3);
- /* *** test for output speech clipping */
- while (clip(&vdecoded[k], l))
- {
- /* frame repeat & recall synthesizer? */
- /* or scale vdecoded? */
- printf("celp: Clipping detected at frame %dn", frame);
- for (j = 0; j < l; j++)
- vdecoded[k + j] = 0.05 * vdecoded[k + j];
- }
- /* *** write postfiltered output speech disk files */
- for (j = 0; j < l; j++)
- pf[k + j] = nint(mmax(-32768., mmin(32767., vdecoded[k + j])));
- /* *write output speech file "ofile" */
- if (iodisk(2, &lun[1], strcat(strcpy(tempstr, ofile), ".spd")
- ,&nrec1, &pf[k], l) != l)
- {
- fprintf(stderr, "celp: *** Error writing ofile.spdn");
- exit(1);
- }
- #ifdef SUNGRAPH
- /* *sungraph's output speech file 'ifile_ofile' */
- save_sg(ofile_pf_vid, &pf[k], l, "save ofile_pf_vid");
- #endif
- #ifndef STREAMLINE
- /* *high pass filter output speech */
- zerofilt(ahpfo, 2, dhpf1o, &vdecoded[k], l);
- polefilt(bhpfo, 2, dhpf2o, &vdecoded[k], l);
- for (j = 0; j < l; j++)
- pf[k + j] = nint(mmax(-32768., mmin(32767., vdecoded[k + j])));
- /* *write output speech file "ofilehpf" */
- if (iodisk(2, &lun[3], strcat(strcpy(tempstr, ofile), "hpf.spd")
- ,&nrec3, &pf[k], l) != l)
- {
- fprintf(stderr, "celp: *** Error writing ofilehpf.spdn");
- exit(1);
- }
- #ifdef SUNGRAPH
- /* *sungraph's output speech file 'ifile_ofile' */
- save_sg(ofile_hpf_vid, &pf[k], l, "save ofile_hpf_vid");
- #endif
- #endif
- k += l;
- }
- /* .......................end block................................. */
- #ifdef SUNGRAPH
- #include "sungraph_endblock.h"
- #endif
- /* *** shift new speech buffer into old speech buffer */
- /* sold snew */
- /* |-------------------|-------------------| snew */
- /* |-------------------| */
- /* ssub */
- for (i = 0; i < ll; i++)
- sold[i] = snew[i];
- /* *** frame finished, end loop */
- } /* end main while loop; either the analyzer loop, analyzer and */
- /* sungraph loop or the synthesizer only loop */
- /* ...........e n d m a i n l o o p ............................... */
- /* *** WRAP-UP ...................................................... */
- /* *** finished reading & processing "ifile" */
- /* *** closing cue and close files */
- for (i = 0; i < STREAMBITS; i++)
- stream[i] = 23456;
- iodisk(-1, &lun[1], strcat(strcpy(tempstr, ofile), ".spd"),
- &nrec1, pf, l);
- #ifndef STREAMLINE
- iodisk(-1, &lun[2], strcat(strcpy(tempstr, ofile), "npf.spd"),
- &nrec2, npf, l);
- iodisk(-1, &lun[3], strcat(strcpy(tempstr, ofile), "hpf.spd"),
- &nrec3, pf, l);
- fclose(fp25);
- #endif
- #ifdef SUNGRAPH
- #include "sungraph_close.h"
- #else
- iodisk(-1, &lun[9], ifile, &nrec9, iarf, ll);
- #endif
- #ifndef STREAMLINE
- #ifdef ANALY
- if (total != 0)
- realerror = 100. * ((float) error / (float) total);
- else
- realerror = 0.0;
- cliend(sumsnr, framesnr, realerror, sumdm, framedm, sumdm2, framedm2);
- #endif
- #endif
- exit(0);
- }