2 #include <Engine/Node/SimpleApi.hpp>
4 #include <ossia/detail/logger.hpp>
5 #include <ossia/network/value/format_value.hpp>
7 #include <libossia/3rdparty/dno/DeNoiser.hpp>
9 namespace Nodes::ValueFilter
18 DeNoiser<double>{}, DeNoiser<double>{}, DeNoiser<double>{},
23 DeNoiser<double> dno_i;
24 std::vector<DeNoiser<double>> dno_v;
26 ossia::value filter(
const ossia::value& val)
30 ossia::value operator()()
const {
return {}; }
31 ossia::value operator()(
const ossia::impulse&)
const {
return {}; }
32 ossia::value operator()(
int i)
const {
return nFilt->dno_i(i); }
33 ossia::value operator()(
float f)
const {
return nFilt->dno_v[0](f); }
34 ossia::value operator()(
bool b)
const {
return b; }
35 ossia::value operator()(
const std::string& s)
const {
return s; }
36 ossia::value operator()(
const ossia::vec2f& t)
const
38 return ossia::make_vec(nFilt->dno_v[0](t[0]), nFilt->dno_v[1](t[1]));
40 ossia::value operator()(
const ossia::vec3f& t)
const
42 return ossia::make_vec(
43 nFilt->dno_v[0](t[0]), nFilt->dno_v[1](t[1]), nFilt->dno_v[2](t[2]));
45 ossia::value operator()(
const ossia::vec4f& t)
const
47 return ossia::make_vec(
48 nFilt->dno_v[0](t[0]), nFilt->dno_v[1](t[1]), nFilt->dno_v[2](t[2]),
49 nFilt->dno_v[3](t[3]));
52 ossia::value operator()(
const std::vector<ossia::value>& t)
const
54 std::vector<ossia::value> ret = t;
55 while(nFilt->dno_v.size() < ret.size())
56 nFilt->dno_v.push_back(nFilt->dno_v.front());
58 for(std::size_t k = 0; k < ret.size(); k++)
59 ret[k] = (
float)nFilt->dno_v[k](ossia::convert<float>(ret[k]));
64 ossia::value operator()(
const ossia::value_map_type& t)
const
80 return ossia::apply(vis{
this}, val.v);
82 catch(std::exception& e)
84 ossia::logger().error(
"{}", e.what());
88 ossia::logger().error(
"error");
94 void set_amount(
float amt)
96 dno_i.set_amount(amt);
101 void set_type(
const type& t = OneEuro)
108 void set_freq(
double freq)
110 dno_i.set_freq(freq);
115 void set_cutoff(
double cutoff)
117 dno_i.set_cutoff(cutoff);
119 f.set_cutoff(cutoff);
122 void set_beta(
double beta)
124 dno_i.set_1e_beta(beta);
134 const ossia::value& value,
const std::string& type,
float amount,
float freq,
135 float cutoff,
float beta)
137 if(type != prev_type)
139 nf.set_type(GetFilterType(type));
142 prev_amount = INFINITY;
143 prev_freq = INFINITY;
144 prev_cutoff = INFINITY;
145 prev_beta = INFINITY;
147 if(amount != prev_amount)
149 nf.set_amount(amount);
150 prev_amount = amount;
152 if(freq != prev_freq)
157 if(cutoff != prev_cutoff)
159 nf.set_cutoff(cutoff);
160 prev_cutoff = cutoff;
162 if(beta != prev_beta)
168 return nf.filter(value);
174 std::string prev_type{
"OneEuro"};
175 double prev_amount{1. / SCALED_AMOUNT}, prev_freq{INIT_FREQ}, prev_cutoff{INIT_CUTOFF},
176 prev_beta{INIT_BETA};
180 type GetFilterType(std::string_view str) noexcept
184 else if(str ==
"Average")
186 else if(str ==
"Median")
198 static const constexpr
auto prettyName =
"Smooth (old)";
199 static const constexpr
auto objectKey =
"ValueFilter";
200 static const constexpr
auto category =
"Control/Mappings";
201 static const constexpr
auto author =
"ossia score";
202 static const constexpr
auto tags = std::array<const char*, 0>{};
203 static const constexpr
auto kind
204 = Process::ProcessCategory::Mapping | Process::ProcessCategory::Deprecated;
205 static const constexpr
auto description =
"Filter noisy value stream";
206 static const uuid_constexpr
auto uuid
207 = make_uuid(
"809c014d-7d02-45dc-8849-de7a7db5fe67");
209 static const constexpr
auto controls = tuplet::make_tuple(
211 "Type", 0U, ossia::make_array(
"OneEuro",
"LowPass",
"Average",
"Median")),
217 static const constexpr value_in value_ins[]{
"in"};
218 static const constexpr value_out value_outs[]{
"out"};
222 using control_policy = ossia::safe_nodes::last_tick;
225 run(
const ossia::value_port& in,
const std::string& type,
float amount,
float freq,
226 float cutoff,
float beta, ossia::value_port& out, ossia::token_request t,
227 ossia::exec_state_facade st,
State&
self)
229 for(
const ossia::timed_value& v : in.get_data())
231 auto filtered =
self.filter(v.value, type, amount, freq, cutoff, beta);
232 out.write_value(filtered, v.timestamp);
235 if(!in.get_data().empty())
237 self.last = in.get_data().back().value;
242 Process::Enum& type, Process::FloatKnob& amount, Process::LogFloatSlider& freq,
243 Process::LogFloatSlider& cutoff, Process::FloatSlider& beta,
250 const auto tMarg = 5;
251 const auto cMarg = 15;
256 c0_bg->setRect({0., 0., w, h});
258 auto type_item = makeControl(
259 tuplet::get<0>(Metadata::controls), type, parent, context, doc, portFactory);
260 type_item.root.setPos(70, 0);
261 type_item.control.rows = 4;
262 type_item.control.columns = 1;
263 type_item.control.setRect(QRectF{0, 0, 60, 105});
265 auto amount_item = makeControl(
266 tuplet::get<1>(Metadata::controls), amount, parent, context, doc, portFactory);
267 amount_item.root.setPos(tMarg, 30);
268 amount_item.control.setPos(0, cMarg);
270 auto freq_item = makeControl(
271 tuplet::get<2>(Metadata::controls), freq, parent, context, doc, portFactory);
272 freq_item.root.setPos(140, 0);
273 freq_item.control.setPos(0, cMarg);
275 auto cutoff_item = makeControl(
276 tuplet::get<3>(Metadata::controls), cutoff, parent, context, doc, portFactory);
277 cutoff_item.root.setPos(140, 40);
278 cutoff_item.control.setPos(0, cMarg);
280 auto beta_item = makeControl(
281 tuplet::get<4>(Metadata::controls), beta, parent, context, doc, portFactory);
282 beta_item.root.setPos(140, 80);
283 beta_item.control.setPos(0, cMarg);
294 static const constexpr
auto prettyName =
"Smooth";
295 static const constexpr
auto objectKey =
"ValueFilter";
296 static const constexpr
auto category =
"Control/Mappings";
297 static const constexpr
auto author =
"ossia score";
298 static const constexpr
auto tags = std::array<const char*, 0>{};
299 static const constexpr
auto kind = Process::ProcessCategory::Mapping;
300 static const constexpr
auto description =
"Filter noisy value stream";
301 static const uuid_constexpr
auto uuid
302 = make_uuid(
"bf603921-5a48-4aa5-9bc1-48a762be6467");
304 static const constexpr
auto controls = tuplet::make_tuple(
306 "Type", 0U, ossia::make_array(
"OneEuro",
"LowPass",
"Average",
"Median")),
313 static const constexpr value_in value_ins[]{
"in"};
314 static const constexpr value_out value_outs[]{
"out"};
318 using control_policy = ossia::safe_nodes::last_tick;
321 run(
const ossia::value_port& in,
const std::string& type,
float amount,
float freq,
322 float cutoff,
float beta,
bool continuous, ossia::value_port& out,
323 ossia::token_request t, ossia::exec_state_facade st,
State&
self)
325 for(
const ossia::timed_value& v : in.get_data())
327 auto filtered =
self.filter(v.value, type, amount, freq, cutoff, beta);
328 out.write_value(filtered, v.timestamp);
331 if(!in.get_data().empty())
333 self.last = in.get_data().back().value;
337 if(continuous &&
self.last.valid())
339 auto filtered =
self.filter(
self.last, type, amount, freq, cutoff, beta);
340 out.write_value(filtered, st.timings(t).start_sample);
346 Process::Enum& type, Process::FloatKnob& amount, Process::LogFloatSlider& freq,
347 Process::LogFloatSlider& cutoff, Process::FloatSlider& beta, Process::Toggle& cont,
354 const auto tMarg = 5;
355 const auto cMarg = 15;
360 c0_bg->setRect({0., 0., w, h});
362 auto type_item = makeControl(
363 tuplet::get<0>(Metadata::controls), type, parent, context, doc, portFactory);
364 type_item.root.setPos(70, 0);
365 type_item.control.rows = 4;
366 type_item.control.columns = 1;
367 type_item.control.setRect(QRectF{0, 0, 60, 105});
369 auto amount_item = makeControl(
370 tuplet::get<1>(Metadata::controls), amount, parent, context, doc, portFactory);
371 amount_item.root.setPos(tMarg, 30);
372 amount_item.control.setPos(0, cMarg);
374 auto freq_item = makeControl(
375 tuplet::get<2>(Metadata::controls), freq, parent, context, doc, portFactory);
376 freq_item.root.setPos(140, 0);
377 freq_item.control.setPos(0, cMarg);
379 auto cutoff_item = makeControl(
380 tuplet::get<3>(Metadata::controls), cutoff, parent, context, doc, portFactory);
381 cutoff_item.root.setPos(140, 40);
382 cutoff_item.control.setPos(0, cMarg);
384 auto beta_item = makeControl(
385 tuplet::get<4>(Metadata::controls), beta, parent, context, doc, portFactory);
386 beta_item.root.setPos(140, 80);
387 beta_item.control.setPos(0, cMarg);
389 auto cont_item = makeControl(
390 tuplet::get<5>(Metadata::controls), cont, parent, context, doc, portFactory);
391 cont_item.root.setPos(tMarg, 0);
Definition: Smooth.hpp:131
Definition: PortFactory.hpp:65
The Process class.
Definition: score-lib-process/Process/Process.hpp:61
Definition: RectItem.hpp:96
Base classes and tools to implement processes and layers.
Definition: JSONVisitor.hpp:1324
Utilities for OSSIA data structures.
Definition: DeviceInterface.hpp:33
Definition: score-lib-process/Control/Widgets.hpp:77
Definition: score-lib-process/Control/Widgets.hpp:337
Definition: Smooth.hpp:14
Definition: Smooth.hpp:195
Definition: Smooth.hpp:291
Definition: ProcessContext.hpp:12
const T & interfaces() const
Access to a specific interface list.
Definition: ApplicationContext.hpp:67