[tpcode] // Purpose // A program to demonstrate the application of a simple digital filter // // Overview // A sequence of data items and digital filter values need to be entered by the // user. The application of the filter to the data involves a simple convolution // operation. The filtered data are stored separately. // // Example // before filtering: // data_in = [0 1 3 6 3 1 0] // filter = [-0.5 1 -0.5] // after filtering: // data_out = [-0.5 -0.5 3 -0.5 -0.5] // where // data_out[0]=data_in[0]*filter[0]+data_in[1]*filter[1]+data_in[2]*filter[2] // data_out[1]=data_in[1]*filter[0]+data_in[2]*filter[1]+data_in[3]*filter[2] // data_out[2]=data_in[2]*filter[0]+data_in[3]*filter[1]+data_in[4]*filter[2] // data_out[3]=data_in[3]*filter[0]+data_in[4]*filter[1]+data_in[5]*filter[2] // data_out[4]=data_in[4]*filter[0]+data_in[5]*filter[1]+data_in[6]*filter[2] // // The program checks the following // 1.The data and filter values must have been entered before the filter is // applied // 2.The filter is not applied if the number of filter values is greater than // the number of input data values // 3.The data and filter values must have been entered and the filter applied // before the filtered data can be displayed #include <iostream> using namespace std; // the data values and the filter struct TheFilter { double* Values; // the filter values POINTER unsigned long Length; // number of filter values bool Valid; // true if the filter values have been obtained }; struct TheData { double* Values; // holds the data to be filtered POINTER unsigned long Length; // number of data values bool Valid; // true if the data values have been obtained }; // function return values enum { OK, FILTER_TOO_LONG }; // function prototypes void EnterData(TheData &OriginalData); //Function Prototypes void EnterFilter(TheFilter &Filter); int ApplyFilter(TheFilter &Filter, TheData &OriginalData, TheData &FilteredData); void DisplayData(TheFilter &Filter, TheData &OriginalData, TheData &FilteredData); // Control the principal operations of the program // Arguments: None // Returns: 0 on completion int main() { // define the filter and its initial values TheFilter Filter = { 0,0,false }; // define the original data and its initial values TheData OriginalData = { 0,0,false }; // define the filtered data and its initial values TheData FilteredData = { 0,0,false }; char UserInput; // loop until the user wishes to exit while (1) { // show the menu of options cout << endl; cout << "Filter Menu" << endl; cout << "-----------" << endl; cout << "1. Enter data for filtering" << endl; cout << "2. Enter filter values" << endl; cout << "3. Apply filter" << endl; cout << "4. Display filtered data" << endl; cout << "5. Exit from the program" << endl << endl; // get the user's choice cout << "Enter your option: "; cin >> UserInput; cout << endl; // act on the user's input switch (UserInput) { case '1': EnterData(OriginalData); FilteredData.Valid = false; break; case '2': EnterFilter(Filter); FilteredData.Valid = false; break; case '3': if (Filter.Valid == true && OriginalData.Valid == true && FilteredData.Valid == false) { if (ApplyFilter(Filter, OriginalData, FilteredData) == FILTER_TOO_LONG) { cout << "The filter must not be longer than the data" << endl; } else { FilteredData.Valid = true; cout << "Filter applied" << endl; } } break; case '4': if (Filter.Valid == true && OriginalData.Valid == true && FilteredData.Valid == true) { DisplayData(Filter, OriginalData, FilteredData); } else { cout << "Data have not yet been filtered" << endl; } break; case '5': delete[] Filter.Values; delete[] OriginalData.Values; delete[] FilteredData.Values; return 0; break; default: cout << "Invalid entry" << endl << endl; break; } } } // Allow the user to enter the data to be filtered 1 EnterData // Arguments: // (1) the structure containing the input data // Returns: nothing // void EnterData(TheData &OriginalData) { // initialize the data structure that holds the data to be filtered, including getting delete[] OriginalData.Values; // the number of data values from the user cout << "Please enter the number of data values would you like to convolute?" << endl; cin >> OriginalData.Length; // allocate memory to the data // Obtain memory from free store for the array OriginalData.Values = new double[OriginalData.Length]; if (OriginalData.Values == 0) { cerr << "\n*** Unable to allocate memory *** \n"; exit(1); } else { // obtain all of the data values for (unsigned int i = 0; i < (OriginalData.Length); i++) { cout << "Enter data value " << i + 1 << ":" << endl; cin >> *(OriginalData.Values + i); } } cout << "Data Assigned" << endl; OriginalData.Valid = true; } // Allow the user to enter the filter values // Arguments: // (1) the structure of the filter to be defined 2 EnterFilter // Returns: nothing // void EnterFilter(TheFilter &Filter) { // initialize the data structure that holds the filter, including getting the number of delete[] Filter.Values; // filter values from the user cout << "Please enter the number of filter values would you like to add? (this must be less than Data values)" << endl; cin >> Filter.Length; // allocate memory to the filter values // Obtain memory from free store for the array // obtain all of the data values Filter.Values = new double[Filter.Length]; if (Filter.Values == 0) { cerr << "\n*** Unable to allocate memory *** \n"; exit(1); } else { // obtain all of the filter values for (unsigned int i = 0; i < (Filter.Length); i++) { cout << "Enter data value " << i + 1 << ":" << endl; cin >> *(Filter.Values + i); } } cout << "Filter Assigned" << endl; Filter.Valid = true; } // Apply the filter to the input data and store in the filtered data structure 3 ApplyFilter // Arguments: // (1) the structure of the filter to be applied // (2) the structure containing the data to be filtered // (3) the structure to hold the filtered data // Returns: OK - if the filter is applied // FILTER_TOO_LONG - the filter is longer than the data // int ApplyFilter(TheFilter &Filter, TheData &DataIn, TheData &FilteredData) { // return an error if the filter is longer than the data if (Filter.Length > DataIn.Length) return FILTER_TOO_LONG; // initialize the data structure that holds the filtered data FilteredData.Length = (DataIn.Length - (Filter.Length - 1)); // get memory for the filtered data FilteredData.Values = new double[Filter.Length]; if (FilteredData.Values == 0) { cerr << "\n*** Unable to allocate memory *** \n"; exit(1); } else { for (unsigned int j = 0; j < (FilteredData.Length); j++) { *(FilteredData.Values + j) = 0; for (unsigned int i = 0; i < (Filter.Length); i++) { *(FilteredData.Values + j) = (*(Filter.Values + i)) * (*(DataIn.Values + j + i)) + (*(FilteredData.Values + j)); } } } Filter.Valid = true; return OK; } // Display input data, filter values and output data 4 DisplayData // Arguments: // (1) the structure of the filter to be applied // (2) the structure containing the data to be filtered // (3) the structure that holds the filtered data // Returns: nothing // void DisplayData(TheFilter &Filter, TheData &DataIn, TheData &FilteredData) { // display all of the input data values cout << "data values: "; for (unsigned int i = 0; i < (DataIn.Length); i++) { cout << *(DataIn.Values + i) << ", "; } cout << endl; // display all of the filter values cout << "filter values: "; for (unsigned int i = 0; i < (Filter.Length); i++) { cout << *(Filter.Values + i) << ", "; } cout << endl; // display all of the data output values cout << "filtered values: "; for (unsigned int i = 0; i < (FilteredData.Length); i++) { cout << *(FilteredData.Values + i) << ", "; } cout << endl; } [/tpcode]