// file: $isip/class/algo/Window/win_02.cc // version: $Id: win_02.cc 9259 2003-07-03 20:08:45Z parihar $ // // isip include files // #include "Window.h" #include // method: diagnose // // arguments: // Integral::DEBUG level: (input) debug level for diagnostics // // return: a bool8 value indicating status // bool8 Window::diagnose(Integral::DEBUG level_a) { //--------------------------------------------------------------------------- // // 0. preliminaries // //--------------------------------------------------------------------------- // output the class name // if (level_a > Integral::NONE) { SysString output(L"diagnosing class "); output.concat(CLASS_NAME); output.concat(L": "); Console::put(output); Console::increaseIndention(); } //-------------------------------------------------------------------------- // // 1. required public methods // class constructors // //-------------------------------------------------------------------------- // set indentation // if (level_a > Integral::NONE) { Console::put(L"testing required public methods...\n"); Console::increaseIndention(); } Window win0; win0.setAlgorithm(RECTANGULAR); win0.setNormalization(NONE); win0.setDuration(0.025); // win0.init(); Window win1(win0); if (!win1.eq(win0)) { win0.debug(L"win0"); win1.debug(L"win1"); return Error::handle(name(), L"copy constructor", Error::TEST, __FILE__, __LINE__); } // test large allocation construction and deletion // if (level_a == Integral::ALL) { Console::put(L"\ntesting large chunk memory allocation and deletion:\n"); // set the memory to a strange block size so we can hopefully catch any // frame overrun errors // Window::setGrowSize((int32)500); Window* pwin = new Window(); for (int32 j = 1; j <= 100; j++) { Window** pwins = new Window*[j * 100]; // create the objects // for (int32 i = 0; i < j * 100; i++) { pwins[i] = new Window(); } // delete objects // for (int32 i = (j * 100) - 1; i >= 0; i--) { delete pwins[i]; } delete [] pwins; } delete pwin; } // reset indentation // if (level_a > Integral::NONE) { Console::decreaseIndention(); } //-------------------------------------------------------------------------- // // 2. required public methods // i/o methods // //-------------------------------------------------------------------------- // set indentation // if (level_a > Integral::NONE) { Console::put(L"testing required public methods: i/o methods...\n"); Console::increaseIndention(); } // declare a reference object // win0.setAlgorithm(HAMMING); win0.setAlignment(LEFT); win0.setNormalization(NONE); win0.setDuration(0.0250); win0.init(); // we need binary and text sof files // String tmp_filename0; Integral::makeTemp(tmp_filename0); String tmp_filename1; Integral::makeTemp(tmp_filename1); // open files in write mode // Sof tmp_file0; tmp_file0.open(tmp_filename0, File::WRITE_ONLY, File::TEXT); Sof tmp_file1; tmp_file1.open(tmp_filename1, File::WRITE_ONLY, File::BINARY); win0.write(tmp_file0, (int32)0); win0.write(tmp_file1, (int32)0); // close the files // tmp_file0.close(); tmp_file1.close(); // open the files in read mode // tmp_file0.open(tmp_filename0); tmp_file1.open(tmp_filename1); // read the object back // win1.read(tmp_file0, (int32)0); win1.init(); if (!win0.eq(win1)) { return Error::handle(name(), L"i/o", Error::TEST, __FILE__, __LINE__); } win1.read(tmp_file1, (int32)0); win1.init(); if (!win0.eq(win1)) { return Error::handle(name(), L"i/o", Error::TEST, __FILE__, __LINE__); } // close and delete the temporary files // tmp_file0.close(); tmp_file1.close(); File::remove(tmp_filename0); File::remove(tmp_filename1); // reset indentation // if (level_a > Integral::NONE) { Console::decreaseIndention(); } //-------------------------------------------------------------------------- // // 3. class-specific public methods // set and get methods // //-------------------------------------------------------------------------- // set indentation // if (level_a > Integral::NONE) { Console::put(L"testing class-specific public methods: set and get methods...\n"); Console::increaseIndention(); } // establish an object // win0.setAlgorithm(HAMMING); VectorFloat tmp(L"27.0, 9.0, 3.0"); // set the parameters manually // win0.setAlgorithm(RECTANGULAR); win0.setAlignment(LEFT); win0.setNormalization(UNIT_ENERGY); win0.setDuration(2.0); win0.setComputeMode(CROSS_FRAME); win0.setSize(3); // check that the values were set // if (win0.algorithm_d != RECTANGULAR) { return Error::handle(name(), L"setAlgorithm", Error::TEST, __FILE__, __LINE__); } else if (win0.cmode_d != CROSS_FRAME) { return Error::handle(name(), L"setMode", Error::TEST, __FILE__, __LINE__); } else if (win0.alignment_d != LEFT) { return Error::handle(name(), L"setAlignment", Error::TEST, __FILE__, __LINE__); } else if (win0.normalization_d != UNIT_ENERGY) { return Error::handle(name(), L"setNormalization", Error::TEST, __FILE__, __LINE__); } else if (win0.duration_d != (float32)2.0) { return Error::handle(name(), L"setDuration", Error::TEST, __FILE__, __LINE__); } else if (win0.data_d.length() != 3) { return Error::handle(name(), L"setSize", Error::TEST, __FILE__, __LINE__); } // test setConstants // win0.setAlgorithm(BLACKMAN); win0.setConstants(tmp); if (!win0.constants_d.eq(tmp)) { return Error::handle(name(), L"setData", Error::TEST, __FILE__, __LINE__); } // test setData // win0.setAlgorithm(CUSTOM); win0.setData(tmp); if (!win0.data_d.eq(tmp)) { return Error::handle(name(), L"setData", Error::TEST, __FILE__, __LINE__); } // reset indentation // if (level_a > Integral::NONE) { Console::decreaseIndention(); } //-------------------------------------------------------------------------- // // 4. class-specific public methods // computation methods // //-------------------------------------------------------------------------- // set indentation // if (level_a > Integral::NONE) { Console::put(L"testing class-specific public methods: computational methods...\n"); Console::increaseIndention(); } // test the basic compute method: // create a vector, multiplying it by the window, and see if it gives us // back the window. // VectorFloat input(L"1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2"); VectorFloat scale(L"1, 0.5, 1, 0.5, 1, 0.5, 1, 0.5, 1, 0.5, 1, 0.5, 1, 0.5, 1, 0.5, 1, 0.5, 1, 0.5"); VectorFloat output; VectorFloat ans; win0.clear(); win0.setSize(input.length()); win0.setAlgorithm(RECTANGULAR); win0.setNormalization(NONE); win0.setDuration(0.01); win0.init(); ans.assign(win0.getData()); win0.compute(output, input); output.mult(scale); if (!ans.almostEqual(output)) { ans.debug(L"ans"); output.debug(L"output"); win0.debug(L"win0"); return Error::handle(name(), L"compute", Error::TEST, __FILE__, __LINE__); } VectorComplexFloat cmplx_input(L"1+1j, 2+2j, 1+1j, 2+2j, 1+1j, 2+2j, 1+1j, 2+2j, 1+1j, 2+2j, 1+1j, 2+2j, 1+1j, 2+2j, 1+1j, 2+2j, 1+1j, 2+2j, 1+1j, 2+2j"); VectorComplexFloat cmplx_ans(L"1+1j, 2+2j, 1+1j, 2+2j, 1+1j, 2+2j, 1+1j, 2+2j, 1+1j, 2+2j, 1+1j, 2+2j, 1+1j, 2+2j, 1+1j, 2+2j, 1+1j, 2+2j, 1+1j, 2+2j"); VectorComplexFloat cmplx_output; win0.compute(cmplx_output, cmplx_input); if (!cmplx_ans.almostEqual(cmplx_output)) { return Error::handle(name(), L"compute", Error::TEST, __FILE__, __LINE__); } // test the RECTANGULAR window // win0.setAlgorithm(RECTANGULAR); win0.compute(output, input); ans.assign(L"1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2"); if (!ans.almostEqual(output)) { ans.debug(L"expected result"); output.debug(L"computing result"); return Error::handle(name(), L"compute", Error::TEST, __FILE__, __LINE__); } // test the BARTLETT window // win0.setAlgorithm(BARTLETT); win0.compute(output, input); ans.assign(L"0.1, 0.389474, 0.289474, 0.768421, 0.478947, 1.14737, 0.668421, 1.52632, 0.857895, 1.90526, 0.952632, 1.71579, 0.763158, 1.33684, 0.573684, 0.957895, 0.38421, 0.578947, 0.194737, 0.2"); if (!ans.almostEqual(output)) { ans.debug(L"expected result"); output.debug(L"computing result"); return Error::handle(name(), L"compute", Error::TEST, __FILE__, __LINE__); } // test the BLACKMAN window // win0.setAlgorithm(BLACKMAN); win0.compute(output, input); ans.assign(L"0.84923, 1.05735, 0.226899, 0.111656, 0.00158469, 0.0414436, 0.133271, 0.764762, 0.716524, 1.92852, 0.964259, 1.43305, 0.382381, 0.266541, 0.0207218, 0.00316938, 0.0558281, 0.453799, 0.528675, 1.69846"); if (!ans.almostEqual(output)) { ans.debug(L"expected result"); output.debug(L"computing result"); return Error::handle(name(), L"compute", Error::TEST, __FILE__, __LINE__); } // test the DOLPH_CHEBYSHEV window // win0.setAlgorithm(DOLPH_CHEBYSHEV); win0.compute(output, input); ans.assign(L"0.405618, 0.550077, 0.375813, 1.07166, 0.1997, 0.358307, 0.508916, 1.10699, 0.601162, 1.0705, 0.535248, 1.20232, 0.553495, 1.01783, 0.179153, 0.3994, 0.535829, 0.751627, 0.275039, 0.811237"); if (!ans.almostEqual(output)) { ans.debug(L"expected result"); output.debug(L"computing result"); return Error::handle(name(), L"compute", Error::TEST, __FILE__, __LINE__); } // test the GAUSSIAN window // win0.setAlgorithm(GAUSSIAN); win0.compute(output, input); ans.assign(L"0.495611, 1.14018, 0.64564, 1.43983, 0.790346, 1.70855, 0.909118, 1.9051, 0.982652, 1.99611, 0.998057, 1.9653, 0.95255, 1.81824, 0.854273, 1.58069, 0.719916, 1.29128, 0.57009, 0.991221"); if (!ans.almostEqual(output)) { ans.debug(L"expected result"); output.debug(L"computing result"); return Error::handle(name(), L"compute", Error::TEST, __FILE__, __LINE__); } // test the HAMMING window // win0.setAlgorithm(HAMMING); win0.compute(output, input); ans.assign(L"0.08, 0.209848, 0.176995, 0.576808, 0.427077, 1.15597, 0.72478, 1.7031, 0.944558, 1.98745, 0.993726, 1.88912, 0.85155, 1.44956, 0.577987, 0.854153, 0.288404, 0.353991, 0.104924, 0.16"); if (!ans.almostEqual(output)) { ans.debug(L"expected result"); output.debug(L"computing result"); return Error::handle(name(), L"compute", Error::TEST, __FILE__, __LINE__); } // test the HANNING window // win0.setAlgorithm(HANNING); win0.compute(output, input); ans.assign(L"0, 0.0541828, 0.10543, 0.453052, 0.377257, 1.08258, 0.700848, 1.67728, 0.939737, 1.98636, 0.993181, 1.87947, 0.838641, 1.4017, 0.54129, 0.754514, 0.226526, 0.210859, 0.0270914, 0"); if (!ans.almostEqual(output)) { ans.debug(L"expected result"); output.debug(L"computing result"); return Error::handle(name(), L"compute", Error::TEST, __FILE__, __LINE__); } // test the KAISER window // win0.setAlgorithm(KAISER); win0.compute(output, input); ans.assign(L"0.370651, 0.937826, 0.566715, 1.32193, 0.748606, 1.65346, 0.892712, 1.88859, 0.979712, 1.99547, 0.997733, 1.95942, 0.944296, 1.78542, 0.826732, 1.49721, 0.660966, 1.13343, 0.468913, 0.741302"); if (!ans.almostEqual(output)) { ans.debug(L"expected result"); output.debug(L"computing result"); return Error::handle(name(), L"compute", Error::TEST, __FILE__, __LINE__); } // test the LIFTER window // win0.setAlgorithm(LIFTER); win0.compute(output, input); ans.assign(L" 0, 5.13093, 4.09906, 11.1391, 6.94705, 16.4069, 9.31324, 20.5076, 11.006, 23.1088, 11.888, 24, 11.888, 23.1088, 11.006, 20.5076, 9.31325, 16.4069, 6.94705, 11.1391"); if (!ans.almostEqual(output)) { ans.debug(L"expected result"); output.debug(L"computing result"); return Error::handle(name(), L"compute", Error::TEST, __FILE__, __LINE__); } // test CUSTOM by comparing it to a known window // win0.setAlgorithm(HAMMING); win0.init(); VectorFloat vals(win0.getData()); win0.compute(output, input); VectorFloat output_tmp; win0.setAlgorithm(CUSTOM); win0.setData(vals); win0.compute(output_tmp, input); if (!output.almostEqual(output_tmp)) { return Error::handle(name(), L"compute", Error::TEST, __FILE__, __LINE__); } // test the compute method for a vector of zeros // input.assign(0.0); win0.compute(output, input); if (!output.almostEqual(input)) { return Error::handle(name(), L"compute", Error::TEST, __FILE__, __LINE__); } // test the RECTANGULAR window // win0.setAlgorithm(RECTANGULAR); input.assign(L"1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20"); VectorFloat output_left, output_right, output_center; output_left.assign(L"1, 2, 3, 4, 5, 6, 7, 8"); output_center.assign(L"7, 8, 9, 10, 11, 12, 13, 14"); output_right.assign(L"13, 14, 15, 16, 17, 18, 19, 20"); // test the window size less than frame size computation // win0.setDuration(0.001); win0.setFrameDuration(0.0025); win0.setComputeMode(CROSS_FRAME); CircularBuffer in; AlgorithmData data; data.makeVectorFloat().assign(input); in.append(data); win0.init(); win0.setAlignment(LEFT); win0.compute(output_tmp, in); if (!output_left.almostEqual(output_tmp)) { output_left.debug(L"expected result"); output_tmp.debug(L"compute result"); return Error::handle(name(), L"compute", Error::TEST, __FILE__, __LINE__); } win0.setAlignment(RIGHT); win0.compute(output_tmp, in); if (!output_right.almostEqual(output_tmp)) { output_right.debug(L"expected result"); output_tmp.debug(L"computing result"); return Error::handle(name(), L"compute", Error::TEST, __FILE__, __LINE__); } win0.setAlignment(CENTER); win0.compute(output_tmp, in); if (!output_center.almostEqual(output_tmp)) { output_center.debug(L"expected result"); output_tmp.debug(L"computing result"); return Error::handle(name(), L"compute", Error::TEST, __FILE__, __LINE__); } input.assign(L"1, 2, 3, 4, 5, 6, 7, 8"); win0.setDuration(3.0 / 8000.0); win0.setFrameDuration(0.001); CircularBuffer in2; AlgorithmData data2; data2.makeVectorFloat().assign(input); in2.append(data2); win0.init(); win0.setAlignment(CENTER); win0.compute(output_tmp, in2); output_center.assign(L"3, 4, 5"); if (!output_center.almostEqual(output_tmp)) { output_center.debug(L"expected result"); output_tmp.debug(L"computing result"); return Error::handle(name(), L"compute", Error::TEST, __FILE__, __LINE__); } // test the pad computation // win0.setDuration(0.025); win0.setFrameDuration(0.01); win0.setComputeMode(CROSS_FRAME); win0.setAlignment(LEFT); win0.init(); if (win0.getLeadingPad() != 2) { return Error::handle(name(), L"getLeadingPad", Error::TEST, __FILE__, __LINE__); } if (win0.getTrailingPad() != 0) { return Error::handle(name(), L"getTrailingPad", Error::TEST, __FILE__, __LINE__); } win0.alignment_d = RIGHT; if (win0.getLeadingPad() != 0) { return Error::handle(name(), L"getLeadingPad", Error::TEST, __FILE__, __LINE__); } if (win0.getTrailingPad() != 2) { return Error::handle(name(), L"getTrailingPad", Error::TEST, __FILE__, __LINE__); } win0.alignment_d = CENTER; if (win0.getLeadingPad() != 1) { return Error::handle(name(), L"getLeadingPad", Error::TEST, __FILE__, __LINE__); } if (win0.getTrailingPad() != 1) { return Error::handle(name(), L"getTrailingPad", Error::TEST, __FILE__, __LINE__); } // reset indentation // if (level_a > Integral::NONE) { Console::decreaseIndention(); } //-------------------------------------------------------------------------- // // 5. print completion message // //-------------------------------------------------------------------------- // reset indentation // if (level_a > Integral::NONE) { Console::decreaseIndention(); } if (level_a > Integral::NONE) { SysString output(L"diagnostics passed for class "); output.concat(name()); output.concat(L"\n"); Console::put(output); } // exit gracefully // return true; }