summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVasile Vilvoiu <vasi@vilvoiu.ro>2021-07-20 18:39:30 +0300
committerVasile Vilvoiu <vasi@vilvoiu.ro>2021-07-20 18:39:30 +0300
commita5943fb45b4065da9284f59cb912f6161823216a (patch)
tree2f26c46a2d4b1845ef65db2e6ff9a1d142077ec2
parent46f0cc9395ffc841626d9242238868383c146233 (diff)
No window constructor for FFT.
NaN fix in FFT::Resample. FFT::Crop index fix.
-rw-r--r--src/fft.cpp34
-rw-r--r--src/fft.hpp3
2 files changed, 26 insertions, 11 deletions
diff --git a/src/fft.cpp b/src/fft.cpp
index 2802346..1cb84e9 100644
--- a/src/fft.cpp
+++ b/src/fft.cpp
@@ -37,9 +37,13 @@ sinc(double x)
}
}
-FFT::FFT(std::size_t win_width, std::unique_ptr<WindowFunction>& win_func)
- : window_width_(win_width), window_function_(std::move(win_func))
+FFT::FFT(std::size_t win_width) : window_width_(win_width)
{
+ /* no zero-width fft */
+ if (win_width == 0) {
+ throw std::runtime_error("cannot compute zero-width fft");
+ }
+
/* allocate buffers */
this->in_ = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * win_width);
assert(this->in_ != nullptr);
@@ -50,6 +54,11 @@ FFT::FFT(std::size_t win_width, std::unique_ptr<WindowFunction>& win_func)
this->plan_ = fftw_plan_dft_1d(win_width, this->in_, this->out_, FFTW_FORWARD, FFTW_ESTIMATE);
}
+FFT::FFT(std::size_t win_width, std::unique_ptr<WindowFunction>& win_func) : FFT(win_width)
+{
+ this->window_function_ = std::move(win_func);
+}
+
FFT::~FFT()
{
fftw_destroy_plan(this->plan_);
@@ -204,7 +213,9 @@ FFT::Resample(const RealWindow& input, double rate, std::size_t width, double fm
}
}
- output[j] = std::clamp<double>(sum / lsum, 0.0f, 1.0f);
+ double value = sum / lsum;
+ value = std::isnan(value) ? 0.0 : value;
+ output[j] = std::clamp<double>(value, 0.0f, 1.0f);
}
return output;
@@ -225,15 +236,18 @@ FFT::Crop(const RealWindow& input, double rate, double fmin, double fmax)
/* [i_fmin..i_fmax] -> [fmin, fmax] */
double di_fmin = std::round(FFT::GetFrequencyIndex(rate, input.size(), fmin));
double di_fmax = std::round(FFT::GetFrequencyIndex(rate, input.size(), fmax));
- assert(di_fmin >= 0);
- assert(di_fmax < input.size());
- assert(di_fmin < di_fmax);
/* we're cropping, so no interpolation allowed */
- auto i_fmin = static_cast<std::size_t>(di_fmin);
- auto i_fmax = static_cast<std::size_t>(di_fmax);
- assert(i_fmax - i_fmin > 0);
+ auto i_fmin = static_cast<std::int64_t>(di_fmin);
+ auto i_fmax = static_cast<std::int64_t>(di_fmax);
+
+ if (i_fmin < 0) {
+ throw std::runtime_error("fmin outside of window");
+ }
+ if (i_fmax >= input.size()) {
+ throw std::runtime_error("fmax outside of window");
+ }
/* return corresponding subvector */
- return RealWindow(input.begin() + i_fmin, input.begin() + i_fmax);
+ return RealWindow(input.begin() + i_fmin, input.begin() + i_fmax + 1);
}
diff --git a/src/fft.hpp b/src/fft.hpp
index 273a7f5..9008c05 100644
--- a/src/fft.hpp
+++ b/src/fft.hpp
@@ -33,6 +33,7 @@ public:
FFT(FFT &&) = delete;
FFT & operator=(const FFT&) = delete;
+ explicit FFT(std::size_t win_width);
FFT(std::size_t win_width, std::unique_ptr<WindowFunction>& win_func);
virtual ~FFT();
@@ -45,4 +46,4 @@ public:
static RealWindow Crop(const RealWindow& input, double rate, double fmin, double fmax);
};
-#endif \ No newline at end of file
+#endif