-
Notifications
You must be signed in to change notification settings - Fork 0
/
operator_fft.cpp
149 lines (132 loc) · 3.53 KB
/
operator_fft.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// SPDX-License-Identifier: GPL-2.0
#include "operator_fft.hpp"
#include "document.hpp"
QJsonObject OperatorFFTState::to_json() const
{
QJsonObject res;
const char *id;
switch (type) {
case OperatorFFTType::FWD:
default:
id = "fwd";
break;
case OperatorFFTType::INV:
id = "inv";
break;
case OperatorFFTType::NORM:
id = "norm";
break;
}
res["type"] = id;
return res;
}
void OperatorFFTState::from_json(const QJsonObject &desc)
{
QString s = desc["type"].toString();
if (s == "inv")
type = OperatorFFTType::INV;
else if (s == "norm")
type = OperatorFFTType::NORM;
else
type = OperatorFFTType::FWD;
}
static const char *get_pixmap_name(OperatorFFTType type)
{
switch (type) {
case OperatorFFTType::FWD:
return ":/icons/fft.svg";
case OperatorFFTType::INV:
return ":/icons/fft_inv.svg";
case OperatorFFTType::NORM:
return ":/icons/fft_norm.svg";
default:
return "";
}
}
static const char *get_tooltip(OperatorFFTType type)
{
switch (type) {
case OperatorFFTType::FWD: return "Fourier transform";
case OperatorFFTType::INV: return "Inverse Fourier transform";
case OperatorFFTType::NORM: return "Norm of Fourier transform";
default:
return "";
}
}
QPixmap OperatorFFT::get_pixmap(OperatorFFTType type, int size)
{
const char *name = get_pixmap_name(type);
return QIcon(name).pixmap(QSize(size, size));
}
void OperatorFFT::init()
{
setPixmap(get_pixmap(state.type, simple_size));
menu = new MenuButton(Side::left, "Change transformation type", this);
menu->add_entry(get_pixmap(OperatorFFTType::FWD, default_button_height), get_tooltip(OperatorFFTType::FWD), [this](){ set_type(OperatorFFTType::FWD); });
menu->add_entry(get_pixmap(OperatorFFTType::INV, default_button_height), get_tooltip(OperatorFFTType::INV), [this](){ set_type(OperatorFFTType::INV); });
menu->add_entry(get_pixmap(OperatorFFTType::NORM, default_button_height), get_tooltip(OperatorFFTType::NORM), [this](){ set_type(OperatorFFTType::NORM); });
}
Operator::InitState OperatorFFT::make_init_state(OperatorFFTType type)
{
auto state = std::make_unique<OperatorFFTState>();
state->type = type;
return {
get_pixmap_name(type),
get_tooltip(type),
std::move(state)
};
}
std::vector<Operator::InitState> OperatorFFT::get_init_states()
{
std::vector<Operator::InitState> res;
res.push_back(make_init_state(OperatorFFTType::FWD));
res.push_back(make_init_state(OperatorFFTType::INV));
res.push_back(make_init_state(OperatorFFTType::NORM));
return res;
}
bool OperatorFFT::update_plan()
{
if (input_connectors[0]->is_empty_buffer()) {
plan.reset();
return make_output_empty(0);
}
bool forward = true;
bool norm = false;
if (state.type == OperatorFFTType::INV)
forward = false;
else if (state.type == OperatorFFTType::NORM)
norm = true;
FFTBuf &new_buf = input_connectors[0]->get_buffer();
bool updated_output = norm ?
make_output_real(0) : make_output_complex(0);
plan = std::make_unique<FFTPlan>(new_buf, output_buffers[0], forward, norm);
return updated_output;
}
bool OperatorFFT::input_connection_changed()
{
return update_plan();
}
void OperatorFFT::set_type(OperatorFFTType type)
{
if (state.type == type)
return;
auto new_state = clone_state();
new_state->type = type;
place_set_state_command("Set FFT type", std::move(new_state), false);
}
void OperatorFFT::state_reset()
{
menu->set_pixmap((int)state.type);
setPixmap(get_pixmap(state.type, simple_size));
if (update_plan())
output_buffer_changed();
execute();
// Execute children
execute_topo();
}
void OperatorFFT::execute()
{
if (!plan)
return;
plan->execute();
}