Loading...
Searching...
No Matches
FactorOracle2MIDI.hpp
1#pragma once
2#include <ossia/detail/hash_map.hpp>
3#include <ossia/detail/math.hpp>
4#include <ossia/detail/ssize.hpp>
5
6#include <halp/controls.hpp>
7#include <halp/meta.hpp>
8#include <halp/midi.hpp>
9
10#include <random>
11#if !defined(NDEBUG) && !defined(_MSC_VER) && !defined(__clang__)
12#include <debug/vector>
13#define debug_vector_t __gnu_debug::vector
14#else
15#define debug_vector_t std::vector
16#endif
17
55namespace FactorOracle2MIDI
56{
59class Notes
60{
61public:
62 int note;
63 int pitch;
64 double startTime;
65 double endTime;
66};
67template <class T>
69{
70public:
74};
75
82template <class T>
83class State
84{
85public:
86 int state_;
87 std::vector<SingleTransition<T>> transition_;
88 int suffix_transition_;
89 int lrs_ = 0;
90 void singleTransitionResize() { transition_.resize(10); }
91};
92
93template <class T>
95{
96public:
97 int phi, k, fo_iter, current_state = 1;
98 std::vector<T> input_values;
99 std::vector<State<T>> states_;
100 std::vector<std::vector<int>> RevSuffix;
102 {
103 this->states_.resize(2);
104 this->states_[0].state_ = 0;
105 this->states_[0].lrs_ = 0;
106 this->states_[0].suffix_transition_ = -1;
107 this->RevSuffix.resize(2);
108 }
109 void AddLetter(int i, std::vector<T> word)
110 {
112
116 if(i != 0)
117 {
118 this->states_.resize(i + 1);
119 this->RevSuffix.resize(i + 1);
120 T alpha = word[i - 1];
121 this->AddState(i - 1);
122 int state_m_plus_one = i;
123 this->AddTransition(i - 1, i, alpha);
124 k = this->states_[i - 1].suffix_transition_;
125 phi = i - 1;
126 int flag = 0, iter = 0;
133 while(k > -1 && flag == 0)
134 {
135 while(iter < this->states_[k].transition_.size())
136 {
137 if(this->states_[k].transition_[iter].symbol_ == alpha)
138 {
139 flag = 1;
140 }
141 iter++;
142 }
143 if(flag == 0)
144 {
145 this->AddTransition(k, state_m_plus_one, alpha);
146 phi = k;
147 k = this->states_[k].suffix_transition_;
148 iter = 0;
149 }
150 }
151 if(k == -1)
152 {
153 this->states_[state_m_plus_one].suffix_transition_ = 0;
154 this->states_[state_m_plus_one].lrs_ = 0;
155 }
156 else
157 {
158 flag = 0, iter = 0;
159 if(this->states_[k].transition_[iter].symbol_ == alpha)
160 {
161 flag = 1;
162 this->states_[state_m_plus_one].suffix_transition_ = this->states_[k].transition_[iter].last_state_;
163 this->states_[state_m_plus_one].lrs_ = this->LengthCommonSuffix(phi, this->states_[state_m_plus_one].suffix_transition_ - 1) + 1;
164 }
165 while(iter < this->states_[k].transition_.size() && flag == 0)
166 {
167 if(this->states_[k].transition_[iter].symbol_ == alpha)
168 {
169
170 this->states_[state_m_plus_one].suffix_transition_ = this->states_[k].transition_[iter].last_state_;
171 this->states_[state_m_plus_one].lrs_ = this->LengthCommonSuffix(phi, this->states_[state_m_plus_one].suffix_transition_ - 1) + 1;
172 flag = 1;
173 }
174
175 iter++;
176 }
177 }
178 T temp_word = word[state_m_plus_one - this->states_[state_m_plus_one].lrs_ - 1];
179 k = this->FindBetter(state_m_plus_one, temp_word, word);
180 if(k != 0)
181 {
182 this->states_[state_m_plus_one].lrs_ = this->states_[state_m_plus_one].lrs_ + 1;
183 this->states_[state_m_plus_one].suffix_transition_ = k;
184 }
185 RevSuffix[this->states_[state_m_plus_one].suffix_transition_].push_back(state_m_plus_one);
186 }
187 };
188 int LengthCommonSuffix(int phi_one, int phi_two)
189 {
190 if(phi_two == this->states_[phi_one].suffix_transition_)
191 return this->states_[phi_one].lrs_;
192 else
193 {
194 while(this->states_[phi_one].suffix_transition_ != this->states_[phi_two].suffix_transition_)
195 phi_two = this->states_[phi_two].suffix_transition_;
196 }
197 if(this->states_[phi_one].lrs_ <= this->states_[phi_two].lrs_)
198 return this->states_[phi_one].lrs_;
199 else
200 return this->states_[phi_two].lrs_;
201 };
202 int FindBetter(int i, T alpha, std::vector<T> word)
203 {
205
212 int len_t = this->RevSuffix[this->states_[i].suffix_transition_].size();
213 int statei = this->states_[i].suffix_transition_;
214 if(len_t == 0)
215 return 0;
216 sort(this->RevSuffix[statei].begin(), this->RevSuffix[statei].end());
217 for(int j = 0; j < len_t; j++)
218 {
219 if(this->states_[this->RevSuffix[this->states_[i].suffix_transition_][j]].lrs_ == this->states_[i].lrs_ && word[this->RevSuffix[this->states_[i].suffix_transition_][j] - this->states_[i].lrs_ - 1] == alpha)
220 {
221 int output_midi = RevSuffix[this->states_[i].suffix_transition_][j];
222 return output_midi;
223 }
224 }
225 return 0;
226 };
227 std::vector<T> FOGenerate(int& i, std::vector<T> v, float q)
228 {
230
236 std::random_device rd;
237 std::mt19937 gen(rd());
238 std::uniform_real_distribution<> dis(0.0, 1.0);
239 float u = dis(gen);
240 if(this->states_.size() == 2 || this->states_.size() == 1)
241 {
242 v.push_back(this->states_[0].transition_[0].symbol_);
243 }
244 else
245 {
246 if(u < q)
247 {
248 i = i + 1;
249 int len = this->states_.size();
250 if(i >= len)
251 i = len - 1;
252 T w = this->states_[i].transition_[0].symbol_;
253 v.push_back(w);
254 }
255 else
256 {
257 int lenSuffix = this->states_[this->states_[i].suffix_transition_].transition_.size() - 1;
258 std::random_device rd;
259 std::mt19937 gen(rd());
260 std::uniform_int_distribution<> dis_int(0, lenSuffix);
261 int rand_alpha = dis_int(gen);
262 T alpha = this->states_[this->states_[i].suffix_transition_].transition_[rand_alpha].symbol_;
263 i = this->states_[this->states_[i].suffix_transition_].transition_[rand_alpha].last_state_;
264 if(i == -1)
265 {
266 i = 0;
267 }
268 v.push_back(alpha);
269 }
270 }
271 return v;
272 };
273 void FactorOracleStart(std::vector<T> word)
274 {
276
279 int len = std::ssize(word);
280 this->states_.resize(2);
281 this->states_[0].state_ = 0;
282 this->states_[0].lrs_ = 0;
283 this->states_[0].suffix_transition_ = -1;
284 this->RevSuffix.resize(2);
285 };
286 void AddState(int first_state) { this->states_[first_state].state_ = first_state; };
287 void AddTransition(int first_state, int last_state, T symbol)
288 {
289 SingleTransition<T> transition_i;
290 transition_i.first_state_ = first_state;
291 transition_i.last_state_ = last_state;
292 transition_i.symbol_ = symbol;
293 this->states_[first_state].transition_.push_back(transition_i);
294 };
295 std::vector<T> CallGenerate(int len, float q)
296 {
297
298 std::vector<T> oracle = {};
299 fo_iter = 1;
300 for(int x = 0; x < len; x++)
301 {
302 oracle = this->FOGenerate(fo_iter, oracle, q);
303 if(fo_iter == len)
304 fo_iter = len - 1;
305 }
306 return oracle;
307 };
308};
309}
310namespace Nodes::FactorOracle2MIDI
311{
312struct Node
313{
314 halp_meta(name, "New Factor Oracle MIDI")
315 halp_meta(c_name, "New Factor Oracle MIDI")
316 halp_meta(category, "Control/Impro")
317 halp_meta(manual_url, "")
318 halp_meta(author, "Maria Paula Carrero Rivas")
319 halp_meta(description, "Factor Oracle algorithm .") // TODO cite
320 halp_meta(uuid, "C87B5326-56C2-4489-8E08-AA9E1EF27359");
321
322 static const constexpr auto controls = tuplet::make_tuple(Control::IntSlider{"Sequence length", 1, 64, 8});
323 static const constexpr midi_in midi_ins[]{"input_midi"};
324 static const constexpr midi_out midi_outs[]{"output_midi"};
325 static const constexpr value_in value_ins[]{"regen", "bang"};
326
327 struct
328 {
329
330 } inputs;
331 struct
332 {
333
334 } outputs;
335 struct State
336 {
338 int i = 0;
339 debug_vector_t<libremidi::midi_bytes> sequence;
340 debug_vector_t<libremidi::midi_bytes> midi_bytes;
341 std::size_t sequence_idx{};
342 };
343
344 using control_policy = ossia::safe_nodes::last_tick;
345 static void run(const ossia::midi_port& input_midi, const ossia::value_port& regen, const ossia::value_port& bangs, int seq_len, ossia::midi_port& output_midi, ossia::token_request, ossia::exec_state_facade, State& self)
346 {
347
348 // Entrées sont dans p1
349 for(auto val : input_midi.messages)
350 {
352 temp.pitch = val.bytes[1];
353 self.oracle.input_values.push_back(val.bytes[1]);
354 self.oracle.AddLetter(self.oracle.current_state, self.oracle.input_values);
355 self.oracle.current_state = self.oracle.current_state + 1;
356 }
357
358 if(!regen.get_data().empty())
359 {
360 if(!self.oracle.input_values.empty())
361 {
362 std::vector<int> temp_vec = self.oracle.CallGenerate(seq_len, 0.6);
363 //self.sequence = self.oracle.CallGenerate(seq_len, 0.6);
364 self.midi_bytes.push_back({144, 0, 40});
365 self.midi_bytes[seq_len][1] = temp_vec[seq_len];
366 self.sequence = self.midi_bytes;
367 }
368 }
369
370 if(!self.sequence.empty() && !self.oracle.input_values.empty())
371 {
372 for(auto& bang : bangs.get_data())
373 {
374 self.sequence_idx = ossia::clamp<int64_t>((int64_t)self.sequence_idx, 0, (int64_t)self.sequence.size() - 1);
375 libremidi::message tmp;
376 tmp.bytes = self.sequence[self.sequence_idx];
377 tmp.timestamp = bang.timestamp;
378 output_midi.messages.push_back(tmp);
379 self.sequence_idx = (self.sequence_idx + 1) % self.sequence.size();
380 }
381 }
382 }
383};
384#undef debug_vector_t
385}
Definition FactorOracle2MIDI.hpp:95
std::vector< State< T > > states_
Definition FactorOracle2MIDI.hpp:99
int FindBetter(int i, T alpha, std::vector< T > word)
Definition FactorOracle2MIDI.hpp:202
FactorOracle2MIDI()
Definition FactorOracle2MIDI.hpp:101
void FactorOracleStart(std::vector< T > word)
Definition FactorOracle2MIDI.hpp:273
std::vector< std::vector< int > > RevSuffix
Definition FactorOracle2MIDI.hpp:100
std::vector< T > FOGenerate(int &i, std::vector< T > v, float q)
Definition FactorOracle2MIDI.hpp:227
void AddLetter(int i, std::vector< T > word)
Definition FactorOracle2MIDI.hpp:109
Definition FactorOracle2MIDI.hpp:60
Definition FactorOracle2MIDI.hpp:69
int first_state_
Definition FactorOracle2MIDI.hpp:71
T symbol_
Definition FactorOracle2MIDI.hpp:73
int last_state_
Definition FactorOracle2MIDI.hpp:72
std::vector< SingleTransition< T > > transition_
denotes the number of the state
Definition FactorOracle2MIDI.hpp:87
int state_
denotes the number of the state
Definition FactorOracle2MIDI.hpp:86
Utilities for OSSIA data structures.
Definition DeviceInterface.hpp:33
Definition FactorOracle2MIDI.hpp:313