#include "signal-manager.h" #include "datatypes.h" #include "midi-node.h" #include "node.h" #include "signal.h" #include "midi.h" #include #include #include void VISEQ::SIGNAL::SignalManager::pause(){ play = false; } void VISEQ::SIGNAL::SignalManager::stop(){ play = false; reset(); } void VISEQ::SIGNAL::SignalManager::start(){ play = true; } void VISEQ::SIGNAL::SignalManager::reset(){ for(auto &s : signals){ s->position = s->start.lock()->position + Vec2Df{0.1, 0.1}; s->next = s->start; s->last = s->start; } gm->reset(); } void VISEQ::SIGNAL::SignalManager::startSignalThread(){ std::thread t1(&SignalManager::updateSignals, this); t1.detach(); } void VISEQ::SIGNAL::SignalManager::stopSignalThread(){ loop = false; } void VISEQ::SIGNAL::SignalManager::addSignalAtNode(WPTR_Node node){ Color c = {(unsigned char)(20 + (rand() % 200)), 100, (unsigned char)(20 + (int)(rand() % 200)), 200}; signals.emplace_back(std::make_shared(node.lock()->position + Vec2Df{0.5f, 0.5f}, 8.0f, 480, c)); // position + 1 or else it does not render. why? no idea! signals.back()->next = node; signals.back()->last = node; signals.back()->start = node; } void VISEQ::SIGNAL::SignalManager::rerouteSignal(VEC_SPTR_Node nodes, VEC_WPTR_Node adjacent_nodes){ auto reroute_signals = signals | RANGE_FILTER([nodes](SIGNAL::SPTR_Signal s){return std::ranges::contains(nodes, s->next.lock());}); for(auto s : reroute_signals){ float dist = 10000000; SPTR_Node next_node; for(auto n : adjacent_nodes){ if(n.lock()->position.dist(s->position) < dist) { dist = n.lock()->position.dist(s->position); next_node = n.lock(); } } s->next = next_node; s->last = next_node; } } void VISEQ::SIGNAL::SignalManager::rebaseSignal(VEC_SPTR_Node nodes){ auto rebase_signals = signals | RANGE_FILTER([nodes](SIGNAL::SPTR_Signal s){return std::ranges::contains(nodes, s->start.lock());}); for(auto s : rebase_signals){ s->start = s->next; } } void VISEQ::SIGNAL::SignalManager::removeSignal(std::shared_ptr s){ erase_signals.push_back(s); } void VISEQ::SIGNAL::SignalManager::updateSignals(){ auto last = std::chrono::high_resolution_clock::now(); while(loop){ std::chrono::duration diff = std::chrono::high_resolution_clock::now() - last; if((int)diff.count() >= 250){ mutex->lock(); if(play){ for(auto& s : signals){ s->direction = (s->next.lock()->position - s->position).norm(); s->update(diff.count()); if(s->position.dist(s->next.lock()->position) < 0.6f) { WPTR_Node next_node = gm->next(s->next, s->last); s->next.lock()->trigger(); if(next_node.lock() != s->next.lock() && !next_node.expired() && s->next.lock()->getNodeType() == NodeType::MIDINODE) { auto midinode = std::dynamic_pointer_cast(s->next.lock()); for(auto &m : midinode->midi_outs){ if(m.second.enabled) { if(midinode->send_note) midi.note(m.second.i, midinode->getNotes().channel, (int)Clamp(midinode->getNotes().note + s->midi_note_offset, 0, 127), midinode->getNotes().velocity, midinode->getNotes().gate); if(midinode->send_cc) midi.cc(m.second.i, midinode->getCC().channel, midinode->getCC().control, (int)Clamp(midinode->getCC().value + s->midi_cc_offset, 0, 127)); if(midinode->send_pitch_bend) midi.pitch_bend(m.second.i, midinode->getPitchBend().channel, midinode->getPitchBend().value); } } s->last = s->next; s->next = next_node; } } } } midi.update(); mutex->unlock(); last = std::chrono::high_resolution_clock::now(); } } } void VISEQ::SIGNAL::SignalManager::drawSignals(Vec2Df mouse_pos, Camera2D camera){ mutex->lock(); if(!erase_signals.empty()){ for(auto s: erase_signals){ std::erase(signals, s); } erase_signals.clear(); } for(auto s : signals){ s->draw(mouse_pos, camera); } mutex->unlock(); }