// file: $isip/class/algo/Cepstrum/cep_02.cc // version: $Id: cep_02.cc 9410 2004-02-26 18:17:43Z parihar $ // // isip include files // #include #include "Cepstrum.h" // method: diagnose // // arguments: // Integral::DEBUG level: (input) debug level for diagnostics // // return: a bool8 value indicating status // bool8 Cepstrum::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 // //-------------------------------------------------------------------------- // set indentation // if (level_a > Integral::NONE) { Console::put(L"testing required public methods...\n"); Console::increaseIndention(); } // declare Cepstrum objects for read/write methods // Cepstrum ceps2; Cepstrum ceps3; Cepstrum ceps4; // set the number of coefficients and lifer coefficients // ceps2.setOrder(12); // 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); // write to text and binary files // ceps2.write(tmp_file0, (int32)0); ceps2.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 value back // ceps3.read(tmp_file0, (int32)0); if (!ceps3.eq(ceps2)) { return Error::handle(name(), L"read", Error::TEST, __FILE__, __LINE__); } ceps4.read(tmp_file0, (int32)0); if (!ceps4.eq(ceps2)) { ceps4.debug(L"ceps4"); return Error::handle(name(), L"read", Error::TEST, __FILE__, __LINE__); } // close and delete the temporary files // tmp_file0.close(); tmp_file1.close(); File::remove(tmp_filename0); File::remove(tmp_filename1); // test the conditional i/o methods // Cepstrum cep_0; Sof tmp_file2; String tmp_filename2; Integral::makeTemp(tmp_filename2); tmp_file2.open(tmp_filename2, File::WRITE_ONLY); tmp_file2.put(CLASS_NAME, 5, -1); String line; line.assign(L"order = 24;\n"); tmp_file2.puts(line); // close the file // tmp_file2.close(); // open the file in read mode // tmp_file2.open(tmp_filename2); // read the values back // cep_0.read(tmp_file2, (int32)5); // close and delete the temporary files // tmp_file2.close(); File::remove(tmp_filename2); // check constructors and memory management methods // Cepstrum ceps0; Cepstrum ceps1(ceps0); if (!ceps1.eq(ceps0)) { 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 // Cepstrum::setGrowSize((int32)500); Cepstrum* pft = new Cepstrum(); for (int32 j = 1; j <= 100; j++) { Cepstrum** pfts = new Cepstrum*[j * 100]; // create the objects // for (int32 i = 0; i < j * 100; i++) { pfts[i] = new Cepstrum(); } // delete objects // for (int32 i = (j * 100) - 1; i >= 0; i--) { delete pfts[i]; } delete [] pfts; } delete pft; } // reset indentation // if (level_a > Integral::NONE) { Console::decreaseIndention(); } //--------------------------------------------------------------------------- // // 2. class-specific public methods: // set methods // //--------------------------------------------------------------------------- // set indentation // if (level_a > Integral::NONE) { Console::put(L"testing class-specific public methods: set methods...\n"); Console::increaseIndention(); } // test set number of coefficients methods // ceps2.setOrder(12); if (ceps2.order_d != (int32)12) { return Error::handle(name(), L"setOrder", Error::TEST, __FILE__, __LINE__); } // reset indentation // if (level_a > Integral::NONE) { Console::decreaseIndention(); } //--------------------------------------------------------------------------- // // 3. class-specific public methods: // get methods // //--------------------------------------------------------------------------- // set indentation // if (level_a > Integral::NONE) { Console::put(L"testing class-specific public methods: get methods...\n"); Console::increaseIndention(); } if (ceps2.getOrder() != 12) { return Error::handle(name(), L"getOrder", Error::TEST, __FILE__, __LINE__); } { Cepstrum cep1; Cepstrum cep2; if (!cep1.eq(cep2)) { return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__); } } // reset indentation // if (level_a > Integral::NONE) { Console::decreaseIndention(); } //-------------------------------------------------------------------------- // // 4. class-specific public methods // computational methods // //-------------------------------------------------------------------------- // set indentation // if (level_a > Integral::NONE) { Console::put(L"testing class-specific public methods: computational methods...\n"); Console::increaseIndention(); } // local variables // Cepstrum ceps; VectorFloat realinput; VectorFloat realoutput; VectorComplexFloat complexinput; VectorComplexFloat complexoutput; VectorFloat realans; VectorComplexFloat complexans; // test the first row in the table where algorithm is IDCT // ceps.setAlgorithm(IDCT); // test using TYPE_I // ceps.setImplementation(TYPE_I); // the input data is real magnitude of FFT of one cycle of a 1000 Hz // cosine sampled at 16 KHz // realinput.assign(L"1.0000, 8.7079, 0.3839, 0.1354, 0.0676, 0.0383, 0.0222, 0.0117, 0.0037"); // get all the cepstral coeffs // ceps.setOrder(8); // expected result is IDCT of the log of the above signal // realans.assign(L" 0.765171, 0.999744, 0.765171, 0.414108, 6.62604e-17, -0.414108, -0.765171, -0.999744, -0.765171"); // compute the result // ceps.compute(realoutput, realinput); if (!realoutput.almostEqual(realans, 20)) { realans.debug(L"expected result:"); realoutput.debug(L"wrong result:"); return Error::handle(name(), L"compute", Error::TEST, __FILE__, __LINE__); } // the input data is complex FFT of one cycle of a 1000 Hz cosine // sampled at 16 KHz // complexinput.assign(L"1.0000, 8.5596 + 1.6001j, -0.3580 - 0.1387j, -0.1151 - 0.0713j, -0.0500 - 0.0456j, -0.0231 - 0.0306j, -0.0099 - 0.0199j, -0.0032 - 0.0113j, -0.0003 - 0.0037j"); // expected result is tha same as before, compute the result // ceps.compute(realoutput, complexinput); if (!realoutput.almostEqual(realans, 20)) { realans.debug(L"expected result:"); realoutput.debug(L"wrong result:"); return Error::handle(name(), L"compute", Error::TEST, __FILE__, __LINE__); } // test with a frame that has some zero values in it // realinput.assign(L"0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"); // get all the cepstral coeffs // ceps.setOrder(8); // expected result is IDCT of the log of the above signal // realans.assign(L"0, 0, 0, 0, 0, 0, 0, 0, 0"); // compute the result // ceps.compute(realoutput, realinput); if (!realoutput.almostEqual(realans, 20)) { realans.debug(L"expected result:"); realoutput.debug(L"wrong result:"); return Error::handle(name(), L"compute", Error::TEST, __FILE__, __LINE__); } // test using TYPE_II // ceps.setImplementation(TYPE_II); // the input data is real magnitude of FFT of one cycle of a 1000 Hz // cosine sampled at 16 KHz // realinput.assign(L"1.0000, 8.7079, 0.3839, 0.1354, 0.0676, 0.0383, 0.0222, 0.0117, 0.0037"); // expected result is IDCT of the log of the above signal // realans.assign(L"1.00473, 0.883543, 0.65579, 0.348939, 6.24709e-17, -0.348939, -0.65579, -0.883543, -1.00473"); // compute the result // ceps.compute(realoutput, realinput); if (!realoutput.almostEqual(realans, 20)) { realans.debug(L"expected result:"); realoutput.debug(L"wrong result:"); return Error::handle(name(), L"compute", Error::TEST, __FILE__, __LINE__); } // the input data is complex FFT of one cycle of a 1000 Hz cosine // sampled at 16 KHz // complexinput.assign(L"1.0000, 8.5596 + 1.6001j, -0.3580 - 0.1387j, -0.1151 - 0.0713j, -0.0500 - 0.0456j, -0.0231 - 0.0306j, -0.0099 - 0.0199j, -0.0032 - 0.0113j, -0.0003 - 0.0037j"); // expected result is tha same as before, compute the result // ceps.compute(realoutput, complexinput); if (!realoutput.almostEqual(realans, 20)) { realans.debug(L"expected result:"); realoutput.debug(L"wrong result:"); return Error::handle(name(), L"compute", Error::TEST, __FILE__, __LINE__); } // test with a frame that has some zero values in it // realinput.assign(L"0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"); // get all the cepstral coeffs // ceps.setOrder(8); // expected result is IDCT of the log of the above signal // realans.assign(L"0, 0, 0, 0, 0, 0, 0, 0, 0"); // compute the result // ceps.compute(realoutput, realinput); if (!realoutput.almostEqual(realans, 20)) { realans.debug(L"expected result:"); realoutput.debug(L"wrong result:"); return Error::handle(name(), L"compute", Error::TEST, __FILE__, __LINE__); } // test using TYPE_III // ceps.setImplementation(TYPE_III); // the input data is real magnitude of FFT of one cycle of a 1000 Hz // cosine sampled at 16 KHz // realinput.assign(L"1.0000, 8.7079, 0.3839, 0.1354, 0.0676, 0.0383, 0.0222, 0.0117, 0.0037"); // expected result is IDCT of the log of the above signal // realans.assign(L"0.72141, 0.883543, 0.510114, 6.24709e-17, -0.510114, -0.883543, -1.02023, -0.883543, -0.510114"); // compute the result // ceps.compute(realoutput, realinput); if (!realoutput.almostEqual(realans, 20)) { realans.debug(L"expected result:"); realoutput.debug(L"wrong result:"); return Error::handle(name(), L"compute", Error::TEST, __FILE__, __LINE__); } // the input data is complex FFT of one cycle of a 1000 Hz cosine // sampled at 16 KHz // complexinput.assign(L"1.0000, 8.5596 + 1.6001j, -0.3580 - 0.1387j, -0.1151 - 0.0713j, -0.0500 - 0.0456j, -0.0231 - 0.0306j, -0.0099 - 0.0199j, -0.0032 - 0.0113j, -0.0003 - 0.0037j"); // expected result is tha same as before, compute the result // ceps.compute(realoutput, complexinput); if (!realoutput.almostEqual(realans, 20)) { realans.debug(L"expected result:"); realoutput.debug(L"wrong result:"); return Error::handle(name(), L"compute", Error::TEST, __FILE__, __LINE__); } // test with a frame that has some zero values in it // realinput.assign(L"0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"); // get all the cepstral coeffs // ceps.setOrder(8); // expected result is IDCT of the log of the above signal // realans.assign(L"0, 0, 0, 0, 0, 0, 0, 0, 0"); // compute the result // ceps.compute(realoutput, realinput); if (!realoutput.almostEqual(realans, 20)) { realans.debug(L"expected result:"); realoutput.debug(L"wrong result:"); return Error::handle(name(), L"compute", Error::TEST, __FILE__, __LINE__); } // test using TYPE_IV // ceps.setImplementation(TYPE_IV); // the input data is real magnitude of FFT of one cycle of a 1000 Hz // cosine sampled at 16 KHz // realinput.assign(L"1.0000, 8.7079, 0.3839, 0.1354, 0.0676, 0.0383, 0.0222, 0.0117, 0.0037"); // expected result is IDCT of the log of the above signal // realans.assign(L"0.985465, 0.72141, 0.264054, -0.264054, -0.72141, -0.985465, -0.985465, -0.72141, -0.264054"); // compute the result // ceps.compute(realoutput, realinput); if (!realoutput.almostEqual(realans, 20)) { realans.debug(L"expected result:"); realoutput.debug(L"wrong result:"); return Error::handle(name(), L"compute", Error::TEST, __FILE__, __LINE__); } // the input data is complex FFT of one cycle of a 1000 Hz cosine // sampled at 16 KHz // complexinput.assign(L"1.0000, 8.5596 + 1.6001j, -0.3580 - 0.1387j, -0.1151 - 0.0713j, -0.0500 - 0.0456j, -0.0231 - 0.0306j, -0.0099 - 0.0199j, -0.0032 - 0.0113j, -0.0003 - 0.0037j"); // expected result is tha same as before, compute the result // ceps.compute(realoutput, complexinput); if (!realoutput.almostEqual(realans, 20)) { realans.debug(L"expected result:"); realoutput.debug(L"wrong result:"); return Error::handle(name(), L"compute", Error::TEST, __FILE__, __LINE__); } // test with a frame that has some zero values in it // realinput.assign(L"0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"); // get all the cepstral coeffs // ceps.setOrder(8); // expected result is IDCT of the log of the above signal // realans.assign(L"0, 0, 0, 0, 0, 0, 0, 0, 0"); // compute the result // ceps.compute(realoutput, realinput); if (!realoutput.almostEqual(realans, 20)) { realans.debug(L"expected result:"); realoutput.debug(L"wrong result:"); return Error::handle(name(), L"compute", Error::TEST, __FILE__, __LINE__); } // test the second algorithm that is IDFT // ceps.setAlgorithm(IDFT); // test using CONVENTIONAL // ceps.setImplementation(CONVENTIONAL); // the input data is real magnitude FFT of one cycle of a 1000 Hz // cos + a 2000 Hz sin sampled at 16 KHz // realinput.assign(L"1.0000, 8.7270, 8.0161, 1.4306, 0.7777, 0.5766, 0.4838, 0.4369, 0.4166"); // expected result is complex IDFT of the log magnitude spectra // complexans.assign(L"0.511774+0j, 0.204663+0.416944j, -0.19542+0.281699j, -0.196205+0.00817621j, -0.0689259-0.0318726j, -0.0689259+0.0318726j, -0.196205-0.00817621j, -0.19542-0.281699j, 0.204663-0.416944j"); // compute the result // ceps.compute(complexoutput, realinput); if (!complexoutput.almostEqual(complexans, 20)) { complexans.debug(L"expected result:"); complexoutput.debug(L"wrong result:"); return Error::handle(name(), L"compute", Error::TEST, __FILE__, __LINE__); } // the input data is complex FFT of one cycle of a 1000 Hz cos + a // 2000 Hz sin sampled at 16 KHz // complexinput.assign(L"1.0000, 8.6656 + 1.0334j, 2.5344 - 7.6049j, -0.8648 + 1.1396j, -0.5720 + 0.5270j, -0.4822 + 0.3162j, -0.4425 + 0.1955j, -0.4233 + 0.1082j, -0.4152 + 0.0348j"); // the input data is complex as before, expected result is complex // one cycle of a 1000 Hz cos + a 2000 Hz sine sampled at 16 KHz // complexans.assign(L"0.1527 + 1.6359j, 0.9561 + 0.1609j, 0.2648 + 0.3548j, -0.2375 + 0.0479j, -0.1764 - 0.3916j, 0.1302 - 0.3504j, -0.0379 - 0.0352j, -0.5724 - 0.2806j, -0.4796 - 1.1417j"); ceps.compute(complexoutput, complexinput); if (!complexoutput.almostEqual(complexans, 20)) { complexans.debug(L"expected result:"); complexoutput.debug(L"wrong result:"); return Error::handle(name(), L"compute", Error::TEST, __FILE__, __LINE__); } // test using TRIGONOMETRIC // ceps.setImplementation(CONVENTIONAL); // the input data is real magnitude FFT of one cycle of a 1000 Hz // cos + a 2000 Hz sin sampled at 16 KHz // realinput.assign(L"1.0000, 8.7270, 8.0161, 1.4306, 0.7777, 0.5766, 0.4838, 0.4369, 0.4166"); // expected result is complex IDFT of the log magnitude spectra // complexans.assign(L"0.511774+0j, 0.204663+0.416944j, -0.19542+0.281699j, -0.196205+0.00817621j, -0.0689259-0.0318726j, -0.0689259+0.0318726j, -0.196205-0.00817621j, -0.19542-0.281699j, 0.204663-0.416944j"); // compute the result // ceps.compute(complexoutput, realinput); if (!complexoutput.almostEqual(complexans, 20)) { complexans.debug(L"expected result:"); complexoutput.debug(L"wrong result:"); return Error::handle(name(), L"compute", Error::TEST, __FILE__, __LINE__); } // the input data is complex FFT of one cycle of a 1000 Hz cos + a // 2000 Hz sin sampled at 16 KHz // complexinput.assign(L"1.0000, 8.6656 + 1.0334j, 2.5344 - 7.6049j, -0.8648 + 1.1396j, -0.5720 + 0.5270j, -0.4822 + 0.3162j, -0.4425 + 0.1955j, -0.4233 + 0.1082j, -0.4152 + 0.0348j"); // the input data is complex as before, expected result is complex // one cycle of a 1000 Hz sine // complexans.assign(L"0.1527 + 1.6359j, 0.9561 + 0.1609j, 0.2648 + 0.3548j, -0.2375 + 0.0479j, -0.1764 - 0.3916j, 0.1302 - 0.3504j, -0.0379 - 0.0352j, -0.5724 - 0.2806j, -0.4796 - 1.1417j"); ceps.compute(complexoutput, complexinput); if (!complexoutput.almostEqual(complexans, 20)) { complexans.debug(L"expected result:"); complexoutput.debug(L"wrong result:"); return Error::handle(name(), L"compute", 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; }