+ delete m_vecFilter;
+ delete m_vecFourierSinTable;
+ delete m_vecFourierCosTable;
+#if HAVE_FFTW
+ if (m_idFilterMethod == FILTER_METHOD_FFT) {
+ fftw_destroy_plan(m_planForward);
+ fftw_destroy_plan(m_planBackward);
+ }
+#endif
+}
+
+
+const SignalFilter::FilterID
+SignalFilter::convertFilterNameToID (const char *filterName)
+{
+ FilterID filterID = FILTER_INVALID;
+
+ if (strcasecmp (filterName, FILTER_BANDLIMIT_STR) == 0)
+ filterID = FILTER_BANDLIMIT;
+ else if (strcasecmp (filterName, FILTER_HAMMING_STR) == 0)
+ filterID = FILTER_G_HAMMING;
+ else if (strcasecmp (filterName, FILTER_SINC_STR) == 0)
+ filterID = FILTER_SINC;
+ else if (strcasecmp (filterName, FILTER_COS_STR) == 0)
+ filterID = FILTER_COSINE;
+ else if (strcasecmp (filterName, FILTER_TRIANGLE_STR) == 0)
+ filterID = FILTER_TRIANGLE;
+ else if (strcasecmp (filterName, FILTER_ABS_BANDLIMIT_STR) == 0)
+ filterID = FILTER_ABS_BANDLIMIT;
+ else if (strcasecmp (filterName, FILTER_ABS_HAMMING_STR) == 0)
+ filterID = FILTER_ABS_G_HAMMING;
+ else if (strcasecmp (filterName, FILTER_ABS_SINC_STR) == 0)
+ filterID = FILTER_ABS_SINC;
+ else if (strcasecmp (filterName, FILTER_ABS_COS_STR) == 0)
+ filterID = FILTER_ABS_COSINE;
+ else if (strcasecmp (filterName, FILTER_SHEPP_STR) == 0)
+ filterID = FILTER_SHEPP;
+
+ return (filterID);
+}
+
+const char *
+SignalFilter::convertFilterIDToName (const FilterID filterID)
+{
+ const char *name = "";
+
+ if (filterID == FILTER_SHEPP)
+ name = FILTER_SHEPP_STR;
+ else if (filterID == FILTER_ABS_COSINE)
+ name = FILTER_ABS_COS_STR;
+ else if (filterID == FILTER_ABS_SINC)
+ name = FILTER_ABS_SINC_STR;
+ else if (filterID == FILTER_ABS_G_HAMMING)
+ name = FILTER_ABS_HAMMING_STR;
+ else if (filterID == FILTER_ABS_BANDLIMIT)
+ name = FILTER_ABS_BANDLIMIT_STR;
+ else if (filterID == FILTER_COSINE)
+ name = FILTER_COS_STR;
+ else if (filterID == FILTER_SINC)
+ name = FILTER_SINC_STR;
+ else if (filterID == FILTER_G_HAMMING)
+ name = FILTER_HAMMING_STR;
+ else if (filterID == FILTER_BANDLIMIT)
+ name = FILTER_BANDLIMIT_STR;
+ else if (filterID == FILTER_TRIANGLE)
+ name = FILTER_TRIANGLE_STR;
+
+ return (name);
+}
+
+const SignalFilter::FilterMethodID
+SignalFilter::convertFilterMethodNameToID (const char* const filterMethodName)
+{
+ FilterMethodID fmID = FILTER_METHOD_INVALID;
+
+ if (strcasecmp (filterMethodName, FILTER_METHOD_CONVOLUTION_STR) == 0)
+ fmID = FILTER_METHOD_CONVOLUTION;
+ else if (strcasecmp (filterMethodName, FILTER_METHOD_FOURIER_STR) == 0)
+ fmID = FILTER_METHOD_FOURIER;
+ else if (strcasecmp (filterMethodName, FILTER_METHOD_FFT_STR) == 0)
+ fmID = FILTER_METHOD_FFT;
+ else if (strcasecmp (filterMethodName, FILTER_METHOD_FFT_ZEROPAD_2_STR) == 0)
+ fmID = FILTER_METHOD_FFT_ZEROPAD_2;
+ else if (strcasecmp (filterMethodName, FILTER_METHOD_FFT_ZEROPAD_4_STR) == 0)
+ fmID = FILTER_METHOD_FFT_ZEROPAD_4;
+ else if (strcasecmp (filterMethodName, FILTER_METHOD_FFT_ZEROPAD_6_STR) == 0)
+ fmID = FILTER_METHOD_FFT_ZEROPAD_6;
+
+ return (fmID);
+}
+
+const char *
+SignalFilter::convertFilterMethodIDToName (const FilterMethodID fmID)
+{
+ const char *name = "";
+
+ if (fmID == FILTER_METHOD_CONVOLUTION)
+ return (FILTER_METHOD_CONVOLUTION_STR);
+ else if (fmID == FILTER_METHOD_FOURIER)
+ return (FILTER_METHOD_FOURIER_STR);
+ else if (fmID == FILTER_METHOD_FFT)
+ return (FILTER_METHOD_FFT_STR);
+ else if (fmID == FILTER_METHOD_FFT_ZEROPAD_2)
+ return (FILTER_METHOD_FFT_ZEROPAD_2_STR);
+ else if (fmID == FILTER_METHOD_FFT_ZEROPAD_4)
+ return (FILTER_METHOD_FFT_ZEROPAD_4_STR);
+ else if (fmID == FILTER_METHOD_FFT_ZEROPAD_6)
+ return (FILTER_METHOD_FFT_ZEROPAD_6_STR);
+
+ return (name);
+}
+
+const SignalFilter::DomainID
+SignalFilter::convertDomainNameToID (const char* const domainName)
+{
+ DomainID dID = DOMAIN_INVALID;
+
+ if (strcasecmp (domainName, DOMAIN_SPATIAL_STR) == 0)
+ dID = DOMAIN_SPATIAL;
+ else if (strcasecmp (domainName, DOMAIN_FREQUENCY_STR) == 0)
+ dID = DOMAIN_FREQUENCY;
+
+ return (dID);
+}
+
+const char *
+SignalFilter::convertDomainIDToName (const DomainID domain)
+{
+ const char *name = "";
+
+ if (domain == DOMAIN_SPATIAL)
+ return (DOMAIN_SPATIAL_STR);
+ else if (domain == DOMAIN_FREQUENCY)
+ return (DOMAIN_FREQUENCY_STR);
+
+ return (name);
+}
+
+
+void
+SignalFilter::filterSignal (const float input[], double output[]) const
+{
+ if (m_idFilterMethod == FILTER_METHOD_CONVOLUTION) {
+ for (int i = 0; i < m_nSignalPoints; i++)
+ output[i] = convolve (input, m_signalInc, i, m_nSignalPoints);
+ } else if (m_idFilterMethod == FILTER_METHOD_FOURIER) {
+ complex<double> fftSignal[m_nSignalPoints];
+ complex<double> complexOutput[m_nSignalPoints];
+ complex<double> filteredSignal[m_nSignalPoints];
+ finiteFourierTransform (input, fftSignal, m_nSignalPoints, -1);
+ dotProduct (m_vecFilter, fftSignal, filteredSignal, m_nSignalPoints);
+ finiteFourierTransform (filteredSignal, complexOutput, m_nSignalPoints, 1);
+ for (int i = 0; i < m_nSignalPoints; i++)
+ output[i] = complexOutput[i].real();
+ } else if (m_idFilterMethod == FILTER_METHOD_FFT || FILTER_METHOD_FFT_ZEROPAD_2 || FILTER_METHOD_FFT_ZEROPAD_4) {
+ fftw_complex in[m_nFilterPoints], out[m_nFilterPoints];
+ for (int i = 0; i < m_nSignalPoints; i++) {
+ in[i].re = input[i];
+ in[i].im = 0;
+ }
+ for (int i = m_nSignalPoints; i < m_nFilterPoints; i++) {
+ in[i].re = in[i].im = 0; // ZeroPad
+ }
+ fftw_one(m_planForward, in, out);
+ for (int i = 0; i < m_nFilterPoints; i++) {
+ out[i].re = m_vecFilter[i] * out[i].re;
+ out[i].im = m_vecFilter[i] * out[i].im;
+ }
+ fftw_one(m_planBackward, out, in);
+ for (int i = 0; i < m_nSignalPoints; i++)
+ output[i] = in[i].re;
+ }