www.pudn.com > features.rar > Feature.cpp
// *********************************************************************
// * This file is part of RES 6.0. *
// * RES 6.0 is an original software distributed within the book *
// * *
// * |-----------------------------------------------------| *
// * | "Speech Recognition: Theory and C++ Implementation" | *
// * | John Wiley & Sons, Ltd | *
// * | by Claudio Becchetti and Lucio Prina Ricotti | *
// * |-----------------------------------------------------| *
// * *
// * See copyright.txt file for further info. on copyright *
// *********************************************************************
// _____________________________________________________________________
// |-------------------------------------------------------------------|
// | |
// | FILE: feature.cpp |
// | FUNCTIONALITY: low level C-like procedure for signal processing |
// | PROGRAM: required to feature extraction |
// | COMMENTS: |
// | CONTRIBUTIONS: Claudio , Fabrizio |
// | ACTUAL REVISION: 6.0 (completely renewed) |
// | DATA ACTUAL REVISION: 19//11/98 |
// | FIRST VERSION: 1.0 (newiofile.cpp) |
// | DATA FIRST VERSION: 25/2/96 |
// | |
// |-------------------------------------------------------------------|
// _____________________________________________________________________
// <<< version 4.0 >>>
//24/4/98 added Unix compatibility
//23/3/98 introduced ImpPolimorphic in FeatureExtraction
//12/2/98 eliminated const char * and operator += with strings
//inserted static const String dsp_block_name;
// Fabrizio
// 09/03/98 bug corrected in function Max_Delta_Feature_Order now return
// num_of_past_samples_required instead of size_of_output_vector
// 10/03/98 bug corrected in Magnitude_And_Energy_Of_Real_Vectors energy passed by value
// instead of by reference, corrected shuffle_optput in DspDerivative
// class, in DspDerivative function Apply deal with case that the feature
// is the first in the utterance
// 02/04/98 added function Size_Of_Output_Vector in NullBlock class
// 2/8/98 fixed bug on feature dim on Null Block and derivative
#include "../features/feature.h"
//add here your custom block::dsp_block_name
const String PreemphasisAndHammingWindow::dsp_block_name
="preemphasis_and_hamming_window";
const String MfccAndEnergy::dsp_block_name
="mfcc_with_energy";
const String FftAndEnergy::dsp_block_name
="fft_with_energy";
const String NullBlock::dsp_block_name
="null_block";
const String DspDerivative::dsp_block_name =
"add_derivatives";
const String DspDerivativeLT::dsp_block_name =
"add_derivatives_lt";
const String MeanSubtraction::dsp_block_name
= "subtract_mean";
//***********************************************
//* *
//* FeatureExtraction *
//* *
//***********************************************
// ADD in this function a NEW BLOCK !!!
void FeatureExtraction::Configure(const String & config_fname,const String & section)
{
ConfigFile conf;
t_index number_of_blocks,i;
String section_name,option_label,block_type,value;
conf.Open_File(config_fname);
//get first parameters
number_of_blocks =conf.Get_Unsigned_Opt(section,
"Number_Of_Blocks");
if(number_of_blocks==0)
merr<<"zero blocks requested in Feature Configuration";
conf.Get_String_Opt(section, "Label_Of_Blocks",option_label);
Assert(option_label.Dim()>0);
//delete previous configuration
if(operations.Dim()>0)
{
//save configuration in diagnostic
Actual_Configuration_String(value);
mwarn<<"reconfiguration of feature extraction requested"<<
"previous configuration was: "<Initialize(config_fname, section_name);
};
//Compute memory_order
num_of_past_samples_required=0;
for(i=0;i< number_of_blocks;i++)
num_of_past_samples_required=
operations[i]->Memory_Order(num_of_past_samples_required);
//Compute Size_Of_Output_Vector
size_of_output_vector =0;
for(i=0;i< number_of_blocks;i++)
size_of_output_vector =
operations[i]->Size_Of_Output_Vector (size_of_output_vector);
return;
}
FeatureExtraction::FeatureExtraction()
{
size_of_output_vector=0;
num_of_past_samples_required=0;
return;
}
FeatureExtraction::~FeatureExtraction()
{
size_of_output_vector=0;
num_of_past_samples_required=0;
operations.Reset();
return;
}
//retrieve configuration from configuration file
//apply all the required transformations
void FeatureExtraction::Extract(VetDouble& output,
const VetDouble &input, t_real smp_rate)
{
t_index i,number_of_blocks;
number_of_blocks = operations.Dim();
Assert(number_of_blocks >0);
output=input;
for(i=0;i< number_of_blocks;i++)
operations[i]->Apply(output,smp_rate);
return;
}
//perform sequential transformations over prev_vetsmp_list to
//the memory of all the modules
void FeatureExtraction::Get_Previous_Frames_Info(
const VetDoubleList & prev_vetsmp_list, t_real smp_rate)
{
t_signed i,dim;
static VetDouble feature;
dim= (t_signed) prev_vetsmp_list.Dim();
Reset();
for(i=dim-1;i>=0;i--)
Extract(feature, prev_vetsmp_list[i],smp_rate);
return;
}
//reset memory
void FeatureExtraction::Reset()
{
t_index i;
for(i=0;iReset_Memory();
return;
}
void FeatureExtraction::Actual_Configuration_String(String & string)
{
String temp;
t_index i;
string.Reset();
for(i=0;iActual_Configuration(temp);
string<>";
}
return;
}
//preenfasi va sostituito in TSPECBASE e Baumwelch con la funzione
//Actual_Configuration
//t_real Preemphasis()
t_index FeatureExtraction::Max_Delta_Feature_Order() const
{
return num_of_past_samples_required;
}
t_index FeatureExtraction::Feature_Vet_Dim() const
{
return size_of_output_vector;
}
//***********************************************
//* *
//* PreemphasisAndHammingWindow *
//* *
//***********************************************
//get options from configuration file
Boolean PreemphasisAndHammingWindow::Initialize(const String & filename,
const String & section)
{
ConfigFile conf;
String value, option_label,block_type;
conf.Open_File(filename);
conf.Get_String_Opt(section, "Type_Of_Block",value,
dsp_block_name );
if (value!= dsp_block_name)
merr<<"Wrong Block Requested:"<0);
compute_energy =conf.Get_Boolean_Opt(section, "Compute_Energy");
compute_log_of_energy=conf.Get_Boolean_Opt(section,"Compute_Log_Of_Energy");
return TRUE;
}
Boolean MfccAndEnergy::Apply(VetDouble & data,t_real smp_rate)
{
static VetDouble temp;
t_real energy=0;
Perform_FftModule_And_Energy(data, energy);
temp=data;
data.Destroy_And_ReDim(feature_vet_dim);
Mfcc_Call(data,temp, smp_rate);
if(compute_energy)
data.Append(energy);
return TRUE;
}
//return actual configuration
void MfccAndEnergy::Actual_Configuration(String & string) const
{
String buffer="no";
string.Reset();
string<0);
compute_energy =conf.Get_Boolean_Opt(section, "Compute_Energy");
compute_log_of_energy=conf.Get_Boolean_Opt(section,"Compute_Log_Of_Energy");
compute_log_of_fft=conf.Get_Boolean_Opt(section,"Compute_Log_Of_FFT");
return TRUE;
}
//apply operation
Boolean FftAndEnergy::Apply(VetDouble & data,t_real smp_rate)
{
static VetDouble temp;
t_real energy;
Perform_FftModule_And_Energy(data, energy);
temp=data;
data.Destroy_And_ReDim(feature_vet_dim);
if (compute_log_of_fft)
data.Log();
if(compute_energy)
data.Append(energy);
return TRUE;
}
//return actual configuration
void FftAndEnergy::Actual_Configuration(String & string) const
{
string.Reset();
string<=start_y+ num_elems);
for(i=0;i< num_elems;i++)
y[start_y+i]=y[start_x+i]- s[i];
return;
}
// history[i-1]=y[i-1];
//out=in[start…start-1+ num_elems]
void DspDerivative::Assign(VetDouble & out, const VetDouble & y,t_index start,
t_index num_elems)
{
t_index i;
for(i=0;i< num_elems;i++)
out[i]=y[start +i];
return;
}
void DspDerivative::First_Assign(VetDouble & data)
{
t_index num_features= data.Dim();
data.Save_And_ReDim(Size_Of_Output_Vector(num_features));
return;
}
void DspDerivative::Reset_Memory()
{
t_index i;
for(i=0;i>buffer;
if(buffer!="[mean_value]")
merr<<"Bad file of feature mean value";
file>>buffer;
if(buffer!="vet_dim:")
merr<<"Bad file of feature mean value";
file>>dim;
mean_vet.Destroy_And_ReDim(dim);
for(t_index i=0;i>mean_vet[i];
file.close();
return;
};
t_index MeanSubtraction::Memory_Order(t_index memory_order)
{
return memory_order;
};