OSSIA
Open Scenario System for Interactive Application
Loading...
Searching...
No Matches
forward_node.hpp
1#pragma once
2#include <ossia/dataflow/audio_port.hpp>
3#include <ossia/dataflow/graph_node.hpp>
4#include <ossia/dataflow/midi_port.hpp>
5#include <ossia/dataflow/port.hpp>
6#include <ossia/math/safe_math.hpp>
7namespace ossia::nodes
8{
9class forward_node : public ossia::nonowning_graph_node
10{
11public:
12 forward_node()
13 {
14 m_inlets.push_back(&audio_in);
15 // m_inlets.push_back(&midi_in);
16 m_outlets.push_back(&audio_out);
17 // m_outlets.push_back(&midi_out);
18 }
19
20 [[nodiscard]] std::string label() const noexcept override { return "forward_node"; }
21 void run(const token_request& t, exec_state_facade) noexcept override
22 {
23 // OPTIMIZEME : we copy the ins & outs of the token more
24 // than necessary
25 {
26 ossia::audio_port& i = *audio_in;
27 ossia::audio_port& o = *audio_out;
28 if(!audio_out.has_gain)
29 {
30 o = i;
31 }
32 else
33 {
34 switch(i.channels())
35 {
36 case 0:
37 return;
38
39 case 1:
40 process_audio_out_mono(i, audio_out);
41 break;
42
43 default:
44 process_audio_out_general(i, audio_out);
45 break;
46 }
47 }
48 }
49 // {
50 // auto i = midi_in.target<ossia::midi_port>();
51 // auto o = midi_out.target<ossia::midi_port>();
52 // o->messages = i->messages;
53 // }
54 }
55
56 ossia::audio_inlet audio_in;
57 // ossia::midi_inlet midi_in;
58 ossia::audio_outlet audio_out;
59 // ossia::midi_outlet midi_out;
60};
61
62class interval final : public forward_node
63{
64public:
65 using forward_node::forward_node;
66
67 ~interval()
68 {
69 if(m_inlets.size() == 4)
70 {
71 delete m_inlets[1];
72 delete m_inlets[2];
73 delete m_inlets[3];
74 m_inlets.resize(1);
75 }
76 }
77 [[nodiscard]] std::string label() const noexcept override { return "Interval"; }
78
79 void run(const token_request& t, exec_state_facade f) noexcept override
80 {
81 forward_node::run(t, f);
82 if(m_inlets.size() >= 4)
83 {
84 {
85 ossia::value_port& vp = *m_inlets[1]->target<ossia::value_port>();
86 if(auto& data = vp.get_data(); !data.empty())
87 {
88 tempo = ossia::convert<float>(data.back().value);
89 }
90 }
91 {
92 ossia::value_port& vp = *m_inlets[2]->target<ossia::value_port>();
93 if(auto& data = vp.get_data(); !data.empty())
94 {
95 const float s = ossia::convert<float>(data.back().value);
96 if(ossia::safe_isfinite(s) && s > no_speed && s < -no_speed)
97 speed_override = s;
98 }
99 }
100 {
101 ossia::value_port& vp = *m_inlets[3]->target<ossia::value_port>();
102 if(auto& data = vp.get_data(); !data.empty())
103 {
104 float seek_ms = ossia::convert<float>(data.back().value);
105 seek = ossia::flicks_per_millisecond<double> * seek_ms;
106 }
107 }
108 }
109 }
110
111 static const constexpr float no_tempo = -1000.f;
112 static const constexpr float no_speed = -1000.f;
113 float tempo{no_tempo};
114
120 float speed_override{no_speed};
121 int64_t seek{std::numeric_limits<int64_t>::min()};
122};
123class loop final : public forward_node
124{
125public:
126 using forward_node::forward_node;
127 [[nodiscard]] std::string label() const noexcept override { return "Loop"; }
128};
129class scenario final : public forward_node
130{
131public:
132 using forward_node::forward_node;
133 [[nodiscard]] std::string label() const noexcept override { return "Scenario"; }
134};
135}