suanPan
resampling.h
Go to the documentation of this file.
1/*******************************************************************************
2 * Copyright (C) 2017-2024 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
23enum class WindowType {
24 Hamming,
25 Hann,
30};
31
32uword gcd(uword, uword);
33
34vec hamming(uword);
35vec hann(uword);
36vec blackman(uword);
37vec blackman_nuttall(uword);
38vec blackman_harris(uword);
39vec flat_top(uword);
40
41vec fir_low_pass(uword, double, vec (*)(uword));
42vec fir_high_pass(uword, double, vec (*)(uword));
43vec fir_band_pass(uword, double, double, vec (*)(uword));
44vec fir_band_stop(uword, double, double, vec (*)(uword));
45
46template<WindowType T> vec fir_low_pass(uword, double) { throw invalid_argument("unknown window type"); }
47
48template<> vec fir_low_pass<WindowType::Hamming>(uword, double);
49
50template<> vec fir_low_pass<WindowType::Hann>(uword, double);
51
52template<> vec fir_low_pass<WindowType::Blackman>(uword, double);
53
54template<> vec fir_low_pass<WindowType::BlackmanNuttall>(uword, double);
55
56template<> vec fir_low_pass<WindowType::BlackmanHarris>(uword, double);
57
58template<> vec fir_low_pass<WindowType::FlatTop>(uword, double);
59
60template<WindowType T> vec fir_high_pass(uword, double) { throw invalid_argument("unknown window type"); }
61
62template<> vec fir_high_pass<WindowType::Hamming>(uword, double);
63
64template<> vec fir_high_pass<WindowType::Hann>(uword, double);
65
66template<> vec fir_high_pass<WindowType::Blackman>(uword, double);
67
68template<> vec fir_high_pass<WindowType::BlackmanNuttall>(uword, double);
69
70template<> vec fir_high_pass<WindowType::BlackmanHarris>(uword, double);
71
72template<> vec fir_high_pass<WindowType::FlatTop>(uword, double);
73
74template<WindowType T> vec fir_band_pass(uword, double, double) { throw invalid_argument("unknown window type"); }
75
76template<> vec fir_band_pass<WindowType::Hamming>(uword, double, double);
77
78template<> vec fir_band_pass<WindowType::Hann>(uword, double, double);
79
80template<> vec fir_band_pass<WindowType::Blackman>(uword, double, double);
81
82template<> vec fir_band_pass<WindowType::BlackmanNuttall>(uword, double, double);
83
84template<> vec fir_band_pass<WindowType::BlackmanHarris>(uword, double, double);
85
86template<> vec fir_band_pass<WindowType::FlatTop>(uword, double, double);
87
88template<WindowType T> vec fir_band_stop(uword, double, double) { throw invalid_argument("unknown window type"); }
89
90template<> vec fir_band_stop<WindowType::Hamming>(uword, double, double);
91
92template<> vec fir_band_stop<WindowType::Hann>(uword, double, double);
93
94template<> vec fir_band_stop<WindowType::Blackman>(uword, double, double);
95
96template<> vec fir_band_stop<WindowType::BlackmanNuttall>(uword, double, double);
97
98template<> vec fir_band_stop<WindowType::BlackmanHarris>(uword, double, double);
99
100template<> vec fir_band_stop<WindowType::FlatTop>(uword, double, double);
101
102template<WindowType T> vec upsampling(const vec& in, const uword up_rate, const uword window_size) {
103 const vec coef = static_cast<double>(up_rate) * fir_low_pass<T>(window_size * 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
112template<WindowType T> mat upsampling(const string& file_name, const uword up_rate, const uword window_size) {
113 mat ext_data;
114 if(std::error_code code; !fs::exists(file_name, code) || !ext_data.load(file_name, raw_ascii) || ext_data.empty() || ext_data.n_cols < 2) {
115 ext_data.reset();
116 return ext_data;
117 }
118
119 const vec time_diff = diff(ext_data.col(0));
120
121 if(!suanpan::approx_equal(time_diff.min(), time_diff.max(), 1000000)) {
122 ext_data.reset();
123 return ext_data;
124 }
125
126 const auto upsampled_data = upsampling<T>(ext_data.col(1), up_rate, window_size);
127
128 mat result(upsampled_data.n_elem, 2, fill::none);
129
130 result.col(1) = upsampled_data;
131
132 const auto time_size = mean(time_diff) / static_cast<double>(up_rate);
133
134 for(auto I = 0llu; I < result.n_rows; ++I) result(I, 0) = static_cast<double>(I) * time_size;
135
136 return result;
137}
138
139mat upsampling(const string&, const string&, uword, uword = 8llu);
140
141#endif
std::enable_if_t<!std::numeric_limits< T >::is_integer, bool > approx_equal(T x, T y, int ulp=2)
Definition: utility.h:60
vec hann(uword)
Definition: resampling.cpp:46
vec blackman_harris(uword)
Definition: resampling.cpp:52
WindowType
Definition: resampling.h:23
vec upsampling(const vec &in, const uword up_rate, const uword window_size)
Definition: resampling.h:102
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 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