2 #include <Scenario/Document/Interval/IntervalModel.hpp>
4 #include <Effect/EffectLayer.hpp>
5 #include <Effect/EffectLayout.hpp>
7 #include <ossia/detail/math.hpp>
8 #include <ossia/detail/parse_strict.hpp>
9 #include <ossia/math/safe_math.hpp>
10 #include <ossia/network/value/format_value.hpp>
14 #include <halp/audio.hpp>
15 #include <halp/callback.hpp>
16 #include <halp/controls.hpp>
17 #include <halp/meta.hpp>
21 using value_out = halp::callback<
"out", ossia::value>;
23 namespace Ui::SignalDisplay
27 halp_meta(name,
"Signal display")
28 halp_meta(c_name,
"SignalDisplay")
29 halp_meta(category,
"Monitoring")
30 halp_meta(author,
"ossia score")
33 "https://ossia.io/score-docs/common-practices/"
34 "4-audio.html#analysing-an-audio-signal")
35 halp_meta(description,
"Visualize an input signal")
36 halp_meta(uuid,
"9906e563-ddeb-4ecd-908c-952baee2a0a5")
37 halp_flag(fully_custom_item);
39 halp_flag(loops_by_default);
41 using vec_type = boost::container::small_vector<float, 8>;
44 struct : halp::val_port<
"in", std::optional<ossia::value>>
55 struct : halp::val_port<
"out", std::optional<vec_type>>
67 void operator()()
const noexcept { }
68 void operator()(ossia::impulse)
const noexcept { ret.push_back(1.f); }
69 void operator()(
int v)
const noexcept { ret.push_back(v); }
70 void operator()(
float v)
const noexcept { ret.push_back(v); }
71 void operator()(
bool v)
const noexcept { ret.push_back(v ? 1.f : 0.f); }
72 void operator()(std::string_view v)
const noexcept
74 if(
auto res = ossia::parse_strict<float>(v))
77 template <std::
size_t N>
78 void operator()(std::array<float, N> arr)
const noexcept
80 ret.insert(ret.end(), arr.begin(), arr.end());
82 void operator()(
const std::vector<ossia::value>& arr)
const noexcept
84 ret.reserve(1 + arr.size());
87 ret.push_back(ossia::convert<float>(val));
90 void operator()(
const ossia::value_map_type& arr)
const noexcept
92 ret.reserve(1 + arr.size());
93 for(
auto& [k, v] : arr)
95 ret.push_back(ossia::convert<float>(v));
100 using tick = halp::tick_flicks;
101 void operator()(halp::tick_flicks tk)
103 if(
auto& opt_v = inputs.port.value)
105 const auto& v = *opt_v;
106 const float val = ossia::convert<float>(v);
107 if(ossia::safe_isnan(val) || ossia::safe_isinf(val))
111 ret.push_back(
float(tk.relative_position));
115 outputs.port.value =
static_cast<vec_type&&
>(ret);
120 static constexpr
int timestamp_index = 0;
121 static constexpr
int first_value_index = 1;
126 std::vector<vec_type> m_values;
132 QGraphicsItem* parent)
134 , m_interval{Scenario::closestParentInterval(process.parent())}
141 auto inl = safe_cast<Process::ControlInlet*>(process.inlets().front());
143 auto fact = portFactory.
get(inl->concreteKey());
144 auto port = fact->makePortItem(*inl, doc,
this,
this);
148 m_interval, &Scenario::IntervalModel::executionEvent,
this,
149 [
this](Scenario::IntervalExecutionEvent ev) {
152 case Scenario::IntervalExecutionEvent::Playing:
153 case Scenario::IntervalExecutionEvent::Stopped:
161 auto outl = safe_cast<Process::ControlOutlet*>(process.outlets().front());
163 outl, &Process::ControlOutlet::valueChanged,
this,
164 [
this](
const ossia::value& v) {
165 auto& val = *v.target<std::vector<ossia::value>>();
172 for(
auto it = val.begin(); it != val.end(); ++it)
174 vv.push_back(*it->target<
float>());
178 if(!m_values.empty() && !m_values.back().empty())
179 if(vv[timestamp_index] < m_values.back()[timestamp_index])
184 m_values.push_back(std::move(vv));
205 void paint_impl(QPainter* p)
const override
207 if(m_values.size() < 2)
210 p->setRenderHint(QPainter::Antialiasing,
true);
211 p->setPen(score::Skin::instance().Light.main.pen1_solid_flat_miter);
213 const auto w = width();
214 const auto h = height();
215 double min = 0, max = 1;
217 const auto to_01 = [&](
float v) {
return 1. - (v - min) / (max - min); };
219 m_values[0][timestamp_index] * w, to_01(m_values[0][first_value_index]) * h};
220 for(std::size_t i = 1; i < m_values.size(); i++)
222 const auto& value = m_values[i];
223 QPointF p1 = {value[timestamp_index] * w, to_01(value[first_value_index]) * h};
225 if(QLineF l{p0, p1}; l.length() > 2)
232 p->setRenderHint(QPainter::Antialiasing,
false);
Definition: EffectLayer.hpp:16
Definition: PortFactory.hpp:74
The Process class.
Definition: score-lib-process/Process/Process.hpp:61
Definition: IntervalModel.hpp:50
FactoryType * get(const key_type &k) const noexcept
Get a particular factory from its ConcreteKey.
Definition: InterfaceList.hpp:123
Definition: ProcessContext.hpp:12
Definition: SignalDisplay.hpp:119
Definition: SignalDisplay.hpp:65
Definition: SignalDisplay.hpp:26
const T & interfaces() const
Access to a specific interface list.
Definition: ApplicationContext.hpp:67