📄 hvxcpchenc.c
字号:
/*This software module was originally developed by Kazuyuki Iijima, Jun Matsumoto (Sony Corporation) and edited by Akira Inoue (Sony Corporation) in the course of development of the MPEG-4 Audio standard (ISO/IEC 14496-3). This software module is an implementation of a part of one or more MPEG-4 Audio (ISO/IEC 14496-3) tools as specified by the MPEG-4 Audio standard (ISO/IEC 14496-3). ISO/IEC gives users of the MPEG-4 Audio standards (ISO/IEC 14496-3) free license to this software module or modifications thereof for use in hardware or software products claiming conformance to the MPEG-4 Audio standards (ISO/IEC 14496-3). Those intending to use this software module in hardware or software products are advised that this use may infringe existing patents. The original developer of this software module and his/her company, the subsequent editors and their companies, and ISO/IEC have no liability for use of this software module or modifications thereof in an implementation. Copyright is not released for non MPEG-4 Audio (ISO/IEC 14496-3) conforming products. The original developer retains full right to use the code for his/her own purpose, assign or donate the code to a third party and to inhibit third party from using the code for non MPEG-4 Audio (ISO/IEC 14496-3) conforming products. This copyright notice must be included in all copies or derivative works. Copyright (c)1996. */#include <math.h>#include <stdio.h>#include <stdlib.h>#include "hvxc.h"#include "hvxcEnc.h"#include "hvxcCommon.h"#define RSD_SIZE 256#define AL 512#define POWER 9#define Lmin 20#define Lmax 148#define FILTER_ORDER 18#define PEAKMAX (Lmax-Lmin)#define FB_STATE_HOLD 4#define Np 10#define ACL 512#define LPF_PI3per4 0#define LPF_PIper2 1#define LPF_PI3per8 2#define LPF_PIper4 3#define LPF_PIper8 4#define LPF_OFFSET 5#define HPF_PI3per4 (0 + LPF_OFFSET)#define HPF_PI4per5 (1 + LPF_OFFSET)#define HPF_PI7per8 (2 + LPF_OFFSET)#define HPF_PI1per8 (3 + LPF_OFFSET)#define HPF_PI1per4 (4 + LPF_OFFSET)#define THROUGH (5 + LPF_OFFSET)#include "hvxcPchEnc.h"#define LARGELEVEL 2000.0extern int ipc_encDelayMode;extern int ipc_decDelayMode;typedef struct{ float pitch, framePower, prob, r0r, peak0, ac[AL]; float engRatio; int scanLmt, peakPos[PEAKMAX];}PitchPrm;typedef struct { float pitch; float prob; float r0r; float rawR0r; float rawPitch;}NgbPrm;static float global_pitch = 0.0;static float prevGp = 0.0;extern float ipc_coef[SAMPLE];extern int judge;extern int HVXCclassifierMode;static void swap_f(float s[],int i,int j){ float tmp; tmp = s[i]; s[i] = s[j]; s[j] = tmp;}static void swap_i(int s[],int i,int j){ int tmp; tmp = s[i]; s[i] = s[j]; s[j] = tmp;}static void sort(int v[],int begin,int end){ int i,last; if ( begin>=end ) return; swap_i( v, begin, (begin+end)/2 ); last = begin; for(i=begin+1; i<=end; i++) if (v[i]<v[begin]){ swap_i(v, ++last, i); } swap_i( v, begin, last ); sort( v, begin, last-1 ); sort( v, last+1, end );}static void sort2(float v[],int begin,int end,int w[]){ int i,last; if ( begin>=end ) return; swap_f( v, begin, (begin+end)/2 ); swap_i( w, begin, (begin+end)/2 ); last = begin; for(i=begin+1; i<=end; i++) if (v[i]>v[begin]){ swap_f(v, last+1, i); swap_i(w, ++last, i); } swap_f( v, begin, last ); swap_i( w, begin, last ); sort2( v, begin, last-1, w ); sort2( v, last+1, end, w );}static void auto_corr(int n,int p,float w[],float x[],float r[]){ int i,j; static float wx[ ACL ]; for(i=0; i<n; i++) wx[i] = w[i] * x[i]; for(i=0; i<=p; i++) { r[i] = 0.0; for(j=0; j<=n-1-i; j++) { r[i] += wx[j] * wx[j+i]; } }}static float lpc2(int n, /* data number */float w[], /* window data */float x[], /* data */int p, /* LPC order */float a[]) /* (disired) LPC coef */{ float u; float *r; int i, j, k, l; float a0[Np+1]; float lag_w[11]; lag_w[0]=1.0; lag_w[1]=0.9994438; lag_w[2]=0.9977772; lag_w[3]=0.9950056; lag_w[4]=0.9911382; lag_w[5]=0.9861880; lag_w[6]=0.9801714; lag_w[7]=0.9731081; lag_w[8]=0.9650213; lag_w[9]=0.9559375; lag_w[10]=0.9458861; r = (float *)malloc( sizeof(float) * (p+1) ); auto_corr( n, p, w, x, r ); for(i = 0; i <= p; i++) { r[i] *= lag_w[i]; } u = r[0]; a0[0] = a[0] = 1.0; for(i=1; i<=p; i++){ a[i] = r[i]; for(j=1; j<i; j++) a[i] += a0[j]*r[i-j]; a[i] = -a[i]/(u+EPS); for(k=1; k<i; k++) a[k] = a0[k] + a[i]*a0[i-k]; u = (1.0-a[i]*a[i])*u; for(j=0; j<=i; j++) a0[j] = a[j]; if(( u/(r[0]+EPS) < 0.000001) && (i+1<=p )) { fprintf(stderr, "stop lpc %d\n", i + 1); for(l=i+1;l<=p;l++) a[l]=0.; break; } } free((char *) r); return( u );} static void get_residual(int n,int np,float a[],float x[],float r[]){ int i, p; for(i=0; i<n; i++){ r[i] = x[i]; for(p=1; p<=np; p++){ if (i-p>=0) r[i] += a[p] * x[i-p]; } }}static void zero_supress(int n,float x[]){ int i; for(i=0; i<n; i++) x[i] = 0.0;}static float get_frame_power(float s[]){ int i; float framePower; framePower = 0.0; for(i=0; i<RSD_SIZE; i++) framePower += s[i]*s[i]; framePower = framePower * 8.0 / (16384.0*16384.0); return( framePower );}static int Ambiguous(float p0,float p1,float d){ int cnd; cnd = fabs(p0 - 2.0 * p1) / (p0+EPS) < d || fabs(p0 - p1 / 2.0) / (p0+EPS) < d || fabs(p0 - 3.0 * p1) / (p0+EPS) < d || fabs(p0 - p1 / 3.0) / (p0+EPS) < d; return(cnd);}static int NearPitch(float p0,float p1,float ratio){ return((p0 * (1.0 - ratio) < p1) && (p1 < p0 * (1.0 + ratio)));}static int CheckAmbiguousPitch(float lev,float *peak,int peak_pos[PEAKMAX]){ float ambgRatio; if(lev>1000.0) { ambgRatio = 1.2; } else { ambgRatio = 1.5; } if(peak[0] / (peak[1]+EPS) < ambgRatio && (abs(peak_pos[0] - 2 * peak_pos[1]) < 5 || abs(2 * peak_pos[0] - peak_pos[1]) < 5)) { return(1); } else { return(0); }} static float gpMax = 0.0;static float gpMin = 148.0;static int CheckGlobalPitch(NgbPrm *crntPrm,NgbPrm *prevPrm,float lev,int peakPos[PEAKMAX],float fb){ static int gpState = 0; static int gpcd = 0; static int fbState = 0; static int gpHoldState = 0; int gpSetFlag; gpSetFlag = 0; if((peakPos[0] > global_pitch * 0.6) && (peakPos[0] < global_pitch * 1.8) && (crntPrm->r0r > 0.39 && lev > LARGELEVEL && peakPos[0] <= 100) || crntPrm->r0r > 0.65 || (crntPrm->r0r > 0.30 && abs(peakPos[0] - gpcd) < 8) && lev > 400.0) { if(gpState==1 && abs(peakPos[0] - gpcd) < 8 && ((!Ambiguous(global_pitch, (float) peakPos[0], 0.11) && !Ambiguous(prevPrm->pitch, (float) peakPos[0], 0.11)) || crntPrm->r0r > 0.65)) { gpState=1; if(global_pitch != 0.0) { prevGp = global_pitch; } global_pitch = (float)peakPos[0]; gpSetFlag = 1; gpHoldState = 0; } else { if(NearPitch(gpcd, (float) peakPos[0], 0.2) && !NearPitch(gpcd, global_pitch, 0.2)) { global_pitch = 0.0; gpHoldState = 0; } gpState=1; } gpcd=peakPos[0]; if(!NearPitch(gpcd, global_pitch, 0.2) && !Ambiguous(gpcd, global_pitch, 0.11)) { global_pitch = 0.0; gpHoldState = 0; } } else { gpState=0; } if(gpHoldState == 5) { if(global_pitch != 0.0) { prevGp = global_pitch; } global_pitch = 0.0; gpHoldState = 0; } else { gpHoldState++; } if(fb == 0.0) { if(fbState == FB_STATE_HOLD) { if(global_pitch != 0.0) { prevGp = global_pitch; } global_pitch = 0.0; } else { fbState++; } } else { fbState=0; } if(gpMax < global_pitch) { gpMax = global_pitch; } if(global_pitch != 0 && gpMin > global_pitch) { gpMin = global_pitch; } return(gpSetFlag);}static void ScanPeakPos(int *currP,float refp,float from,float to,int slim,int peakPos[PEAKMAX],float *peak,float *s,NgbPrm *ngbPrm){ int i, loopFlag; loopFlag = 1; i = 0; while(loopFlag && i < slim) { if(refp * from < (float) peakPos[i] && (float) peakPos[i] < refp * to) { loopFlag = 0; *currP = peakPos[i]; ngbPrm->pitch = (float) *currP; ngbPrm->prob = peak[0] / (peak[i]+EPS); ngbPrm->r0r = peak[0] / (s[0]+EPS); } i++; } return;}static float getpitch(NgbPrm *crntPrm,NgbPrm *prevPrm,int *scanlimit,float *framepower,float *s,int *peakPos,float *peak0,float lev){ int i, j, loopFlag; float peak[PEAKMAX]; float r0; int currP; int trkp; int reason; static int ambgs_p; static int new_ambgs_p=0; r0 = s[0]; for(i=Lmin+1,j=0; i<Lmax-1; i++) { if(s[i]-s[i-1]>0 && s[i]-s[i+1]>0 && s[i]>0.0) { peak[j] = s[i]; peakPos[j] = i; j++; } } *scanlimit = j; if(j != 0) { sort2( peak, 0, j-1, peakPos ); } else { peakPos[0] = 0; } if(r0 == 0.0) { currP = (int) global_pitch; crntPrm->r0r = 0.0; } else { currP = peakPos[0]; crntPrm->r0r = peak[0] / r0; } crntPrm->rawR0r = crntPrm->r0r; crntPrm->pitch = currP; crntPrm->prob = peak[0] / (peak[1]+EPS); *peak0 = peak[0]; ambgs_p = new_ambgs_p; new_ambgs_p = 0; new_ambgs_p = CheckAmbiguousPitch(lev, peak, peakPos); if((peakPos[0] > global_pitch * 0.4) && !new_ambgs_p && (crntPrm->r0r > 0.39 && lev > LARGELEVEL && peakPos[0] <= 100) || crntPrm->r0r > 0.65) { currP = peakPos[0]; crntPrm->pitch = (float) currP; crntPrm->prob = peak[0] / (peak[1]+EPS); crntPrm->r0r = s[currP]/(r0+EPS); } else { if(prevPrm->pitch == 0.0) { if(crntPrm->r0r > 0.25) { currP = peakPos[0]; crntPrm->pitch = (float) currP; crntPrm->prob = peak[0] / (peak[1]+EPS); crntPrm->r0r = s[currP]/(r0+EPS); } else { if(global_pitch != 0.0) { ScanPeakPos(&currP, global_pitch, 0.9, 1.1, j, peakPos, peak, s, crntPrm); } } } else { if( crntPrm->r0r > 0.30 && lev > 1000.0 && !Ambiguous((float) peakPos[0], global_pitch, 0.11) && !new_ambgs_p) { currP = peakPos[0]; crntPrm->pitch = (float) currP; crntPrm->prob = peak[0] / (peak[1]+EPS); } else if (crntPrm->r0r > 0.3 && lev>1000.0 ) { currP = peakPos[0]; crntPrm->pitch = (float) currP; crntPrm->prob = peak[0] / (peak[1]+EPS); if(global_pitch != 0.0) { if(Ambiguous(prevPrm->pitch, global_pitch, 0.11)) { trkp = (int) global_pitch; } else { trkp = (int) prevPrm->pitch; } } else if(prevGp != 0.0) { trkp = (int) prevGp; } else { trkp = (int) prevPrm->pitch; } loopFlag = 1; i=1; while(loopFlag && (i < *scanlimit) && (s[peakPos[i]]/(r0+EPS) > 0.25)) { if(abs(peakPos[i]-trkp) < abs(currP-trkp)) { loopFlag = 0; currP = peakPos[i]; crntPrm->pitch = (float) currP; crntPrm->prob = peak[i] / (peak[0]+EPS); crntPrm->r0r = peak[0] / (r0+EPS); } i++; } } else if (crntPrm->r0r<0.39 && lev>4000.0) { currP = peakPos[0]; crntPrm->pitch = (float) currP; crntPrm->prob = peak[0] / (peak[1]+EPS); crntPrm->r0r = s[currP]/(r0+EPS); } else if (crntPrm->r0r > 0.1) { reason = 0; if(new_ambgs_p) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -