📄 lp_anal.c
字号:
#include "main.h"#include "showdata.h"#include <stdlib.h>#include <stdio.h>#include <math.h>#include "lp_anal.h"#include "pctolsf.h"#include "bwexp.h"#include "celp_sup.h"#include "code_lsf.h"#include "setarray.h"
/* I can't figure out how to insert this in the makefile under MS
Developer, so I'm just going to set it here! */
#define DURBIN 1static void ApplyWindow(float SpeechIn[F_LEN],float HamSpeech[F_LEN]);static void AutoCor(float speech_in[F_LEN], float ac[ORDER+1]);static void ACtoPC(float ac[ORDER+1],float pc[ORDER+1]);static void ACtoRC(float ac[ORDER+1],float rc[ORDER],float *err);static void HighFreqCorrect(float ac[ORDER+1],float alpha);static void RCtoPC(float k[ORDER], float pc[ORDER]);static void Durbin(float ac[], float pc[]);/*************************************************************************** ** ROUTINE* LP_Analysis** FUNCTION* Linear Predictive analysis* SYNOPSIS* LP_Analysis(SpeechIn, qlsf, frame_num)** formal** data I/O* name type type function* -------------------------------------------------------------------* SpeechIn float i Frame of input speech* qlsf float o Frame of quantized LSFs* frame_num int i CELP frame number***************************************************************************** DESCRIPTION** This performs an autocorrelation LP analysis of speech* returning a set of line spectral frequencies representing* the spectrum of the input speech signal.***************************************************************************** CALLED BY** Analysis** CALLS** ApplyWindow AutoCor ACtoPC BWexp_PCs PCtoLSF QuanLSF ****************************************************************************/#define TRUE 1#define FALSE 0void LP_Analysis(float SpeechIn[F_LEN],float qlsf[ORDER],int frame_num){float lsf[ORDER+1];float ac[ORDER+1], pc[ORDER+1], pcexp[ORDER+1];float HamSpeech[F_LEN];int findex[ORDER];/* Apply Hamming window to Input Speech */ ApplyWindow(SpeechIn, HamSpeech);/* Calculate Autocorrelations */ AutoCor(HamSpeech, ac);/* Convert ACs to PCs */ ACtoPC(ac, pc);/* Bandwidth Expand PCs */ BWExpand(OMEGA, pc, pcexp);/* Convert PCs to LSFs */ PCtoLSF(pcexp, lsf);/* Quantize the LSFs */ QuanLSF(lsf, qlsf, findex);}/*************************************************************************** ** ROUTINE* ApplyWindow** FUNCTION* Apply a Hamming Window to input speech* SYNOPSIS* ApplyWindow(SpeechIn, HamSpeech)** formal** data I/O* name type type function* -------------------------------------------------------------------* SpeechIn float i Frame of input speech* HamSpeech float o Frame of output speech***************************************************************************/void ApplyWindow(float SpeechIn[F_LEN],float HamSpeech[F_LEN]){static int first=TRUE;static float HamWindow[F_LEN];int i;/* Generate Hamming window */ if(first) { first=FALSE; CreateHam(HamWindow, F_LEN); }/* Apply Hamming window to input speech */ for(i=0;i<F_LEN;i++) { HamSpeech[i] = SpeechIn[i] * HamWindow[i]; }}/*************************************************************************** ** ROUTINE* AutoCor** FUNCTION* Calculate the autocorrelations for a frame of speech* SYNOPSIS* AutoCor(speech_in, ac)** formal** data I/O* name type type function* -------------------------------------------------------------------* speech_in float i Frame of input speech* ac float o Autocorrelations***************************************************************************/void AutoCor(float speech_in[F_LEN], float ac[ORDER+1]){int i, j;/* Calculate autocorrelations */ for (i=0; i<ORDER+1; i++) { for (ac[i]=0, j=i; j<F_LEN; j++) ac[i]+=speech_in[j]*speech_in[j-i]; }}/*************************************************************************** ** ROUTINE* ACtoPC** FUNCTION* Calculate the Predictor Coefficients for a frame of speech* SYNOPSIS* ACtoPC(ac, pc)** formal** data I/O* name type type function* -------------------------------------------------------------------* ac float i Autocorrelations* pc float o Predictor Coefficients***************************************************************************/void ACtoPC(float ac[ORDER+1],float pc[ORDER+1]){float alpha;float rc[ORDER];#ifdef DURBIN/* Use Durbin recursion to convert from ACs to PCs */ SetArray(ORDER+1, 0.0, pc); pc[0] = 1.0; Durbin(ac, pc);#else/* Convert ACs to RCs */ ACtoRC(ac, rc, &alpha);/* Perform high frequency correction */ HighFreqCorrect(ac, alpha);/* Convert corrected ACs to RCs */ ACtoRC(ac, rc, &alpha);/* Convert corrected RCs to PCs */ RCtoPC(rc, pc);#endif}/******************************************************************************* NAME* Durbin*** SYNOPSIS** subroutine Durbin (ac, pc)** formal * data I/O* name type type function* -------------------------------------------------------------------* ac[ORDER] real i auto-correlation coefficients* pc[ORDER+1] real o prediction coeffs (voiced-> +pc[1])* ***************************************************************************** * DESCRIPTION** This performs the classical Durbin recursion* on the correlation sequence c[0], c[1], c[2] . . .* to obtain n reflection coefficients (rc).** The sign convention used defines the first reflection coefficient* as the normalized first autocorrelation coefficient, which results* in positive values of rc[0] for voiced speech.******************************************************************************* CALLED BY** ACtoPC** CALLS** SetArray ****************************************************************************** ** REFERENCES** Parsons, Voice and Speech Processing, McGraw-Hill, 1987, p.160&378.*****************************************************************************/void Durbin(float ac[], float pc[]){ int i, j; float alpha, beta, rc[ORDER], tmp[ORDER]; /* If zero energy, set rc's to zero & return */ if (ac[0] <= 0.0) { for (i = 0; i < ORDER; i++) rc[i] = 0.0; return; } /* Intialization */ alpha = ac[0]; pc[0] = rc[0] = -ac[1] / ac[0]; beta = ac[1]; /* Recursion */ for (i = 1; i < ORDER; i++) { alpha = alpha + beta * rc[i - 1]; beta = ac[i+1]; for (j = 0; j <= i - 1; j++) beta = beta + ac[j+1] * pc[i-j-1]; rc[i] = -beta / alpha; for (j = 0; j <= i - 1; j++) tmp[j] = rc[i] * pc[i-j-1]; for (j = 0; j <= i - 1; j++) pc[j] = pc[j] + tmp[j]; pc[i] = rc[i]; } /* Rearrange array ordering and set pc[0]=1 */ for (i = ORDER+1; i > 0; i--) pc[i] = pc[i-1]; pc[0] = 1;} /***************************************************************************** NAME* ACtoRC ** FUNCTION** Schur recursion to do autocorrelation analysis.* Converts autocorrelation sequence to reflection coefficients.** SYNOPSIS** subroutine ACtoRC (ac, rc, err)** formal * data I/O* name type type function* -------------------------------------------------------------------* ac(ORDER+1) float i auto-correlation coefficients* rc(ORDER) float o reflection coefficients (voiced->+rc1)* err float i/o normalized prediction error* **************************************************************************** * DESCRIPTION** This performs the classical Schur recursion (rediscovered by* LeRoux & Guegen) on the correlation sequence ac(0), ac(1), ac(2)...* to obtain n reflection coefficients (rc). The recursion can be* performed entirely in fractional arithemetic because the* correlation sequence is normalized by ac(0), so all the quantities* in the recursion are less than unity magnitude (except ac(0)).** The sign convention used defines the first reflection coefficient* as the normalized first autocorrelation coefficient, which results* in positive values of rc(1) for voiced speech.****************************************************************************** CALLED BY** ACtoPC** CALLS** SetArray***************************************************************************** * REFERENCES** Parsons, Voice and Speech Processing, McGraw-hill, 1987, p.160&378.****************************************************************************** PROCESS DESCRIPTION** Name Type Function** d float Recursion sequence (dim n)* g float Recursion sequence (dim n)* p int Orderindex recursion* err float Backward error* err0 float Backward error of order 0***************************************************************************/void ACtoRC(float ac[ORDER+1],float rc[ORDER],float *err){ float *d, *g, rch; int i, p; d=(float *)calloc(ORDER, sizeof(float)); if(d == NULL) { printf("Error callocating memory (d) in actorc\n"); exit(1); } g=(float *)calloc(ORDER, sizeof(float)); if(g == NULL) { printf("Error callocating memory (g) in actorc\n"); exit(1); }/* If zero energy, set rc's to zero & return */ if (ac[0] <= 0.0) { SetArray(ORDER, 0.0, rc); return; } for (i = 0; i < ORDER; i++) g[i] = d[i] = ac[i+1] / ac[0]; rch = g[0]; rc[0] = rch; *err = 1. - rch * rch; for (p = 1; p < ORDER; p++) { for (i = 0; i < ORDER - p; i++) { g[i] = g[i+1] - rch * d[i]; d[i] = d[i] - rch * g[i+1]; }/* Extract the reflection coefficient */ rch = g[0] / *err; rc[p] = rch;/* The mean squares error recursion */ *err = *err * (1. - rch * rch); } free(d); free(g);}/*************************************************************************** ** ROUTINE* HighFreqCorrect** FUNCTION* Perform high frequency correction on input * (eq. 16, Atal & Schroeder)* SYNOPSIS* HighFreqCorrect(ac, alpha)** formal** data I/O* name type type function* -------------------------------------------------------------------* ac float i Frame of autocorrelation coefficients* alpha float i Normalized prediction error***************************************************************************/void HighFreqCorrect(float ac[ORDER+1],float alpha){float lemin;/* Unnormalized prediction error scaled by lambda */ lemin = LAMBDA * ac[0] * alpha; /* High Frequency Correction */ ac[0] += 0.375 * lemin; ac[1] -= 0.25 * lemin; ac[2] += 0.0625 * lemin;}/***************************************************************************** NAME* RCtoPC** FUNCTION** convert reflection coefficients into lpc coefficients** BEWARE: This code does not use memory efficiently.** SYNOPSIS** subroutine RCtoPC(k, pc)** formal * data I/O* name type type function* -------------------------------------------------------------------* k float i reflection coefficients (m)* pc float o predictor parameters (m+1: a(1)=1.0)***************************************************************************** * DESCRIPTION** Converts reflection coefficients into lpc coefficients.** CELP's LP predictor coefficient convention is:* p+1 -(i-1)* A(z) = SUM a z where a = +1.0* i=1 i 1******************************************************************************* CALLED BY** ACtoPC***************************************************************************** * REFERENCES** Rabiner & Schafer, Digital Processing of Speech Signals,* Prentice-Hall, 1978, p. 443, equations 8.131a&b&c.***************************************************************************/void RCtoPC(float k[ORDER], float pc[ORDER]){ int i, j; float a[ORDER+1][ORDER+1];/* intialize the array */ for (i = 0; i <= ORDER; i++) { for (j = 0; j <= ORDER; j++) { a[j][i] = 0.0; } }/* convert reflection coefficients */ for (i = 1; i <= ORDER; i++) { a[i][i] = k[i-1]; for (j = 1; j <= i-1; j++) a[j][i] = a[j][i-1] - k[i-1] * a[i-j][i-1]; } pc[0] = 1.0; for (j = 1; j <= ORDER; j++) pc[j] = -a[j][ORDER];}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -