97 int phi, k, fo_iter, current_state = 1;
98 std::vector<T> input_values;
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);
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_;
126 int flag = 0, iter = 0;
133 while(k > -1 && flag == 0)
135 while(iter < this->states_[k].transition_.size())
137 if(this->states_[k].transition_[iter].symbol_ == alpha)
145 this->AddTransition(k, state_m_plus_one, alpha);
147 k = this->states_[k].suffix_transition_;
153 this->states_[state_m_plus_one].suffix_transition_ = 0;
154 this->states_[state_m_plus_one].lrs_ = 0;
159 if(this->states_[k].transition_[iter].symbol_ == alpha)
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;
165 while(iter < this->states_[k].transition_.size() && flag == 0)
167 if(this->states_[k].transition_[iter].symbol_ == alpha)
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;
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);
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;
185 RevSuffix[this->states_[state_m_plus_one].suffix_transition_].push_back(state_m_plus_one);
188 int LengthCommonSuffix(
int phi_one,
int phi_two)
190 if(phi_two == this->states_[phi_one].suffix_transition_)
191 return this->states_[phi_one].lrs_;
194 while(this->states_[phi_one].suffix_transition_ != this->states_[phi_two].suffix_transition_)
195 phi_two = this->states_[phi_two].suffix_transition_;
197 if(this->states_[phi_one].lrs_ <= this->states_[phi_two].lrs_)
198 return this->states_[phi_one].lrs_;
200 return this->states_[phi_two].lrs_;
212 int len_t = this->RevSuffix[this->states_[i].suffix_transition_].size();
213 int statei = this->states_[i].suffix_transition_;
216 sort(this->RevSuffix[statei].begin(), this->RevSuffix[statei].end());
217 for(
int j = 0; j < len_t; j++)
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)
221 int output_midi = RevSuffix[this->states_[i].suffix_transition_][j];
236 std::random_device rd;
237 std::mt19937 gen(rd());
238 std::uniform_real_distribution<> dis(0.0, 1.0);
240 if(this->states_.size() == 2 || this->states_.size() == 1)
242 v.push_back(this->states_[0].transition_[0].symbol_);
249 int len = this->states_.size();
252 T w = this->states_[i].transition_[0].symbol_;
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_;
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);
286 void AddState(
int first_state) { this->states_[first_state].state_ = first_state; };
287 void AddTransition(
int first_state,
int last_state, T symbol)
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);
295 std::vector<T> CallGenerate(
int len,
float q)
298 std::vector<T> oracle = {};
300 for(
int x = 0; x < len; x++)
302 oracle = this->FOGenerate(fo_iter, oracle, q);
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 .")
320 halp_meta(uuid,
"C87B5326-56C2-4489-8E08-AA9E1EF27359");
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"};
339 debug_vector_t<libremidi::midi_bytes> sequence;
340 debug_vector_t<libremidi::midi_bytes> midi_bytes;
341 std::size_t sequence_idx{};
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)
349 for(
auto val : input_midi.messages)
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;
358 if(!regen.get_data().empty())
360 if(!self.oracle.input_values.empty())
362 std::vector<int> temp_vec = 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;
370 if(!self.sequence.empty() && !self.oracle.input_values.empty())
372 for(
auto& bang : bangs.get_data())
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();