Files
viseq/src/signal-manager.cpp
T

142 lines
5.0 KiB
C++
Raw Normal View History

2026-01-05 02:56:30 +01:00
#include "signal-manager.h"
#include "datatypes.h"
#include "midi-node.h"
#include "node.h"
#include "signal.h"
#include "midi.h"
#include <chrono>
#include <memory>
#include <thread>
2026-01-12 00:16:36 +01:00
namespace VISEQ::SIGNAL {
2026-01-05 02:56:30 +01:00
2026-01-12 00:16:36 +01:00
void SignalManager::pause(){
play = false;
}
2026-01-05 02:56:30 +01:00
2026-01-12 00:16:36 +01:00
void SignalManager::stop(){
play = false;
reset();
}
2026-01-05 02:56:30 +01:00
2026-01-12 00:16:36 +01:00
void SignalManager::start(){
play = true;
}
2026-01-05 02:56:30 +01:00
2026-01-12 00:16:36 +01:00
void 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();
2026-01-05 02:56:30 +01:00
}
2026-01-12 00:16:36 +01:00
void SignalManager::startSignalThread(){
std::thread t1(&SignalManager::updateSignals, this);
t1.detach();
}
2026-01-05 02:56:30 +01:00
2026-01-12 00:16:36 +01:00
void SignalManager::stopSignalThread(){
loop = false;
}
2026-01-05 02:56:30 +01:00
2026-01-12 00:16:36 +01:00
void 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<Signal>(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;
}
2026-01-05 02:56:30 +01:00
2026-01-12 00:16:36 +01:00
void 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());});
2026-01-05 02:56:30 +01:00
2026-01-12 00:16:36 +01:00
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();
}
2026-01-05 02:56:30 +01:00
}
2026-01-12 00:16:36 +01:00
s->next = next_node;
s->last = next_node;
2026-01-05 02:56:30 +01:00
}
2026-01-12 00:16:36 +01:00
}
2026-01-05 02:56:30 +01:00
2026-01-12 00:16:36 +01:00
void 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;
}
2026-01-05 02:56:30 +01:00
}
2026-01-12 00:16:36 +01:00
void SignalManager::removeSignal(std::shared_ptr<Signal> s){
erase_signals.push_back(s);
}
2026-01-05 02:56:30 +01:00
2026-01-12 00:16:36 +01:00
void SignalManager::updateSignals(){
auto last = std::chrono::high_resolution_clock::now();
while(loop){
std::chrono::duration<double, std::micro> 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<MidiNode>(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);
}
2026-01-05 02:56:30 +01:00
}
2026-01-12 00:16:36 +01:00
s->last = s->next;
s->next = next_node;
2026-01-05 02:56:30 +01:00
}
}
}
}
2026-01-12 00:16:36 +01:00
midi.update();
mutex->unlock();
last = std::chrono::high_resolution_clock::now();
2026-01-05 02:56:30 +01:00
}
}
}
2026-01-12 00:16:36 +01:00
void 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);
2026-01-05 02:56:30 +01:00
}
2026-01-12 00:16:36 +01:00
mutex->unlock();
2026-01-05 02:56:30 +01:00
}
2026-01-12 00:16:36 +01:00
void to_json(json& j, const std::shared_ptr<SignalManager>& G){
j = *G;
}
void from_json(const json& j, std::shared_ptr<SignalManager>& G){
G.reset(new SignalManager(j.get<SignalManager>()));
2026-01-05 02:56:30 +01:00
}
}