diff --git a/src/config-node.h b/src/config-node.h index f312a77..3605c41 100644 --- a/src/config-node.h +++ b/src/config-node.h @@ -1,8 +1,12 @@ #pragma once #include "datatypes.h" +#include "edge.h" +#include "midi-node.h" #include "node.h" #include "raymath.h" +#include +#include namespace VISEQ::GRAPH::NODES { @@ -38,28 +42,48 @@ namespace VISEQ::GRAPH::NODES { mode = state->node_mode; } + std::vector> getConnectedMidiNodes(){ + auto midi_conns = connections | RANGE_FILTER([](EDGES::SPTR_Edge c){ return c->start.lock()->getNodeType() == NodeType::MIDINODE || c->end.lock()->getNodeType() == NodeType::MIDINODE;}) | std::ranges::to>>(); + std::vector> midi_nodes; + for(auto e : midi_conns){ + if(e->start.lock()->getNodeType() == NodeType::MIDINODE) midi_nodes.push_back(std::dynamic_pointer_cast(e->start.lock())); + if(e->end.lock()->getNodeType() == NodeType::MIDINODE) midi_nodes.push_back(std::dynamic_pointer_cast(e->end.lock())); + } + return midi_nodes; + } + void interact(){ float wheel = GetMouseWheelMove(); + auto midi_nodes = getConnectedMidiNodes(); if(KEYS_DOWN.ctrl && !KEYS_DOWN.alt){ switch(state->node_mode){ case 0:{ midiNote.note += wheel; + for(auto mn : midi_nodes){ + mn.lock()->modMidiNote(wheel); + } break;} case 1:{ midiCC.value += wheel; + for(auto mn : midi_nodes){ + mn.lock()->modMidiCC(wheel); + } break;} case 2:{ midiPitchBend.value += wheel; + for(auto mn : midi_nodes){ + mn.lock()->modMidiPitchBend(wheel); + } break;} }; - if(midiNote.note < 0 ) midiNote.note = VISEQ::MIDI::Notes.size()-1; - if(midiNote.note >= (int)VISEQ::MIDI::Notes.size()) midiNote.note = 0; + if(midiNote.note < -127 ) midiNote.note = -127; + if(midiNote.note > 127 ) midiNote.note = 127; - if(midiCC.value < 0 ) midiCC.value = 127; - if(midiCC.value > 127 ) midiCC.value = 0; + if(midiCC.value < -127 ) midiCC.value = -127; + if(midiCC.value > 127 ) midiCC.value = 127; - if(midiPitchBend.value < 0 ) midiPitchBend.value = 0; + if(midiPitchBend.value < -16383 ) midiPitchBend.value = -16383; if(midiPitchBend.value > 16383 ) midiPitchBend.value = 16383; } else if(KEYS_DOWN.shift && !KEYS_DOWN.alt) { @@ -136,16 +160,16 @@ namespace VISEQ::GRAPH::NODES { } else { switch(mode){ case 0:{ - int offset = MeasureText(MIDI::Notes[(int)midiNote.note].c_str(), 12); - DrawText(MIDI::Notes[midiNote.note].c_str(), position.x-offset/2.0f, position.y-5, 12, WHITE ); + int offset = MeasureText(std::format("{:+}", midiNote.note).c_str(), 12); + DrawText(std::format("{:+}", midiNote.note).c_str(), position.x-offset/2.0f, position.y-5, 12, WHITE ); break;} case 1:{ - int offset = MeasureText(std::format("{}", midiCC.value).c_str(), 12); - DrawText(std::format("{}", midiCC.value).c_str(), position.x-offset/2.0f, position.y-5, 12, WHITE ); + int offset = MeasureText(std::format("{:+}", midiCC.value).c_str(), 12); + DrawText(std::format("{:+}", midiCC.value).c_str(), position.x-offset/2.0f, position.y-5, 12, WHITE ); break;} case 2:{ - int offset = MeasureText(std::format("{}", midiPitchBend.value).c_str(), 12); - DrawText(std::format("{}", midiPitchBend.value).c_str(), position.x-offset/2.0f, position.y-5, 12, WHITE ); + int offset = MeasureText(std::format("{:+}", midiPitchBend.value).c_str(), 12); + DrawText(std::format("{:+}", midiPitchBend.value).c_str(), position.x-offset/2.0f, position.y-5, 12, WHITE ); break;} } } diff --git a/src/graph-manager.h b/src/graph-manager.h index c088abb..11f335a 100644 --- a/src/graph-manager.h +++ b/src/graph-manager.h @@ -84,11 +84,14 @@ namespace VISEQ::GRAPH { } void addConnection(WPTR_Node from, WPTR_Node to){ + EdgeType et = EdgeType::MIDIEDGE; + if(from.lock()->getNodeType() == NodeType::CONFIGNODE || to.lock()->getNodeType() == NodeType::CONFIGNODE) et = EdgeType::CONFIGEDGE; if(from.lock() != to.lock()) { edges.emplace_back(std::make_shared()); + edges.back()->edgeType = et; edges.back()->start = from; edges.back()->end = to; - edges.back()->start_conn = from.lock()->connectors.back(); // TODO: crashes on start + edges.back()->start_conn = from.lock()->connectors.back(); edges.back()->end_conn = to.lock()->connectors.back(); from.lock()->connections.push_back(edges.back()); to.lock()->connections.push_back(edges.back()); @@ -212,7 +215,7 @@ namespace VISEQ::GRAPH { WPTR_Node next(WPTR_Node current, WPTR_Node last){ VEC_WPTR_Edge possible_connections = current.lock()->connections | RANGE_FILTER([current](WPTR_Edge c){ - return (c.lock()->start.lock() == current.lock() && c.lock()->pass_forward) || (c.lock()->end.lock() == current.lock() && c.lock()->pass_backward); + return (c.lock()->getEdgeType() == EdgeType::MIDIEDGE) && ((c.lock()->start.lock() == current.lock() && c.lock()->pass_forward) || (c.lock()->end.lock() == current.lock() && c.lock()->pass_backward)); }) | std::ranges::to(); if(possible_connections.empty()) return SPTR_Node(nullptr); diff --git a/src/midi-node.h b/src/midi-node.h index d238039..13728ac 100644 --- a/src/midi-node.h +++ b/src/midi-node.h @@ -1,5 +1,6 @@ #pragma once +#include "config-node.h" #include "datatypes.h" #include "node.h" #include "raymath.h" @@ -10,7 +11,23 @@ namespace VISEQ::GRAPH::NODES { class MidiNode : public Node{ - + private: + int midi_note_channel = 1; + int midi_note = 48; + int midi_velocity = 60; + int midi_gate = 10; // gate time in milliseconds + + int midi_cc_channel = 0; + int midi_cc = 0; + int midi_cc_value = 0; + + int midi_pc_channel = 0; + int midi_pc = 0; + int midi_pc_value = 0; + + int midi_pitch_bend_channel = 0; + int midi_pitch_bend = 8192; + public: struct NodeMidiOut{ @@ -42,22 +59,6 @@ namespace VISEQ::GRAPH::NODES { int mode = 0; - int midi_note_channel = 1; - int midi_note = 48; - int midi_velocity = 60; - int midi_gate = 10; // gate time in milliseconds - - int midi_cc_channel = 0; - int midi_cc = 0; - int midi_cc_value = 0; - - int midi_pc_channel = 0; - int midi_pc = 0; - int midi_pc_value = 0; - - int midi_pitch_bend_channel = 0; - int midi_pitch_bend = 8192; - float start = 0; float fade = 0; float time = 0; @@ -87,9 +88,46 @@ namespace VISEQ::GRAPH::NODES { return midi_gate; } + std::vector> getConnectedConfigNodes(){ + auto config_conns = connections | RANGE_FILTER([](EDGES::SPTR_Edge c){ return c->start.lock()->getNodeType() == NodeType::CONFIGNODE || c->end.lock()->getNodeType() == NodeType::CONFIGNODE;}) | std::ranges::to>>(); + std::vector> config_nodes; + for(auto e : config_conns){ + if(e->start.lock()->getNodeType() == NodeType::CONFIGNODE) config_nodes.push_back(std::dynamic_pointer_cast(e->start.lock())); + if(e->end.lock()->getNodeType() == NodeType::CONFIGNODE) config_nodes.push_back(std::dynamic_pointer_cast(e->end.lock())); + } + return config_nodes; + } + void update() override { Node::update(); mode = state->node_mode; + + } + + int getMidiNote(){ + int mod_notes = 0; + for(auto cn : getConnectedConfigNodes()){ + mod_notes += cn.lock()->midiNote.note; + } + return midi_note + mod_notes; + } + + void modMidiNote(int incr){ + midi_note += incr; + if(midi_note < 0 ) midi_note = VISEQ::MIDI::Notes.size()-1; + if(midi_note >= (int)VISEQ::MIDI::Notes.size()) midi_note = 0; + } + + void modMidiCC(int incr){ + midi_cc += incr; + if(midi_cc < 0 ) midi_cc = 127; + if(midi_cc > 127 ) midi_cc = 0; + } + + void modMidiPitchBend(int incr){ + midi_pitch_bend += incr; + if(midi_pitch_bend < 0 ) midi_pitch_bend = 0; + if(midi_pitch_bend > 16383 ) midi_pitch_bend = 16383; } void interact(){ @@ -98,24 +136,15 @@ namespace VISEQ::GRAPH::NODES { if(KEYS_DOWN.ctrl && !KEYS_DOWN.alt){ switch(state->node_mode){ case 0:{ - midi_note += wheel; + modMidiNote(wheel); break;} case 1:{ - midi_cc += wheel; + modMidiCC(wheel); break;} case 2:{ - midi_pitch_bend += wheel; + modMidiPitchBend(wheel); break;} }; - if(midi_note < 0 ) midi_note = VISEQ::MIDI::Notes.size()-1; - if(midi_note >= (int)VISEQ::MIDI::Notes.size()) midi_note = 0; - - if(midi_cc < 0 ) midi_cc = 127; - if(midi_cc > 127 ) midi_cc = 0; - - if(midi_pitch_bend < 0 ) midi_pitch_bend = 0; - if(midi_pitch_bend > 16383 ) midi_pitch_bend = 16383; - } else if(KEYS_DOWN.shift && !KEYS_DOWN.alt) { midi_velocity += wheel; if(midi_velocity < 0 ) midi_velocity = 127;