diff --git a/src/datatypes.h b/src/datatypes.h index fa25f54..340dc25 100644 --- a/src/datatypes.h +++ b/src/datatypes.h @@ -2,7 +2,7 @@ #include #include - +#include "libremidi/libremidi.hpp" enum Distribution {ROUNDROBIN, RANDOM}; @@ -125,20 +125,17 @@ Vec2D operator*(const Vec2D& left, T scalar){ return Vec2D(left.x * scalar, left.y * scalar); }; -/*template */ -/*bool contains(T X, T Y) {*/ -/* for (unsigned int i=0;i #include #include #include @@ -193,7 +194,9 @@ int main(){ Node* n = cm.next(s.next, s.last); if(n != s.next && n != nullptr) { - midi.note(s.next->midi_out, 1, 50, 50, 500); + for(auto &m : s.next->midi_outs){ + if(m.second.enabled) midi.note(m.second.i, s.next->midi_channel, s.next->midi_note, s.next->midi_velocity, s.next->midi_gate); + } s.last = s.next; s.next = n; } @@ -212,7 +215,6 @@ int main(){ GuiCheckBox((Rectangle){20, 80 + i*20.0f, 20, 20}, mo.port.port_name.c_str(), &mo.enabled); i++; } - if(GuiButton((Rectangle){20, 100 + (float)midi.midi_out_ports.size()*20, 240, 20}, "OPEN PORT")) midi.open_midi_out(app.gui_selected_midi_out); if(GuiButton((Rectangle){20, 60, 240, 20}, "ADD SIGNAL")){ signals.emplace_back(Signal(nodes.front().position.x + 1, nodes.front().position.y + 1, 5.0f, 2.0f)); // position + 1 or else it does not render. why? no idea! @@ -227,21 +229,34 @@ int main(){ int option = n.mode; GuiComboBox((Rectangle){ n.position.x + 20, n.position.y + 40, 220, 20 }, "Round Robin;Random", &option); n.mode = (Distribution)option; - - int i = 0; + + int y_midi = 60; + GuiLabel((Rectangle){n.position.x + 20, n.position.y + y_midi, 220, 20}, "MIDI OUT"); for(auto& mo : midi.midi_out_ports){ - GuiCheckBox((Rectangle){20, 80 + i*20.0f, 20, 20}, mo.port.port_name.c_str(), &mo.enabled); + if(!n.midi_outs.contains(mo.number) && mo.enabled){ + n.midi_outs[mo.number] = {mo.number, mo.port.port_name, false}; + } + } + int i = 0; + for(auto& mo : n.midi_outs){ + GuiCheckBox((Rectangle){n.position.x + 20, n.position.y + y_midi + 20 + i*20.0f, 20, 20}, mo.second.name.c_str(), &mo.second.enabled); i++; } - - std::string toggle_out_ports = ""; - for(auto& mo : midi.midi_outs){ - toggle_out_ports += midi.midi_out_ports[mo.first].port.port_name + "\n"; - } - toggle_out_ports = toggle_out_ports.substr(0, toggle_out_ports.size()-2); - GuiLabel((Rectangle){n.position.x + 20, n.position.y + 60, 220, 20}, "MIDI OUT"); - GuiToggleGroup((Rectangle){n.position.x + 20, n.position.y + 80, 220, 20}, toggle_out_ports.c_str(), &n.midi_out); + + int y_channel = y_midi + 20 + i*20; + if(GuiValueBox((Rectangle){n.position.x + 100, n.position.y + y_channel, 140, 20}, "CHANNEL", &n.midi_channel, 0, 15, n.gui_midi_channel_edit)) n.gui_midi_channel_edit = !n.gui_midi_channel_edit; + if(GuiValueBox((Rectangle){n.position.x + 100, n.position.y + y_channel + 20, 140, 20}, "NOTE", &n.midi_note, 0, 127, n.gui_midi_note_edit)) n.gui_midi_note_edit = !n.gui_midi_note_edit; + if(GuiValueBox((Rectangle){n.position.x + 100, n.position.y + y_channel + 40, 140, 20}, "VELOCITY", &n.midi_velocity, 0, 127, n.gui_midi_velocity_edit)) n.gui_midi_velocity_edit = !n.gui_midi_velocity_edit; + if(GuiValueBox((Rectangle){n.position.x + 100, n.position.y + y_channel + 60, 140, 20}, "GATE", &n.midi_gate, 0, 5000, n.gui_midi_gate_edit)) n.gui_midi_gate_edit = !n.gui_midi_gate_edit; + + float v = n.midi_channel; + GuiSlider((Rectangle){n.position.x + 100, n.position.y + y_channel + 80, 120, 20}, "CHANNEL", std::format("{}",(int)v).c_str(), &v, 0.0f, 15.0f); + n.midi_channel = (int)round(v); + + GuiToggleGroup((Rectangle){n.position.x + 20, n.position.y + y_channel + 100, 25, 20}, "1;2;3;4;5;6;7;8\n9;10;11;12;13;14;15;16", &n.midi_channel); + + GuiToggleGroup((Rectangle){n.position.x + 20, n.position.y + y_channel + 140, 25, 20}, "C-1;C#-1;D-1;D#-1;E-1;F-1;F#-1;G-1\nG#-1;A-1;A#-1;B-1;C0;C#0;D0;D#0\nE0;F0;F#0;G0;G#0;A0;A#0;B0\nC1;C#1;D1;D#1;E1;F1;F#1;G1\nG#1;A1;A#1;B1;C2;C#2;D2;D#2\nE2;F2;F#2;G2;G#2;A2;A#2;B2\nC3;C#3;D3;D#3;E3;F3;F#3;G3\nG#3;A3;A#3;B3;C4;C#4;D4;D#4\nE4;F4;F#4;G4;G#4;A4;A#4;B4\nC5;C#5;D5;D#5;E5;F5;F#5;G5\nG#5;A5;A#5;B5;C6;C#6;D6;D#6\nE6;F6;F#6;G6;G#6;A6;A#6;B6\nC7;C#7;D7;D#7;E7;F7;F#7;G7\nG#7;A7;A#7;B7;C8;C#8;D8;D#8\nE8;F8;F#8;G8;G#8;A8;A#8;B8\nC9;C#9;D9;D#9;E9;F9;F#9;G9\nG#9;A9;A#9;B9;C10", &n.midi_note); } } diff --git a/src/midi.h b/src/midi.h index ba9d2b5..bee0566 100644 --- a/src/midi.h +++ b/src/midi.h @@ -5,11 +5,9 @@ #include "libremidi/observer_configuration.hpp" #include "raylib.h" -#include #include #include -#include - +#include "datatypes.h" struct NoteTimer{ int midi_out; @@ -21,17 +19,6 @@ struct NoteTimer{ bool erase = false; }; -struct MidiOutPort{ - libremidi::output_port port; - int number; - bool enabled; -}; - -struct MidiOut{ - libremidi::midi_out out; - -}; - class Midi { public: @@ -63,8 +50,10 @@ class Midi { void note(int midi_out, int channel, int note, int velocity, int gate){ if(!midi_outs.empty()){ - midi_outs[midi_out]->send_message(libremidi::channel_events::note_on(channel, note, velocity)); - notes.emplace_back(midi_out, channel, note, velocity, GetTime(), gate); + if(midi_outs[midi_out]->is_port_open()){ + midi_outs[midi_out]->send_message(libremidi::channel_events::note_on(channel, note, velocity)); + notes.emplace_back(midi_out, channel, note, velocity, GetTime(), gate); + } } } diff --git a/src/node.h b/src/node.h index 572b437..8e42297 100644 --- a/src/node.h +++ b/src/node.h @@ -1,13 +1,19 @@ #pragma once +#include #include -#include #include "datatypes.h" #include "moveable.h" #define R 14.0f +struct NodeMidiOut{ + int i; + std::string name; + bool enabled; +}; + class Node : public Movable{ public: @@ -24,21 +30,21 @@ class Node : public Movable{ int midi_out = -1; - std::vector midi_outs; + std::map midi_outs; + bool gui_midi_channel_edit = false; + bool gui_midi_note_edit = false; + bool gui_midi_velocity_edit = false; + bool gui_midi_gate_edit = false; + + int midi_channel = 0; int midi_note = 0; - int midi_cc = 0; + int midi_velocity = 0; int midi_gate = 0; - Distribution mode = Distribution::ROUNDROBIN; - - void note() { - - } + int midi_cc = 0; - void cc() { - - } + Distribution mode = Distribution::ROUNDROBIN; void draw(Vec2D *mouse) { if(!hover_move) DrawCircle(position.x, position.y, radius, (Color){180, 210, 115, 255});