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;
	};