+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] = abs( complexOutput[i] );
+ }
+ } 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 / m_nSignalPoints;
+ out[i].im = m_vecFilter[i] * out[i].im / m_nSignalPoints;
+ }
+ fftw_one(m_planBackward, out, in);
+ for (int i = 0; i < m_nSignalPoints; i++)
+ output[i] = sqrt (in[i].re * in[i].re + in[i].im * in[i].im);
+ }
+}
+
+double
+SignalFilter::response (double x)
+{
+ double response = 0;
+
+ if (m_idDomain == DOMAIN_SPATIAL)
+ response = spatialResponse (m_idFilter, m_bw, x, m_filterParam, m_numIntegral);
+ else if (m_idDomain == DOMAIN_FREQUENCY)
+ response = frequencyResponse (m_idFilter, m_bw, x, m_filterParam);
+
+ return (response);
+}
+
+
+double
+SignalFilter::spatialResponse (FilterID filterID, double bw, double x, double param, int nIntegral = 0)
+{
+ if (nIntegral == 0)
+ return spatialResponseAnalytic (filterID, bw, x, param);
+ else
+ return spatialResponseCalc (filterID, bw, x, param, nIntegral);
+}