GEO mode for signals takes direction of next connection into account
This commit is contained in:
+37
-20
@@ -3,6 +3,7 @@
|
||||
#include "connection.h"
|
||||
#include "node-manager.h"
|
||||
#include "raylib.h"
|
||||
#include "raymath.h"
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
@@ -23,41 +24,57 @@ class ConnectionManager{
|
||||
}
|
||||
|
||||
int next(int current, int last){
|
||||
std::vector<Connection*> paths;
|
||||
std::vector<int> node_ids;
|
||||
std::vector<Connection*> possible_connections;
|
||||
std::vector<int> next_node_ids;
|
||||
|
||||
for(auto& p : connections){
|
||||
if((p.v1 == current && p.v1_v2) || (p.v2 == current && p.v2_v1)) {
|
||||
p.active = false;
|
||||
paths.push_back(&p);
|
||||
node_ids.push_back( p.v1 == current ? p.v2 : p.v1 );
|
||||
for(auto& c : connections){
|
||||
if((c.v1 == current && c.v1_v2) || (c.v2 == current && c.v2_v1)) {
|
||||
c.active = false;
|
||||
possible_connections.push_back(&c);
|
||||
next_node_ids.push_back( c.v1 == current ? c.v2 : c.v1 );
|
||||
}
|
||||
}
|
||||
|
||||
if(paths.size() == 2) {
|
||||
int next = node_ids[0] == last ? node_ids[1] : node_ids[0];
|
||||
if(paths[0]->v1 == next || paths[0]->v2 == next) paths[0]->active = true;
|
||||
if(paths[1]->v1 == next || paths[1]->v2 == next) paths[1]->active = true;
|
||||
return next;
|
||||
}
|
||||
/*if(possible_connections.size() == 2) {*/
|
||||
/* int next = next_node_ids[0] == last ? next_node_ids[1] : next_node_ids[0];*/
|
||||
/* if(possible_connections[0]->v1 == next || possible_connections[0]->v2 == next) possible_connections[0]->active = true;*/
|
||||
/* if(possible_connections[1]->v1 == next || possible_connections[1]->v2 == next) possible_connections[1]->active = true;*/
|
||||
/* return next;*/
|
||||
/*}*/
|
||||
|
||||
if(paths.empty()) return -1;
|
||||
if(possible_connections.empty()) return -1;
|
||||
|
||||
int return_path = 0;
|
||||
float angle = -1;
|
||||
if(nm->nodes.at(current).distributionMode == Distribution::GEOMETRIC){
|
||||
Vec2D<float> coming_from = (nm->nodes.at(current).position - nm->nodes.at(last).position).norm();
|
||||
int i = 0;
|
||||
for(auto n : possible_connections){
|
||||
int next_position = n->v1 == current ? n->v2 : n->v1;
|
||||
float angle_v1_v2 = coming_from.norm().dot((nm->nodes.at(next_position).position - nm->nodes.at(current).position).norm());
|
||||
if(angle_v1_v2 > angle) {
|
||||
return_path = i;
|
||||
angle = angle_v1_v2;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
if(nm->nodes.at(current).mode == Distribution::ROUNDROBIN){
|
||||
if(nm->nodes.at(current).distributionMode == Distribution::ROUNDROBIN){
|
||||
if(counter.find(current) == counter.end()) {
|
||||
counter[current] = 0;
|
||||
} else {
|
||||
counter[current] = (counter[current] + 1) % paths.size();
|
||||
counter[current] = (counter[current] + 1) % possible_connections.size();
|
||||
return_path = counter[current];
|
||||
}
|
||||
}
|
||||
if(nm->nodes.at(current).mode == Distribution::RANDOM){
|
||||
return_path = rand() % paths.size();
|
||||
|
||||
if(nm->nodes.at(current).distributionMode == Distribution::RANDOM){
|
||||
return_path = rand() % possible_connections.size();
|
||||
}
|
||||
paths.at(return_path)->active = true;
|
||||
return paths.at(return_path)->v1 == current ? paths.at(return_path)->v2 : paths.at(return_path)->v1;
|
||||
|
||||
possible_connections.at(return_path)->active = true;
|
||||
return possible_connections.at(return_path)->v1 == current ? possible_connections.at(return_path)->v2 : possible_connections.at(return_path)->v1;
|
||||
}
|
||||
|
||||
void addConnection(int from, int to){
|
||||
|
||||
+2
-2
@@ -60,8 +60,8 @@ class Connection{
|
||||
|
||||
// Dynamic opacity by distance to mouse
|
||||
unsigned char opacity = 150.0f - Clamp(middle_handle.dist(mouse_pos), 0.0f, 150.0f);
|
||||
unsigned char opacity_from = 250.0f - Clamp(from_to_handle.dist(mouse_pos), 0.0f, 120.0f);
|
||||
unsigned char opacity_to = 250.0f - Clamp(to_from_handle.dist(mouse_pos), 0.0f, 120.0f);
|
||||
unsigned char opacity_from = 250.0f - Clamp(from_to_handle.dist(mouse_pos), 0.0f, 220.0f);
|
||||
unsigned char opacity_to = 250.0f - Clamp(to_from_handle.dist(mouse_pos), 0.0f, 220.0f);
|
||||
|
||||
// On/Off switches on both sides
|
||||
if(ViButton(mouse_pos, from_to_handle.x, from_to_handle.y, 8.0f, v1_v2 ? (Color){120, 210, 115, opacity_from} : (Color){232, 50, 32, opacity_from} )) v1_v2 = !v1_v2;
|
||||
|
||||
+6
-1
@@ -25,7 +25,7 @@
|
||||
#include "libremidi/libremidi.hpp"
|
||||
#include "raylib.h"
|
||||
|
||||
enum Distribution {ROUNDROBIN, RANDOM};
|
||||
enum Distribution {GEOMETRIC, ROUNDROBIN, RANDOM};
|
||||
|
||||
// 2D Vectors
|
||||
|
||||
@@ -58,6 +58,10 @@ class Vec2D{
|
||||
return (x*v.x) + (y*v.y);
|
||||
};
|
||||
|
||||
T dot(Vec2D v){
|
||||
return (x*v.x) + (y*v.y);
|
||||
};
|
||||
|
||||
operator Vector2() const {
|
||||
return (Vector2){x,y};
|
||||
}
|
||||
@@ -152,6 +156,7 @@ Vec2D<T> operator*(const Vec2D<T>& left, T scalar){
|
||||
|
||||
// App Settings
|
||||
struct AppSettings{
|
||||
int mode = 0;
|
||||
int width;
|
||||
int height;
|
||||
float grid;
|
||||
|
||||
+43
-6
@@ -63,9 +63,9 @@ int main(){
|
||||
|
||||
app.settings.fps = 60.0f;
|
||||
app.settings.bpm = 120.0f;
|
||||
app.settings.grid = 120.0f; // 120px for a 16th note
|
||||
app.settings.grid = 60.0f; // 120px for a 16th note
|
||||
|
||||
app.settings.speed = (app.settings.grid * 8.0f) * (app.settings.bpm / 120.f);
|
||||
app.settings.speed = (app.settings.grid * 16.0f) * (app.settings.bpm / 120.f);
|
||||
|
||||
app.settings.width = monitor_width - 300;
|
||||
app.settings.height = monitor_height - 300;
|
||||
@@ -78,10 +78,10 @@ int main(){
|
||||
camera.zoom = 1.0f;
|
||||
|
||||
for(int i = 0; i < 4; ++i){
|
||||
app.nm.addNode((float)i * app.settings.grid + 10 * app.settings.grid, 5 * app.settings.grid);
|
||||
app.nm.addNode((float)i * app.settings.grid*4 + 10 * app.settings.grid, 5 * app.settings.grid*4);
|
||||
}
|
||||
for(int i = 3; i >= 0; --i){
|
||||
app.nm.addNode((float)i * app.settings.grid + 10 * app.settings.grid, 6 * app.settings.grid);
|
||||
app.nm.addNode((float)i * app.settings.grid*4 + 10 * app.settings.grid, 6 * app.settings.grid*4);
|
||||
}
|
||||
|
||||
for(int i = 0; i < 8; ++i){
|
||||
@@ -104,7 +104,7 @@ int main(){
|
||||
ClearBackground((Color){46,46,46});
|
||||
BeginMode2D(camera);
|
||||
|
||||
app.settings.speed = (app.settings.grid * 8.0f) * (app.settings.bpm / 120.f);
|
||||
app.settings.speed = (app.settings.grid * 16.0f) * (app.settings.bpm / 120.f);
|
||||
|
||||
Vector2 mp = GetScreenToWorld2D(GetMousePosition(), camera);
|
||||
Vec2D<float> mouse_pos = {(float)mp.x, (float)mp.y};
|
||||
@@ -146,6 +146,11 @@ int main(){
|
||||
|
||||
if(!copied_nodes.empty() && IsKeyDown(KEY_LEFT_CONTROL) && IsKeyPressed(KEY_V)) istate = InteractionState::PASTE_SELECTED_NODES;
|
||||
|
||||
if(IsKeyPressed(KEY_TAB)) {
|
||||
app.settings.mode = (app.settings.mode + 1) % 3;
|
||||
app.nm.setNodeMode(app.settings.mode);
|
||||
}
|
||||
|
||||
switch(istate){
|
||||
case InteractionState::HOVER_CANVAS:
|
||||
{
|
||||
@@ -214,7 +219,7 @@ int main(){
|
||||
if(IsKeyDown(KEY_LEFT_CONTROL)) {
|
||||
dragging_nodes.front().position = (Vec2D<float>){round((mouse_pos.x+dragging_nodes.front().drag_offset.x)/app.settings.grid)*app.settings.grid, round((mouse_pos.y+dragging_nodes.front().drag_offset.y)/app.settings.grid)*app.settings.grid};
|
||||
} else if(IsKeyDown(KEY_LEFT_SHIFT)){
|
||||
float steps = round(dragging_nodes.front().neighbor->position.dist(mouse_pos) / 60.0f) * 60.0f;
|
||||
float steps = round(dragging_nodes.front().neighbor->position.dist(mouse_pos) / app.settings.grid) * app.settings.grid;
|
||||
Vec2D<float> polar = dragging_nodes.front().neighbor->position - (dragging_nodes.front().neighbor->position - (mouse_pos + dragging_nodes.front().drag_offset)).norm() * steps;
|
||||
dragging_nodes.front().position = polar;
|
||||
} else {
|
||||
@@ -311,17 +316,49 @@ int main(){
|
||||
float wheel = GetMouseWheelMove();
|
||||
if(wheel != 0){
|
||||
if(!hovering_nodes.empty() && IsKeyDown(KEY_LEFT_CONTROL) && !IsKeyDown(KEY_LEFT_ALT)){
|
||||
switch(app.settings.mode){
|
||||
case 0:{
|
||||
hovering_nodes.front().midi_note += wheel;
|
||||
break;}
|
||||
case 1:{
|
||||
hovering_nodes.front().midi_cc += wheel;
|
||||
break;}
|
||||
case 2:{
|
||||
hovering_nodes.front().midi_pitch_bend += wheel;
|
||||
break;}
|
||||
};
|
||||
if(hovering_nodes.front().midi_note < 0 ) hovering_nodes.front().midi_note = app.sm.midi.midiNotes.size()-1;
|
||||
if(hovering_nodes.front().midi_note >= app.sm.midi.midiNotes.size() ) hovering_nodes.front().midi_note = 0;
|
||||
|
||||
if(hovering_nodes.front().midi_cc < 0 ) hovering_nodes.front().midi_cc = 127;
|
||||
if(hovering_nodes.front().midi_cc > 127 ) hovering_nodes.front().midi_cc = 0;
|
||||
|
||||
if(hovering_nodes.front().midi_pitch_bend < 0 ) hovering_nodes.front().midi_pitch_bend = 0;
|
||||
if(hovering_nodes.front().midi_pitch_bend > 16383 ) hovering_nodes.front().midi_pitch_bend = 16383;
|
||||
|
||||
} else if(!hovering_nodes.empty() && IsKeyDown(KEY_LEFT_SHIFT) && !IsKeyDown(KEY_LEFT_ALT)) {
|
||||
hovering_nodes.front().midi_velocity += wheel;
|
||||
if(hovering_nodes.front().midi_velocity < 0 ) hovering_nodes.front().midi_velocity = 127;
|
||||
if(hovering_nodes.front().midi_velocity > 127 ) hovering_nodes.front().midi_velocity = 0;
|
||||
} else if(!hovering_nodes.empty() && IsKeyDown(KEY_LEFT_ALT)) {
|
||||
switch(app.settings.mode){
|
||||
case 0:{
|
||||
float incr = (float)wheel * (IsKeyDown(KEY_LEFT_SHIFT) ? 100.0f : IsKeyDown(KEY_LEFT_CONTROL) ? 1000.0f : 10.0f);
|
||||
hovering_nodes.front().midi_gate += incr;
|
||||
if(hovering_nodes.front().midi_gate < 0 ) hovering_nodes.front().midi_gate = 0;
|
||||
break;}
|
||||
case 1:{
|
||||
hovering_nodes.front().midi_cc_value += wheel;
|
||||
if(hovering_nodes.front().midi_cc_value < 0 ) hovering_nodes.front().midi_cc_value = 0;
|
||||
if(hovering_nodes.front().midi_cc_value > 127 ) hovering_nodes.front().midi_cc_value = 127;
|
||||
break;}
|
||||
case 2:{
|
||||
float incr = (float)wheel * (IsKeyDown(KEY_LEFT_SHIFT) ? 100.0f : IsKeyDown(KEY_LEFT_CONTROL) ? 1000.0f : 10.0f);
|
||||
hovering_nodes.front().midi_pitch_bend += incr;
|
||||
if(hovering_nodes.front().midi_pitch_bend < 0 ) hovering_nodes.front().midi_pitch_bend = 0;
|
||||
if(hovering_nodes.front().midi_pitch_bend > 16383 ) hovering_nodes.front().midi_pitch_bend = 16383;
|
||||
break;}
|
||||
};
|
||||
} else {
|
||||
Vector2 mouseWorldPos = GetScreenToWorld2D(GetMousePosition(), camera);
|
||||
camera.offset = GetMousePosition();
|
||||
|
||||
+17
@@ -8,6 +8,7 @@
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <numbers>
|
||||
#include "datatypes.h"
|
||||
|
||||
struct NoteTimer{
|
||||
@@ -91,6 +92,22 @@ class Midi {
|
||||
}
|
||||
}
|
||||
|
||||
void cc(int midi_out, int channel, int cc, int value){
|
||||
if(midi_outs.contains(midi_out)){
|
||||
if(midi_outs[midi_out]->is_port_open()){
|
||||
midi_outs[midi_out]->send_message(libremidi::channel_events::control_change(channel, cc, value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pitch_bend(int midi_out, int channel, int pitch_value){
|
||||
if(midi_outs.contains(midi_out)){
|
||||
if(midi_outs[midi_out]->is_port_open()){
|
||||
midi_outs[midi_out]->send_message(libremidi::channel_events::pitch_bend(channel, pitch_value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void update(){
|
||||
float time = GetTime();
|
||||
for(auto &n : notes){
|
||||
|
||||
@@ -50,6 +50,12 @@ class NodeManager{
|
||||
return iterator - 1;
|
||||
}
|
||||
|
||||
void setNodeMode(int mode){
|
||||
for(auto &n : nodes | std::ranges::views::values){
|
||||
n.mode = mode;
|
||||
}
|
||||
}
|
||||
|
||||
int addNode(float x, float y){
|
||||
return addNode(Vec2D<float>(x,y));
|
||||
}
|
||||
|
||||
+68
-9
@@ -22,7 +22,6 @@ class Node : public Movable{
|
||||
Node(int id, float x, float y, float r) : Movable(Vec2D<float>(x, y), 0.0f), radius(r), id(id) {}
|
||||
Node(int id, Vec2D<float> p, float r) : Movable(p, 0.0f), radius(r), id(id) {}
|
||||
|
||||
|
||||
Node *neighbor = nullptr;
|
||||
|
||||
float radius;
|
||||
@@ -42,6 +41,11 @@ class Node : public Movable{
|
||||
bool copied = false;
|
||||
bool triggered = false;
|
||||
|
||||
bool send_note = true;
|
||||
bool send_cc = false;
|
||||
bool send_pc = false;
|
||||
bool send_pitch_bend = false;
|
||||
|
||||
int midi_out = -1;
|
||||
|
||||
Vec2D<float> drag_offset;
|
||||
@@ -53,18 +57,30 @@ class Node : public Movable{
|
||||
bool gui_midi_velocity_edit = false;
|
||||
bool gui_midi_gate_edit = false;
|
||||
|
||||
int midi_channel = 1;
|
||||
int mode = 0;
|
||||
|
||||
int midi_note_channel = 1;
|
||||
int midi_note = 48;
|
||||
int midi_velocity = 60;
|
||||
int midi_gate = 100;
|
||||
int midi_gate = 25; // 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;
|
||||
float last = 0;
|
||||
|
||||
Distribution mode = Distribution::ROUNDROBIN;
|
||||
Distribution distributionMode = Distribution::GEOMETRIC;
|
||||
|
||||
void setMidiPort(int midi_port, bool state){
|
||||
midi_outs[midi_port].enabled = state;
|
||||
@@ -89,22 +105,65 @@ class Node : public Movable{
|
||||
DrawRing(position, radius, radius+4, 0, 360, 24, (Color){60, 60, 60, 255});
|
||||
DrawRing(position, radius, radius+4, 0.0f - 90.0f, (360.0f/127.0f) * midi_velocity - 90.0f, 24, (Color){158, 134, 200, 255});
|
||||
DrawCircleLinesV(position, radius + 4, (Color){100, 100, 100, 255});
|
||||
if(mode == Distribution::RANDOM) DrawCircle(position.x, position.y, radius/2.0f, VS_COLOR_PINK);
|
||||
|
||||
float midi_gate_map = round((255.f / midi_gate) * fade);
|
||||
Color gate_color = ColorAlphaBlend(VS_COLOR_RED, (Color){180, 210, 115, (unsigned char)Clamp(255 - midi_gate_map, 0, 255)}, WHITE);
|
||||
|
||||
Color gate_color = VS_COLOR_GREEN;
|
||||
|
||||
switch(mode){
|
||||
case 0:{
|
||||
gate_color = ColorAlphaBlend(VS_COLOR_RED, (Color){180, 210, 115, (unsigned char)Clamp(255 - midi_gate_map, 0, 255)}, WHITE);
|
||||
break;}
|
||||
case 1:{
|
||||
gate_color = ColorAlphaBlend(VS_COLOR_RED, (Color){229, 181, 103, (unsigned char)Clamp(255 - midi_gate_map, 0, 255)}, WHITE);
|
||||
break;}
|
||||
case 2:{
|
||||
gate_color = ColorAlphaBlend(VS_COLOR_RED, (Color){232, 125, 62, (unsigned char)Clamp(255 - midi_gate_map, 0, 255)}, WHITE);
|
||||
break;}
|
||||
}
|
||||
if(!dragging && !selected && !in_rect && !hovering) DrawCircle(position.x, position.y, radius, gate_color);
|
||||
if(selected || dragging || in_rect || hovering) DrawCircle(position.x, position.y, radius, (Color){108, 153, 187, 255});
|
||||
|
||||
if(distributionMode == Distribution::RANDOM) DrawCircle(position.x, position.y, radius/2.0f, VS_COLOR_PINK);
|
||||
if(distributionMode == Distribution::ROUNDROBIN) DrawCircle(position.x, position.y, radius/2.0f, VS_COLOR_YELLOW);
|
||||
|
||||
if(selected) DrawCircleLinesV(position, radius+8, (Color){158, 255, 210, 255});
|
||||
|
||||
if(IsKeyDown(KEY_LEFT_ALT)){
|
||||
int offset_gate = MeasureText(std::format("{:.2f}", (float)midi_gate/1000.0f).c_str(), 12);
|
||||
DrawText(std::format("{:.2f}",(float)midi_gate/1000.0f).c_str(), position.x-offset_gate/2.0f, position.y-5, 12, WHITE );
|
||||
float value = 0;
|
||||
int offset_gate = 0;
|
||||
switch(mode){
|
||||
case 0:
|
||||
value = (float)midi_gate/1000.0f;
|
||||
offset_gate = MeasureText(std::format("{:.2f}", value).c_str(), 12);
|
||||
DrawText(std::format("{:.2f}",value).c_str(), position.x-offset_gate/2.0f, position.y-5, 12, WHITE );
|
||||
break;
|
||||
case 1:
|
||||
value = (float)midi_cc_value;
|
||||
offset_gate = MeasureText(std::format("{}", value).c_str(), 12);
|
||||
DrawText(std::format("{}",value).c_str(), position.x-offset_gate/2.0f, position.y-5, 12, WHITE );
|
||||
break;
|
||||
case 2:
|
||||
value = (float)midi_pitch_bend;
|
||||
offset_gate = MeasureText(std::format("{}", value).c_str(), 12);
|
||||
DrawText(std::format("{}",value).c_str(), position.x-offset_gate/2.0f, position.y-5, 12, WHITE );
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
int offset = MeasureText(MIDI::Notes[midi_note].c_str(), 12);
|
||||
switch(mode){
|
||||
case 0:{
|
||||
int offset = MeasureText(MIDI::Notes[(int)midi_note].c_str(), 12);
|
||||
DrawText(MIDI::Notes[midi_note].c_str(), position.x-offset/2.0f, position.y-5, 12, WHITE );
|
||||
break;}
|
||||
case 1:{
|
||||
int offset = MeasureText(std::format("{}", midi_cc).c_str(), 12);
|
||||
DrawText(std::format("{}", midi_cc).c_str(), position.x-offset/2.0f, position.y-5, 12, WHITE );
|
||||
break;}
|
||||
case 2:{
|
||||
int offset = MeasureText(std::format("{}", midi_pitch_bend).c_str(), 12);
|
||||
DrawText(std::format("{}", midi_pitch_bend).c_str(), position.x-offset/2.0f, position.y-5, 12, WHITE );
|
||||
break;}
|
||||
}
|
||||
}
|
||||
|
||||
Vec2D<float> connector = position - ((position - *mouse)).norm() * (radius + R);
|
||||
|
||||
@@ -60,7 +60,7 @@ class SignalManager{
|
||||
|
||||
void addSignalAtNode(int node_id){
|
||||
Color c = {(unsigned char)(20 + (rand() % 200)), 100, (unsigned char)(20 + (int)(rand() % 200)), 200};
|
||||
signals.emplace(signals.end(), Signal(nm->nodes[node_id].position.x+1, nm->nodes[node_id].position.y+1, 5.0f, 0, c)); // position + 1 or else it does not render. why? no idea!
|
||||
signals.emplace(signals.end(), Signal(nm->nodes[node_id].position.x+1, nm->nodes[node_id].position.y+1, 8.0f, 0, c)); // position + 1 or else it does not render. why? no idea!
|
||||
signals.back().next = node_id;
|
||||
signals.back().last = node_id;
|
||||
signals.back().start = node_id;
|
||||
@@ -87,7 +87,9 @@ class SignalManager{
|
||||
if(n != s.next && n != -1) {
|
||||
for(auto &m : nm->nodes[s.next].midi_outs){
|
||||
if(m.second.enabled) {
|
||||
midi.note(m.second.i, nm->nodes[s.next].midi_channel, nm->nodes[s.next].midi_note, nm->nodes[s.next].midi_velocity, nm->nodes[s.next].midi_gate);
|
||||
if(nm->nodes[s.next].send_note) midi.note(m.second.i, nm->nodes[s.next].midi_note_channel, nm->nodes[s.next].midi_note, nm->nodes[s.next].midi_velocity, nm->nodes[s.next].midi_gate);
|
||||
if(nm->nodes[s.next].send_cc) midi.cc(m.second.i, nm->nodes[s.next].midi_cc_channel, nm->nodes[s.next].midi_cc, nm->nodes[s.next].midi_cc_value);
|
||||
if(nm->nodes[s.next].send_pitch_bend) midi.pitch_bend(m.second.i, nm->nodes[s.next].midi_pitch_bend_channel, nm->nodes[s.next].midi_pitch_bend);
|
||||
}
|
||||
}
|
||||
s.last = s.next;
|
||||
|
||||
@@ -95,9 +95,9 @@ class AppUI{
|
||||
|
||||
n.config = !GuiWindowBox((Rectangle){np.x + 10, np.y + 10, 240, 440}, "config");
|
||||
|
||||
int option = n.mode;
|
||||
GuiToggleGroup((Rectangle){ np.x + 20, np.y + 40, 110, 20 }, "Round Robin;Random", &option);
|
||||
n.mode = (Distribution)option;
|
||||
int option = n.distributionMode;
|
||||
GuiToggleGroup((Rectangle){ np.x + 20, np.y + 40, 73, 20 }, "GEO;RR;RAND", &option);
|
||||
n.distributionMode = (Distribution)option;
|
||||
|
||||
GuiLabel((Rectangle){np.x + 20, np.y + 65, 220, 20}, "SIGNALS");
|
||||
if(GuiButton((Rectangle){np.x + 20, np.y + 90, 220, 20}, "ADD SIGNAL")){
|
||||
@@ -114,30 +114,65 @@ class AppUI{
|
||||
}
|
||||
|
||||
int y_channel = y_midi + 30 + i*20;
|
||||
GuiLabel((Rectangle){np.x + 20, np.y + y_channel, 220, 20}, "CHANNEL");
|
||||
GuiToggleGroup((Rectangle){np.x + 20, np.y + y_channel + 30, 25, 20}, "1;2;3;4;5;6;7;8\n9;10;11;12;13;14;15;16", &n.midi_channel);
|
||||
GuiCheckBox((Rectangle){np.x + 20, np.y + y_channel, 20, 20}, "NOTE", &n.send_note);
|
||||
GuiCheckBox((Rectangle){np.x + 90, np.y + y_channel, 20, 20}, "CC", &n.send_cc);
|
||||
GuiCheckBox((Rectangle){np.x + 160, np.y + y_channel, 20, 20}, "PITCH", &n.send_pitch_bend);
|
||||
|
||||
GuiLabel((Rectangle){np.x + 20, np.y + y_channel + 90, 100, 20}, "NOTE");
|
||||
int y_cc_note = y_channel + 120;
|
||||
switch(settings->mode){
|
||||
case 0:{
|
||||
GuiLabel((Rectangle){np.x + 20, np.y + y_cc_note - 75, 220, 20}, "NOTE CHANNEL");
|
||||
GuiToggleGroup((Rectangle){np.x + 20, np.y + y_cc_note - 50, 25, 20}, "1;2;3;4;5;6;7;8\n9;10;11;12;13;14;15;16", &n.midi_note_channel);
|
||||
|
||||
GuiLabel((Rectangle){np.x + 20, np.y + y_cc_note , 100, 20}, "NOTE");
|
||||
float v = n.midi_note;
|
||||
GuiLabel((Rectangle){np.x + 210, np.y + y_channel + 90, 20, 20}, sm->midi.midiNotes[(int)round(v)].c_str());
|
||||
GuiLabel((Rectangle){np.x + 160, np.y + y_channel + 90, 40, 20}, std::format("{}",n.midi_note).c_str());
|
||||
GuiSlider((Rectangle){np.x + 20, np.y + y_channel + 120, 220, 20}, "", "", &v, 0, 127);
|
||||
GuiLabel((Rectangle){np.x + 210, np.y + y_cc_note , 20, 20}, sm->midi.midiNotes[(int)round(v)].c_str());
|
||||
GuiLabel((Rectangle){np.x + 160, np.y + y_cc_note , 40, 20}, std::format("{}",n.midi_note).c_str());
|
||||
GuiSlider((Rectangle){np.x + 20, np.y + y_cc_note + 30, 220, 20}, "", "", &v, 0, 127);
|
||||
n.midi_note = round(v);
|
||||
|
||||
GuiLabel((Rectangle){np.x + 20, np.y + y_channel + 150, 100, 20}, "VELOCITY");
|
||||
GuiLabel((Rectangle){np.x + 20, np.y + y_cc_note + 60, 100, 20}, "VELOCITY");
|
||||
v = n.midi_velocity;
|
||||
GuiLabel((Rectangle){np.x + 210, np.y + y_channel + 150, 20, 20}, std::format("{}",n.midi_velocity).c_str());
|
||||
GuiSlider((Rectangle){np.x + 20, np.y + y_channel + 180, 220, 20}, "", "", &v, 0, 127);
|
||||
GuiLabel((Rectangle){np.x + 210, np.y + y_cc_note + 60, 20, 20}, std::format("{}",n.midi_velocity).c_str());
|
||||
GuiSlider((Rectangle){np.x + 20, np.y + y_cc_note + 90, 220, 20}, "", "", &v, 0, 127);
|
||||
n.midi_velocity = round(v);
|
||||
|
||||
GuiLabel((Rectangle){np.x + 20, np.y + y_channel + 210, 100, 20}, "GATE");
|
||||
GuiLabel((Rectangle){np.x + 20, np.y + y_cc_note + 120, 100, 20}, "GATE");
|
||||
v = n.midi_gate;
|
||||
GuiLabel((Rectangle){np.x + 210, np.y + y_channel + 210, 20, 20}, std::format("{}",(float)n.midi_gate/1000.0f).c_str());
|
||||
GuiSlider((Rectangle){np.x + 20, np.y + y_channel + 240, 220, 20}, "", "", &v, 0, 30000);
|
||||
GuiLabel((Rectangle){np.x + 210, np.y + y_cc_note + 120, 20, 20}, std::format("{}",(float)n.midi_gate/1000.0f).c_str());
|
||||
GuiSlider((Rectangle){np.x + 20, np.y + y_cc_note + 150, 220, 20}, "", "", &v, 0, 30000);
|
||||
n.midi_gate = round(v);
|
||||
break;}
|
||||
case 1:
|
||||
{
|
||||
GuiLabel((Rectangle){np.x + 20, np.y + y_cc_note - 75, 220, 20}, "CC CHANNEL");
|
||||
GuiToggleGroup((Rectangle){np.x + 20, np.y + y_cc_note - 50, 25, 20}, "1;2;3;4;5;6;7;8\n9;10;11;12;13;14;15;16", &n.midi_cc_channel);
|
||||
|
||||
//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;
|
||||
GuiLabel((Rectangle){np.x + 20, np.y + y_cc_note , 100, 20}, "CC");
|
||||
float v = n.midi_cc;
|
||||
GuiLabel((Rectangle){np.x + 160, np.y + y_cc_note , 40, 20}, std::format("{}",n.midi_cc).c_str());
|
||||
GuiSlider((Rectangle){np.x + 20, np.y + y_cc_note + 30, 220, 20}, "", "", &v, 0, 127);
|
||||
n.midi_cc = round(v);
|
||||
|
||||
GuiLabel((Rectangle){np.x + 20, np.y + y_cc_note + 60, 100, 20}, "CC VALUE");
|
||||
v = n.midi_cc_value;
|
||||
GuiLabel((Rectangle){np.x + 210, np.y + y_cc_note + 60, 20, 20}, std::format("{}",n.midi_cc_value).c_str());
|
||||
GuiSlider((Rectangle){np.x + 20, np.y + y_cc_note + 90, 220, 20}, "", "", &v, 0, 127);
|
||||
n.midi_cc_value = round(v);
|
||||
|
||||
break;}
|
||||
case 2:
|
||||
{
|
||||
GuiLabel((Rectangle){np.x + 20, np.y + y_cc_note - 75, 220, 20}, "PITCH BEND CHANNEL");
|
||||
GuiToggleGroup((Rectangle){np.x + 20, np.y + y_cc_note - 50, 25, 20}, "1;2;3;4;5;6;7;8\n9;10;11;12;13;14;15;16", &n.midi_pitch_bend_channel);
|
||||
|
||||
GuiLabel((Rectangle){np.x + 20, np.y + y_cc_note , 100, 20}, "CC");
|
||||
float v = n.midi_pitch_bend;
|
||||
GuiLabel((Rectangle){np.x + 160, np.y + y_cc_note , 40, 20}, std::format("{}",n.midi_pitch_bend).c_str());
|
||||
GuiSlider((Rectangle){np.x + 20, np.y + y_cc_note + 30, 220, 20}, "", "", &v, 0, 16383);
|
||||
n.midi_pitch_bend = round(v);
|
||||
break;}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user