Loading...
Searching...
No Matches
Spammer.hpp
1#include <ossia/detail/jthread.hpp>
2#include <ossia/detail/triple_buffer.hpp>
3#include <halp/mappers.hpp>
4#include <AvndProcesses/AddressTools.hpp>
5
6namespace avnd_tools
7{
8
10{
11 halp_meta(name, "Spammer")
12 halp_meta(author, "ossia team")
13 halp_meta(category, "Control/Data processing")
14 halp_meta(description, "Send a message at a given frequency")
15 halp_meta(c_name, "avnd_pattern_spam")
16 halp_meta(manual_url, "https://ossia.io/score-docs/processes/spammer.html")
17 halp_meta(uuid, "0fa9415b-dcda-4ab8-b3f5-353c5d35fc8a")
18
19 struct
20 {
21 halp::val_port<"Input", ossia::value> input;
22
23 struct : halp::time_chooser<"Delay", halp::range{0.0001, 30., 0.2}>
24 {
25 using mapper = halp::log_mapper<std::ratio<95, 100>>;
26 } delay;
27
28 PatternSelector pattern;
29 halp::knob_f32<"Smooth", halp::range{0., 1., 0.5}> smooth;
30 } inputs;
31
32 struct
33 {
34
35 } outputs;
36
37 void update()
38 {
39 m_thread = std::jthread{};
40 inputs.pattern.reprocess();
41 m_thread = std::jthread([this, roots = this->roots, cur = ossia::value{},
42 smooth = ossia::value{}](std::stop_token tk) mutable {
43 while(!tk.stop_requested())
44 {
45 std::this_thread::sleep_for(m_delay.load(std::memory_order_relaxed));
46 float s = m_smooth.load(std::memory_order_relaxed);
47 this->m_buffer.consume(cur);
48
49 smooth_recursively(smooth, cur, 1.f - s);
50 cur = smooth;
51
52 if(cur.valid())
53 {
54 for(auto p : roots)
55 {
56 p->get_parameter()->push_value(cur);
57 }
58 }
59 }
60 });
61 }
62
63 void operator()()
64 {
65 if(!m_path)
66 return;
67
68 m_smooth.store(inputs.smooth.value, std::memory_order_relaxed);
69 m_buffer.produce(inputs.input.value);
70
71 m_delay.store(
72 std::chrono::nanoseconds(int64_t(1e9 * inputs.delay.value)),
73 std::memory_order_release);
74 if(!m_thread.joinable() || inputs.pattern.devices_dirty)
75 {
76 update();
77 }
78 }
79
80 struct do_smooth
81 {
82 float a{};
83 void operator()(const int& in, int& filtered)
84 {
85 filtered = in * a + filtered * (1.0f - a);
86 }
87
88 void operator()(const float& in, float& filtered)
89 {
90 filtered = in * a + filtered * (1.0f - a);
91 }
92
93 void operator()(const bool& in, bool& filtered)
94 {
95 filtered = in * a + filtered * (1.0f - a);
96 }
97
98 template <std::size_t N>
99 void operator()(const std::array<float, N>& in, std::array<float, N>& filtered)
100 {
101 for(std::size_t i = 0; i < N; i++)
102 filtered[i] = in[i] * a + filtered[i] * (1.0f - a);
103 }
104
105 void
106 operator()(const std::vector<ossia::value>& in, std::vector<ossia::value>& filtered)
107 {
108 if(in.size() != filtered.size()) [[unlikely]]
109 filtered.resize(in.size());
110
111 for(std::size_t i = 0; i < in.size(); i++)
112 {
113 if(filtered[i].get_type() != in[i].get_type()) [[unlikely]]
114 filtered[i] = in[i];
115 else
116 ossia::apply(*this, in[i], filtered[i]);
117 }
118 }
119
120 void operator()(const std::string& in, std::string& filtered) { filtered = in; }
121 template <typename T>
122 void operator()(const T& in, T& filtered)
123 {
124 filtered = in;
125 }
126
127 template <typename T>
128 void operator()(const ossia::impulse& in, T& filtered)
129 {
130 (*this)(filtered, filtered);
131 }
132
133 void operator()(const ossia::impulse& in, ossia::impulse& filtered) { }
134 template <typename T, typename U>
135 void operator()(const T& in, U& filtered)
136 {
137 }
138 };
139
140 static void
141 smooth_recursively(ossia::value& prev, const ossia::value& next, float alpha)
142 {
143 if(prev.get_type() != next.get_type()) [[unlikely]]
144 prev = next;
145 else [[likely]]
146 {
147 if(prev.valid() && next.valid())
148 ossia::apply(do_smooth{alpha}, next, prev);
149 }
150 }
151
152 static_assert(std::atomic<std::chrono::nanoseconds>::is_always_lock_free);
153 std::atomic<std::chrono::nanoseconds> m_delay{std::chrono::nanoseconds{100000}};
154 std::atomic<float> m_smooth{};
155 std::jthread m_thread;
156 ossia::triple_buffer<ossia::value> m_buffer{ossia::value{}};
157
158 ossia::value m_prev;
159};
160}
Definition AddressTools.hpp:21
Definition AddressTools.hpp:28
Definition Spammer.hpp:81
Definition Spammer.hpp:10