#include <iostream>
#include <fstream>
using namespace std;
// THE FOLLOWING HEADER CONTAINS CODE FOR DIGITAL FILTERS. TWO CLASSES ARE
// PRESENTED, INPUT SIGNAL SEQUENCE AND THE FILTERED OUTPUT SIGNAL SEQUENCE (FIR).
// ALL COPY RIGHTS RESERVED.
class sequence /* compiler executes line by line */ /* REMEMBER! NO implementation in headers!!! */
{
public:
//friend class FIR; /* Make sequence class a friend of FIR class */
sequence(int _NUMBER_OF_SAMPLES = 0, float* _SAMPLES = NULL); /* constructor */
~sequence(); /* Destructor */
sequence(const sequence& s); /* constructor copy, s is just dummy variable and used repeatitevly */
const sequence& operator=(const sequence& s); /* Assignment operator */
sequence operator+(const sequence& s); /* operator + */
sequence& operator+=(const sequence &s); /* Be careful, this operator returns a pointer! */
friend istream& operator>>(istream&, sequence&);
/* input stream operator to read data from a file to sample array, both operators come in pairs */
friend ostream& operator<<(ostream&, sequence&); /* output stream operator */
int get_number_of_samples() const; /* Get number of samples member function */
float* get_samples() const; /* Get the samples from a file, return type could be void (create another array) or float */
/* const is typed after argument list above to promise compiler that sequence won't be modified in apply_filter function */
float* all_samples_zero(); /* a function to zero all sample array values */
private:
int number_of_samples;
float* samples;
};
class FIR
{
public:
//friend class sequence;
FIR(int _NUMBER_OF_COEFFICIENTS = 0, float* _COEFFICIENTS = NULL); /* constructor */
~FIR(); /* Destructor */
FIR(const FIR& f); /* constructor copy */
const FIR& operator=(const FIR& f); /* Assignment operator */
friend istream& operator>>(istream&, FIR&); /* stream operator */
friend ostream& operator<<(ostream&, FIR&);
int get_number_of_coefficients(); /* Get number of coefficients */
float* get_coefficients(); /* Get the samples from a file, return type could be void (create another array) or float */
sequence* apply_filter(const sequence& f); /* Write the argument inside (in this decleration!!), because it is another argument besides FIR elements */
/* filter function || HOW TO ACCESS Vin FROM SEQUENCE CLASS? use
(const sequence& s) as argument || output sequence is read to a file */
private:
int number_of_coefficients;
float* coefficients;
};
//=====================================================================================================================
sequence::sequence(int _NUMBER_OF_SAMPLES, float* _SAMPLES) /* CLASS: SEQUENCE (CONSTRUCTOR) */
{
number_of_samples=_NUMBER_OF_SAMPLES;
samples=new float [number_of_samples];
}
sequence::~sequence() /* CLASS: SEQUENCE (DESTRUCTOR) */
{
delete [] samples;
}
sequence::sequence(const sequence& s) /* CLASS: SEQUENCE (COPY CONSTRUCTOR) */
:number_of_samples(s.number_of_samples)
{
samples=new float [number_of_samples]; /* Necessary to allocate a new array */
for(int i=0; i<number_of_samples; i++) samples[i]=s.samples[i];
}
istream& operator>>(istream& in, sequence &s) /* CLASS: SEQUENCE (INPUT STREAM OPERATOR) */
{
in>>s.number_of_samples;//>>s.samples(in);
//return(in); NO NEED, IF SO OPERATOR WILL EXIT HERE!
s.samples=new float [s.number_of_samples];
for(int i=0; i<s.number_of_samples; i++) in>>s.samples[i];
return(in);
}
ostream& operator<<(ostream& out, sequence &s) /* CLASS: SEQUENCE (OUTPUT STREAM OPERATOR) */
{
out<<s.number_of_samples;//<<s.samples; // STREAM OPERATOR NOT MEMBER FUNC ANY MORE! INSTANCES WITH DOTS REQUIRED
s.samples=new float [s.number_of_samples];
for(int i=0; i<s.number_of_samples; i++) out<<s.samples[i];
return(out);
}
const sequence& sequence::operator=(const sequence& s) /* CLASS: SEQUENCE (ASSIGNMENT OPERATOR) */
{
if(this==&s) return(*this);
if(number_of_samples!=s.number_of_samples)
{
number_of_samples=s.number_of_samples;
delete[] samples;
samples = new float[number_of_samples];
}
for(int i=0; i<number_of_samples; i++) samples[i]=s.samples[i];
return(*this);
}
sequence sequence::operator+(const sequence &s) /* CLASS: SEQUENCE (OVERLOAD ADDITION OPERATOR) */
{
sequence result(s);
//result.number_of_samples+=s.number_of_samples; /* should I add number of samples ? */
for(int i=0; i<number_of_samples; i++) result.samples[i]+=samples[i];
return(result);
}
sequence& sequence::operator+=(const sequence& s) /* CLASS: SEQUENCE (OVERLOAD ADDITION OPERATOR, change instance value to the total summation) */
{
//sequence result(*this);
//result.number_of_samples+=s.number_of_samples; /* should I add number of samples ? */
for(int i=0; i<number_of_samples; i++) this->samples[i]+=s.samples[i];
return(*this);
}
FIR::FIR(int _NUMBER_OF_COEFFICIENTS, float* _COEFFICIENTS) /* CLASS: FIR (CONSTRUCTOR) */
{
number_of_coefficients=_NUMBER_OF_COEFFICIENTS;
coefficients=new float [number_of_coefficients];
}
FIR::~FIR() /* CLASS: FIR (DESTRUCTOR) */
{
delete [] coefficients;
}
FIR::FIR(const FIR& f) /* CLASS: FIR (COPY CONSTRUCTOR) */
:number_of_coefficients(f.number_of_coefficients)
{
coefficients=new float [number_of_coefficients];
for(int i=0; i<number_of_coefficients; i++) coefficients[i]=f.coefficients[i];
}
istream& operator>>(istream& in, FIR &f) /* CLASS: FIR (INPUT STREAM OPERATOR) */
{
in>>f.number_of_coefficients;//>>f.coefficients;
f.coefficients=new float [f.number_of_coefficients];
for(int i=0; i<f.number_of_coefficients; i++) in>>f.coefficients[i];
return(in);
}
ostream& operator<<(ostream& out, FIR &f) /* CLASS: FIR (OUTPUT STREAM OPERATOR) */
{
out<<f.number_of_coefficients;//<<f.coefficients;
f.coefficients=new float [f.number_of_coefficients]; /* Allocating a new array is required for every stream operator */
for(int i=0; i<f.number_of_coefficients; i++) out<<f.coefficients[i];
return(out);
}
const FIR& FIR::operator=(const FIR& f) /* CLASS: FIR (ASSIGNMENT OPERATOR) */
{
if(this==&f) return(*this);
if(number_of_coefficients!=f.number_of_coefficients)
{
number_of_coefficients=f.number_of_coefficients;
delete[] coefficients;
coefficients = new float[number_of_coefficients];
}
for(int i=0; i<number_of_coefficients; i++) coefficients[i]=f.coefficients[i];
return(*this);
}
int sequence::get_number_of_samples() const
{
return(number_of_samples); /* Change number of samples to public instead of private using member function */
}
float* sequence::get_samples() const
{
/* Change samples array pointer to public instead of private using member function */
//for(int i=0;i<number_of_samples;i++) samples_file>>samples[i];
return(samples);
}
float* sequence::all_samples_zero()
{
for(int i=0; i<number_of_samples; i++) samples[i]=0.0;
return(samples); /* is it correct to return a pointer? */
}
int FIR::get_number_of_coefficients()
{
/* Change number of coefficients to public instead of private using member function */
return(number_of_coefficients);
}
float* FIR::get_coefficients()
{
/* Change coefficients array pointer to public instead of private using member function */
//for(int i=0;i<number_of_coefficients;i++) coefficients_file>>coefficients[i];
return(coefficients);
}
sequence* FIR::apply_filter(const sequence& f)
{
sequence* filtered_samples = new sequence; /* Create a pointer to a new sequence */
int counter=f.get_number_of_samples();
for(int i=0; i<counter; i++)
{
if (0==i) filtered_samples->get_samples()[i]=coefficients[0]*f.get_samples()[i];
else filtered_samples->get_samples()[i]=coefficients[0] * f.get_samples()[i]+ coefficients[1] * f.get_samples()[i-1];
}
return(filtered_samples);
} // SOMETIMES PROGRAMME CRASHES BECAUSE IT TRIES TO ACCESS SMTHUNG WHICH DOESN'T EXIST
int main()
{
ifstream samples_file("input.txt");
ifstream coefficients_file("filter.txt");
ofstream output_filtered_samples_file("output.txt");
FIR test_FIR; /* CREATE NEW FIR INSTANCE */
sequence test_sequence; /* CREATE NEW SEQUENCE INSTANCE */
//sequence* filtered_sequence = new sequence;coefficients_file>>test_FIR;
samples_file>>test_sequence;
coefficients_file>>test_FIR;
sequence* filtered_sequence = test_FIR.apply_filter(test_sequence);
output_filtered_samples_file<<filtered_sequence;
for(int i=0;i<filtered_sequence->get_number_of_samples();i++) cout<<filtered_sequence->get_samples()[i]<<endl; /* INPUT OPERATORS ARE WRONG!!! FIX THEM, ARE THEY? */
// cin>>1; /* DEMONSTRATOR SAID SOMETHING ABOUT GETFUNCTIONS RETUREN VALUE NOT VARIABLE! WHAT? CHECK LATER */
// for (int i=0; i<12; i++) cout<<test_sequence.get_samples()[i]<<endl;
// for (int i=0; i<a; i++) coefficients_file>>test_FIR.get_coefficients()[i]; NO NEED FOR THESE, STREAM OPERATORS DO THAT ALREADY!!!
// for (int i=0; i<b; i++) samples_file>>test_sequence.get_samples()[i];
// for (int i=0; i<a; i++) output_filtered_samples_file<<filtered_sequence->get_samples()[i];
return 0;
}
// WHY CODE WORKS IF CPP FILE RUN ALONE?