shithub: orca

Download patch

ref: d9225e3b6919e1ce7c62a76ca19a5f33438cb7fe
parent: 46416a7cf609513dd9def022ec99039227375135
author: cancel <cancel@cancel.fm>
date: Sat Dec 8 17:48:58 EST 2018

Add more stuff for midi sending via osc

--- a/bank.h
+++ b/bank.h
@@ -38,6 +38,10 @@
 
 typedef struct {
   U8 oevent_type;
+} Oevent_any;
+
+typedef struct {
+  U8 oevent_type;
   U8 channel;
   U8 octave;
   U8 note;
@@ -46,7 +50,7 @@
 } Oevent_midi;
 
 typedef union {
-  U8 oevent_type;
+  Oevent_any any;
   Oevent_midi midi;
 } Oevent;
 
--- a/tui_main.c
+++ b/tui_main.c
@@ -25,8 +25,14 @@
       "    -h or --help       Print this message and exit.\n"
       "\n"
       "OSC options:\n"
-      "    --osc-port <number>  UDP Port to send OSC messages to\n"
-      "                         Default: none\n"
+      "    --osc-port <number>\n"
+      "        UDP Port to send OSC messages to.\n"
+      "        Default: none\n"
+      "\n"
+      "    --osc-midi-bidule <path>\n"
+      "        Set MIDI to send to via OSC formatted for Plogue Bidule.\n"
+      "        The path argument is the path of the Plogue OSC MIDI device.\n"
+      "        Example: /OSC_MIDI_0\n"
       );
   // clang-format on
 }
@@ -382,7 +388,7 @@
       return;
     wmove(win, cury + 1, 0);
     Oevent const* ev = oevent_list->buffer + i;
-    Oevent_types evt = ev->oevent_type;
+    Oevent_types evt = ev->any.oevent_type;
     switch (evt) {
     case Oevent_type_midi: {
       Oevent_midi const* em = (Oevent_midi const*)ev;
@@ -460,7 +466,32 @@
                   scratch_field, undo_hist, tui_cursor, needs_remarking);
 }
 
+typedef enum {
+  Midi_mode_type_null,
+  Midi_mode_type_osc_bidule,
+} Midi_mode_type;
+
 typedef struct {
+  Midi_mode_type type;
+} Midi_mode_any;
+
+typedef struct {
+  Midi_mode_type type;
+  char const* path;
+} Midi_mode_osc_bidule;
+
+typedef union {
+  Midi_mode_any any;
+  Midi_mode_osc_bidule osc_bidule;
+} Midi_mode;
+
+void midi_mode_init(Midi_mode* mm) { mm->any.type = Midi_mode_type_null; }
+void midi_mode_set_osc_bidule(Midi_mode* mm, char const* path) {
+  mm->osc_bidule.type = Midi_mode_type_osc_bidule;
+  mm->osc_bidule.path = path;
+}
+
+typedef struct {
   Field field;
   Field scratch_field;
   Markmap_reusable markmap_r;
@@ -477,6 +508,7 @@
   double accum_secs;
   char const* filename;
   Oosc_dev* oosc_dev;
+  Midi_mode const* midi_mode;
   bool needs_remarking;
   bool is_draw_dirty;
   bool is_playing;
@@ -501,6 +533,7 @@
   a->accum_secs = 0.0;
   a->filename = NULL;
   a->oosc_dev = NULL;
+  a->midi_mode = NULL;
   a->needs_remarking = true;
   a->is_draw_dirty = false;
   a->is_playing = false;
@@ -554,9 +587,41 @@
   return true;
 }
 
+void app_set_midi_mode(App_state* a, Midi_mode const* midi_mode) {
+  a->midi_mode = midi_mode;
+}
+
+void send_output_events(Oosc_dev* oosc_dev, Midi_mode const* midi_mode,
+                        Oevent const* events, Usz count) {
+  Midi_mode_type midi_mode_type = midi_mode->any.type;
+  for (Usz i = 0; i < count; ++i) {
+    Oevent const* e = events + i;
+    switch ((Oevent_types)e->any.oevent_type) {
+    case Oevent_type_midi: {
+      Oevent_midi const* em = (Oevent_midi const*)e;
+      switch (midi_mode_type) {
+      case Midi_mode_type_null:
+        break;
+      case Midi_mode_type_osc_bidule: {
+        I32 ints[3];
+        ints[0] = (0x9 << 4) | em->channel;  // status
+        ints[1] = 12 * em->octave + em->note; // note number
+        // ints[1] = 12 * 4 + em->note; // note number
+        ints[2] = em->velocity;               // velocity
+        ints[2] = 127;               // velocity
+        oosc_send_int32s(oosc_dev, midi_mode->osc_bidule.path, ints,
+                         ORCA_ARRAY_COUNTOF(ints));
+      } break;
+      }
+    } break;
+    }
+  }
+}
+
 void app_do_stuff(App_state* a) {
   double secs_span = 60.0 / (double)a->bpm / 4.0;
   Oosc_dev* oosc_dev = a->oosc_dev;
+  Midi_mode const* midi_mode = a->midi_mode;
   while (a->accum_secs > secs_span) {
     a->accum_secs -= secs_span;
     undo_history_push(&a->undo_hist, &a->field, a->tick_num);
@@ -568,23 +633,10 @@
     a->needs_remarking = true;
     a->is_draw_dirty = true;
 
-    if (oosc_dev) {
-      Oevent const* events = a->oevent_list.buffer;
-      Usz oevent_count = a->oevent_list.count;
-      for (Usz i = 0; i < oevent_count; ++i) {
-        Oevent const* e = events + i;
-        switch ((Oevent_types)e->oevent_type) {
-        case Oevent_type_midi: {
-          Oevent_midi const* em = (Oevent_midi const*)e;
-          I32 ints[5];
-          ints[0] = em->channel;
-          ints[1] = em->octave;
-          ints[2] = em->note;
-          ints[3] = em->velocity;
-          ints[4] = em->bar_divisor;
-          oosc_send_int32s(oosc_dev, "/test", ints, ORCA_ARRAY_COUNTOF(ints));
-        } break;
-        }
+    if (oosc_dev && midi_mode) {
+      Usz count = a->oevent_list.count;
+      if (count > 0) {
+        send_output_events(oosc_dev, midi_mode, a->oevent_list.buffer, count);
       }
     }
   }
@@ -789,6 +841,7 @@
 enum {
   Argopt_margins = UCHAR_MAX + 1,
   Argopt_osc_port,
+  Argopt_osc_midi_bidule,
 };
 
 int main(int argc, char** argv) {
@@ -796,10 +849,13 @@
       {"margins", required_argument, 0, Argopt_margins},
       {"help", no_argument, 0, 'h'},
       {"osc-port", required_argument, 0, Argopt_osc_port},
+      {"osc-midi-bidule", required_argument, 0, Argopt_osc_midi_bidule},
       {NULL, 0, NULL, 0}};
   char* input_file = NULL;
   int margin_thickness = 2;
   U16 osc_port = 0;
+  Midi_mode midi_mode;
+  midi_mode_init(&midi_mode);
   for (;;) {
     int c = getopt_long(argc, argv, "h", tui_options, NULL);
     if (c == -1)
@@ -829,6 +885,9 @@
       }
       osc_port = (U16)osc_port0;
     } break;
+    case Argopt_osc_midi_bidule: {
+      midi_mode_set_osc_bidule(&midi_mode, optarg);
+    } break;
     case '?':
       usage();
       return 1;
@@ -890,6 +949,7 @@
     field_init_fill(&app_state.field, 25, 57, '.');
   }
   app_state.filename = input_file;
+  app_set_midi_mode(&app_state, &midi_mode);
 
   // Set up timer lib
   stm_setup();