📄 fe_feature.cpp
字号:
break;
case FE_PARCOR:
_lpc_parcor_basic(&frameA[0], frameSize, &acf[0], &featA[n][0], m_lpcOrder, &G);
featA[n][0] = 0;
break;
case FE_FORMANT:
{
vector<CComplex> rootsA(m_lpcOrder+1);
for(i=0;i<=m_lpcOrder;i++) rootsA[i] = 0;
_lpc_basic(&frameA[0], frameSize, &acf[0], m_lpcOrder, &G);
/* Note that we compute all formant frequencies for post-processing */
int ntmp=lpc_to_formant(&acf[0],m_lpcOrder,&featTmpA[n][0],m_lpcOrder/2,rootsA);
for(k=0;k<=m_lpcOrder/2;k++) featTmpA[n][k] *= (m_sampleRate/(float)(2*M_PI));
}
break;
case FE_LPC:
_lpc_basic(&frameA[0], frameSize, &featA[n][0], m_lpcOrder, &G);
break;
case FE_FBANK:
_filterbank_basic(&frameA[0], frameSize, &featA[n][0], m_fbOrder, fft_size, m_cepSmooth, (int)(m_sampleRate/MAX_PITCH_FREQ));
break;
case FE_MFCC:
_mel_cepstrum_basic(&frameA[0], frameSize, &featA[n][0], m_fbOrder, m_cepOrder, m_fftSize);
cepstral_window(&featA[n][0],m_cepOrder,m_lifter);
break;
case FE_PLCC:
_plp_basic(&frameA[0], frameSize, &featA[n][0], m_plccOrder, m_plpOrder);
cepstral_window(&featA[n][0],m_plccOrder,m_lifter);
break;
case FE_LPCC:
_lpc_basic(&frameA[0], frameSize, &acf[0], m_lpcOrder, &G);
lpc_to_cepstrum(&acf[0], m_lpcOrder, &featA[n][0], m_cepOrder, G);
cepstral_window(&featA[n][0],m_cepOrder,m_lifter);
break;
case FE_FTCC:
_fft_cepstrum_basic(&frameA[0], frameSize, &featA[n][0], m_cepOrder, fft_size);
cepstral_window(&featA[n][0],m_cepOrder,m_lifter);
break;
default:
assert(0);
return 0;
break;
}
}
if(fk==FE_FORMANT){
/* check formant range, noting that F0 is always zero */
formant_check_range(featTmpA, m_lpcOrder/2, frameN);
/* smooth formant trajectory */
formant_median_filter(featTmpA, m_lpcOrder/2, frameN);
formant_linear_filter(featTmpA, m_lpcOrder/2, frameN);
/* Make formant consistent with pitch information */
assert(m_pitchA.size()>0);
frameN = formant_remove_nonvoice(featTmpA, m_lpcOrder/2, frameN, m_pitchA);
/* Copy to the result variable, skipping F0 */
for(n=0;n<frameN;n++){
for(int k=0;k<dimN && k<m_lpcOrder/2+1;k++){
featA[n][k]=featTmpA[n][k+1];
}
}
}
return frameN;
}
int Fe::ReadParaFile(const char *parafile)
{
FILE *fi = fopen(parafile,"r");
if(!fi) return 0;
char line[1024], arg1[256], arg2[256];
string name;
while(fgets(line,sizeof(line)-1,fi)){
if(line[0]==0) break; // end of file
if(line[0]=='#') continue; // skip comment line
sscanf(line,"%s%s", arg1, arg2);
name=arg1;
if(name=="SAMPLING_RATE"){ m_sampleRate = atoi(arg2); }
else if(name=="WINDOW_SIZE"){ m_winSizeMs = atoi(arg2); }
else if(name=="SHIFT_SIZE"){ m_shiftSizeMs = atoi(arg2); }
else if(name=="PREEMPHASIS_FACTOR"){ m_emphFac = (float)atof(arg2); }
else if(name=="FFT_SIZE"){ m_fftSize = atoi(arg2); }
else if(name=="LPC_ORDER"){ m_lpcOrder = atoi(arg2); }
else if(name=="CEPSTRUM_ORDER"){ m_cepOrder = atoi(arg2); }
else if(name=="PLP_ORDER"){ m_plpOrder = atoi(arg2); }
else if(name=="PLP_CEPSTRUM_ORDER"){ m_plccOrder = atoi(arg2); }
else if(name=="FILTER_BANK_ORDER"){ m_fbOrder = atoi(arg2); }
else if(name=="CEPSTRAL_SMOOTHING"){ m_cepSmooth = (strcmp(arg2,"ON")==0); }
else if(name=="DITHERING"){ m_dither = (strcmp(arg2,"ON")==0); }
else if(name=="TEMPORAL_FILTER_SIZE"){ m_deltaSize = atoi(arg2); }
}
fclose(fi);
return 1;
}
int Fe::ReadTag(const char *tag, int* pTag, int ndim)
{
int i;
for(i=0;i<ndim;i++) pTag[i] = 0;
if(!tag){
for(i=0;i<ndim;i++) pTag[i] = 1;
return 1;
}
vector<char> tmp(strlen(tag)+1);
strcpy(&tmp[0],tag);
char* tmp_save = NULL;
char* p = strtok_r(&tmp[0], " ,", &tmp_save);
if(!p){
for(i=0;i<ndim;i++) pTag[i] = 1;
}
while(p){
int begin = 0, end = 0;
int len = strlen(p);
char* p_save = NULL;
if(*p == '-'){
begin = 0;
if(*(p+1) != '\0')
end = atoi(p+1);
else
end = -1;
}
else if(*(p+len-1) == '-'){
end = ndim-1;
*(p+len-1) = '\0';
begin = atoi(p);
}
else{
char* q = strtok_r(p, "-", &p_save);
if(q) begin = end = atoi(q);
q = strtok_r(NULL, "-", &p_save);
if(q) end = atoi(q);
}
for(i=begin; i<=end; i++) pTag[i] = 1;
p = strtok_r(NULL, " ,", &tmp_save);
}
return 1;
}
int Fe::GetShiftSize()
{
int nshift = (int)((m_shiftSizeMs*m_sampleRate)/1000.0+0.5);
if(nshift%2) nshift += 1;
return nshift;
}
int Fe::GetFrameSize()
{
int frameSize = (int)((m_winSizeMs*m_sampleRate)/1000.0+0.5);
if(frameSize%2) frameSize += 1;
return frameSize;
}
const char *GetFeatName(FeatKind fk)
{
assert((int)fk>=0 && (int)fk<(int)FE_NUM_FEAT);
return FE_featNameA[(int)fk];
}
string GetFeatExtension(FeatKind fk)
{
FeatKind bk=GetBaseFeatKind(fk);
string name=GetFeatName(bk);
for(int i=0;i<name.size();i++) name[i]=tolower(name[i]);
if(HasDeltaFeat(fk)) name=name+"_d";
if(HasStftFeat(fk)) {
int k=name.find("_stft");
name=name.substr(0,k);
name=name+"_s";
}
return name;
}
FeatKind GetBaseFeatKind(FeatKind fk)
{
string name=GetFeatName(fk);
int k=name.find("_D");
if(k==string::npos) return fk;
if(name[k+2]==0 || name[k+2]=='_'){
name=name.substr(0,k);
for(int i=0;i<FE_NUM_FEAT-1;i++){
if(strcmp(FE_featNameA[i],name.c_str())==0) return (FeatKind)i;
}
}
return fk;
}
FeatKind FeatName2Kind(const char* name)
{
int i;
for(i=0;i<FE_NUM_FEAT-1;i++){
if(strcmp(FE_featNameA[i],name)==0) return (FeatKind)i;
}
return (FeatKind)i;
}
int HasDeltaFeat(FeatKind fk)
{
const char *name=GetFeatName(fk);
char *i=strstr(name,"_D");
if(i) return 1;
else return 0;
}
int HasStftFeat(FeatKind fk)
{
const char *name=GetFeatName(fk);
char *i=strstr(name,"_SPEC");
if(i) return 1;
else return 0;
}
int Fe::GetDim(FeatKind fk)
{
int ndim = 0;
fk=GetBaseFeatKind(fk);
switch(fk){
case FE_LPC: case FE_LPCCOV:
ndim = m_lpcOrder + 1; break;
case FE_LPCC: case FE_MFCC: case FE_FTCC:
ndim = m_cepOrder + 1; break;
case FE_PLCC:
ndim = m_plccOrder + 1; break;
case FE_FBANK:
ndim = m_fbOrder; break;
case FE_LAR: case FE_LSF: case FE_PARCOR:
ndim = m_lpcOrder + 1; break;
case FE_FORMANT:
/* F1, F2, F3, F4 */
ndim = 4; break;
case FE_FFT_SPEC: case FE_LPC_SPEC: case FE_LPCC_SPEC:
case FE_MFCC_SPEC: case FE_FTCC_SPEC:
ndim = m_fftSize; break;
case FE_FFTCEP:
ndim = m_fftSize; break;
case FE_ZCR: case FE_ENERGY: case FE_PITCH: case FE_VUS: case FE_ENDPOINT:
case FE_EPOCH: case FE_GLOFLOW: case FE_GLOPULSE: case FE_LPCRES:
ndim = 1; break;
default:
ndim = 1; break;
}
return ndim;
}
int GetDefaultDim(enum FeatKind fk)
{
int dim=0;
fk=GetBaseFeatKind(fk);
switch(fk){
case FE_FFT_SPEC: case FE_LPC_SPEC: case FE_LPCC_SPEC: case FE_MFCC_SPEC: case FE_FTCC_SPEC:
dim = DEFAULT_FFT_SIZE/2+1; break;
case FE_FFTCEP:
dim = DEFAULT_FFT_SIZE/2+1; break;
case FE_LPC: case FE_LPCCOV: case FE_LAR: case FE_LSF: case FE_PARCOR:
dim = FE_LPC_ORDER+1; break;
case FE_FBANK:
dim = FE_NUM_CHANNELS+1; break;
case FE_LPCC: case FE_FTCC: case FE_MFCC:
dim = FE_CEP_ORDER+1; break;
case FE_PLCC:
dim = PLP_CEP_ORDER+1; break;
case FE_FORMANT:
dim = 4; break;
default:
dim = 1; break;
}
return dim;
}
int GetDefaultOrder(enum FeatKind fk)
{
int order=1;
fk=GetBaseFeatKind(fk);
switch(fk){
case FE_FFT_SPEC:
order = DEFAULT_FFT_SIZE/2+1; break;
case FE_FFTCEP:
order = DEFAULT_FFT_SIZE/2+1; break;
case FE_LPC_SPEC:
order = FE_LPC_ORDER; break;
case FE_LPCC_SPEC: case FE_MFCC_SPEC: case FE_FTCC_SPEC:
order = FE_CEP_ORDER; break;
case FE_LPC: case FE_LPCCOV: case FE_LAR: case FE_LSF: case FE_PARCOR:
order = FE_LPC_ORDER; break;
case FE_FBANK:
order = FE_NUM_CHANNELS; break;
case FE_LPCC: case FE_FTCC: case FE_MFCC: case FE_PLCC:
order = PLP_CEP_ORDER; break;
case FE_FORMANT:
order = 4; break;
default:
order = 1; break;
}
return order;
}
float Fe::LogE(float x)
{
if(x>m_energyFloor) return log(x);
else return m_logEnergyFloor;
}
int Fe::Integrate(float *a, int n, short *b)
{
float alpha = (float)0.98;
static float prev = 0;
for(int i=0;i<n;i++){
prev = a[i] + alpha*prev;
b[i] = (short)(prev);
}
return 1;
}
int Fe::Integrate(short *a, int n, short *b)
{
float alpha = (float)0.98;
static float prev = 0;
for(int i=0;i<n;i++){
prev = a[i] + alpha*prev;
b[i] = (short)(prev);
}
return 1;
}
float Fe::GetMedian(float* a, int n)
{
int i;
float median = 0;
vector<float> tmp(n);;
for(i=0;i<n;i++)
tmp[i] = a[i];
qsort(&tmp[0],n,sizeof(float),FE_CompareFloat);
median = tmp[(n-1)/2];
return median;
}
int Fe::InitProgress(int* pProgress, int* pCancel)
{
m_pProgress = pProgress;
m_pCancel = pCancel;
return 1;
}
int Fe::CheckWinMessage()
{
#if defined(_WIN32) && defined(ANALYSIS_LIB)
MSG message;
if(PeekMessage(&message, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&message);
DispatchMessage(&message);
}
#endif
if(m_pCancel && (*m_pCancel)) return 0;
else return 1;
}
int Fe::ShowProgress(int progress)
{
#if defined(_WIN32) && defined(ANALYSIS_LIB)
if(m_pProgress) *m_pProgress = progress;
#endif
return 1;
}
int FE_CompareFloat(const void *a, const void *b)
{
float *aa = (float*)a;
float *bb = (float*)b;
if(*aa > *bb) return 1;
else if(*aa < *bb) return -1;
else return 0;
}
#ifdef WIN32
char* strtok_r(char *s1, const char *s2, char **savept)
{
char *p = NULL;
char *z = NULL;
if(s1) *savept = s1;
if((*savept) == NULL) return NULL;
z = *savept + strlen(*savept);
p = strtok(*savept,s2);
if(p != NULL && (p + strlen(p) + 1) < z)
*savept = p + strlen(p) + 1;
else
*savept = NULL;
return p;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -