suanPan
resampling.h
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright (C) 2017-2022 Theodore Chang
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  ******************************************************************************/
17 
18 #ifndef RESAMPLING_H
19 #define RESAMPLING_H
20 
21 #include <Toolbox/utility.h>
22 
23 enum class WindowType {
24  Hamming,
25  Hann,
26  Blackman,
29  FlatTop
30 };
31 
32 uword gcd(uword, uword);
33 
34 vec hamming(uword);
35 vec hann(uword);
36 vec blackman(uword);
37 vec blackman_nuttall(uword);
38 vec blackman_harris(uword);
39 vec flat_top(uword);
40 
41 vec fir_low_pass(uword, double, vec (*)(uword));
42 vec fir_high_pass(uword, double, vec (*)(uword));
43 vec fir_band_pass(uword, double, double, vec (*)(uword));
44 vec fir_band_stop(uword, double, double, vec (*)(uword));
45 
46 template<WindowType T> vec fir_low_pass(uword, double) { throw invalid_argument("unknown window type"); }
47 
48 template<> vec fir_low_pass<WindowType::Hamming>(uword, double);
49 
50 template<> vec fir_low_pass<WindowType::Hann>(uword, double);
51 
52 template<> vec fir_low_pass<WindowType::Blackman>(uword, double);
53 
54 template<> vec fir_low_pass<WindowType::BlackmanNuttall>(uword, double);
55 
56 template<> vec fir_low_pass<WindowType::BlackmanHarris>(uword, double);
57 
58 template<> vec fir_low_pass<WindowType::FlatTop>(uword, double);
59 
60 template<WindowType T> vec fir_high_pass(uword, double) { throw invalid_argument("unknown window type"); }
61 
62 template<> vec fir_high_pass<WindowType::Hamming>(uword, double);
63 
64 template<> vec fir_high_pass<WindowType::Hann>(uword, double);
65 
66 template<> vec fir_high_pass<WindowType::Blackman>(uword, double);
67 
68 template<> vec fir_high_pass<WindowType::BlackmanNuttall>(uword, double);
69 
70 template<> vec fir_high_pass<WindowType::BlackmanHarris>(uword, double);
71 
72 template<> vec fir_high_pass<WindowType::FlatTop>(uword, double);
73 
74 template<WindowType T> vec fir_band_pass(uword, double, double) { throw invalid_argument("unknown window type"); }
75 
76 template<> vec fir_band_pass<WindowType::Hamming>(uword, double, double);
77 
78 template<> vec fir_band_pass<WindowType::Hann>(uword, double, double);
79 
80 template<> vec fir_band_pass<WindowType::Blackman>(uword, double, double);
81 
82 template<> vec fir_band_pass<WindowType::BlackmanNuttall>(uword, double, double);
83 
84 template<> vec fir_band_pass<WindowType::BlackmanHarris>(uword, double, double);
85 
86 template<> vec fir_band_pass<WindowType::FlatTop>(uword, double, double);
87 
88 template<WindowType T> vec fir_band_stop(uword, double, double) { throw invalid_argument("unknown window type"); }
89 
90 template<> vec fir_band_stop<WindowType::Hamming>(uword, double, double);
91 
92 template<> vec fir_band_stop<WindowType::Hann>(uword, double, double);
93 
94 template<> vec fir_band_stop<WindowType::Blackman>(uword, double, double);
95 
96 template<> vec fir_band_stop<WindowType::BlackmanNuttall>(uword, double, double);
97 
98 template<> vec fir_band_stop<WindowType::BlackmanHarris>(uword, double, double);
99 
100 template<> vec fir_band_stop<WindowType::FlatTop>(uword, double, double);
101 
102 template<WindowType T> vec upsampling(const vec& in, const uword up_rate) {
103  const vec coef = static_cast<double>(up_rate) * fir_low_pass<T>(8llu * up_rate, 1. / static_cast<double>(up_rate));
104 
105  vec out(up_rate * in.n_elem, fill::zeros);
106 
107  for(auto I = 0llu, J = 0llu; I < in.n_elem; ++I, J += up_rate) out(J) = in(I);
108 
109  return conv(out, coef, "same");
110 }
111 
112 template<WindowType T> mat upsampling(const string& file_name, const uword up_rate) {
113  mat ext_data;
114 
115  if(!fs::exists(file_name) || !ext_data.load(file_name) || ext_data.empty() || ext_data.n_cols < 2) {
116  ext_data.reset();
117  return ext_data;
118  }
119 
120  const vec time_diff = diff(ext_data.col(0));
121 
122  if(!suanpan::approx_equal(time_diff.min(), time_diff.max(), 1000000)) {
123  ext_data.reset();
124  return ext_data;
125  }
126 
127  const auto upsampled_data = upsampling<T>(ext_data.col(1), up_rate);
128 
129  mat result(upsampled_data.n_elem, 2, fill::none);
130 
131  result.col(1) = upsampled_data;
132 
133  const auto time_size = mean(time_diff) / static_cast<double>(up_rate);
134 
135  for(auto I = 0llu; I < result.n_rows; ++I) result(I, 0) = static_cast<double>(I) * time_size;
136 
137  return result;
138 }
139 
140 #endif
std::enable_if_t<!std::numeric_limits< T >::is_integer, bool > approx_equal(T x, T y, int ulp=2)
Definition: utility.h:46
vec hann(uword)
Definition: resampling.cpp:46
vec blackman_harris(uword)
Definition: resampling.cpp:52
WindowType
Definition: resampling.h:23
uword gcd(uword, uword)
Definition: resampling.cpp:20
vec fir_low_pass(uword, double, vec(*)(uword))
Definition: resampling.cpp:56
vec hamming(uword)
Definition: resampling.cpp:44
vec fir_band_pass(uword, double, double, vec(*)(uword))
Definition: resampling.cpp:89
vec upsampling(const vec &in, const uword up_rate)
Definition: resampling.h:102
vec blackman_nuttall(uword)
Definition: resampling.cpp:50
vec fir_band_stop(uword, double, double, vec(*)(uword))
Definition: resampling.cpp:110
vec fir_high_pass(uword, double, vec(*)(uword))
Definition: resampling.cpp:68
vec blackman(uword)
Definition: resampling.cpp:48
vec flat_top(uword)
Definition: resampling.cpp:54