shithub: orca

Download patch

ref: ea71fc06eb53136d6b9bdbd13e09bbcc135430c6
parent: 5c09a12f1591c84a6f7d52c231ba97fb151ad25a
author: cancel <cancel@cancel.fm>
date: Sun Jan 20 01:12:40 EST 2019

Add raw UDP datagram ';' operator

--- a/bank.h
+++ b/bank.h
@@ -4,6 +4,7 @@
 typedef enum {
   Oevent_type_midi,
   Oevent_type_osc_ints,
+  Oevent_type_udp_string,
 } Oevent_types;
 
 typedef struct {
@@ -28,10 +29,19 @@
   U8 numbers[Oevent_osc_int_count];
 } Oevent_osc_ints;
 
+enum { Oevent_udp_string_count = 16 };
+
+typedef struct {
+  U8 oevent_type;
+  U8 count;
+  char chars[Oevent_udp_string_count];
+} Oevent_udp_string;
+
 typedef union {
   Oevent_any any;
   Oevent_midi midi;
   Oevent_osc_ints osc_ints;
+  Oevent_udp_string udp_string;
 } Oevent;
 
 typedef struct {
--- a/osc_out.c
+++ b/osc_out.c
@@ -91,7 +91,7 @@
   free(dev);
 }
 
-static void oosc_send_datagram(Oosc_dev* dev, char const* data, Usz size) {
+void oosc_send_datagram(Oosc_dev* dev, char const* data, Usz size) {
   ssize_t res = sendto(dev->fd, data, size, 0, dev->chosen->ai_addr,
                        dev->chosen->ai_addrlen);
   if (res < 0) {
--- a/osc_out.h
+++ b/osc_out.h
@@ -12,9 +12,20 @@
                                           char const* dest_addr,
                                           char const* dest_port);
 void oosc_dev_destroy(Oosc_dev* dev);
+
+// Send a raw UDP datagram.
+void oosc_send_datagram(Oosc_dev* dev, char const* data, Usz size);
+
+// Send a list/array of 32-bit integers in OSC format to the specified "osc
+// address" (a path like /foo) as a UDP datagram.
 void oosc_send_int32s(Oosc_dev* dev, char const* osc_address, I32 const* vals,
                       Usz count);
 
+// Susnote is for handling MIDI note sustains -- each MIDI on event should be
+// matched with a MIDI note-off event. The duration/sustain length of a MIDI
+// note is specified when it is first triggered, so the orca VM itself is not
+// responsible for sending the note-off event. We keep a list of currently 'on'
+// notes so that they can have a matching 'off' sent at the correct time.
 typedef struct {
   float remaining;
   U16 chan_note;
--- a/sim.c
+++ b/sim.c
@@ -224,6 +224,7 @@
   _('#', comment)                                                              \
   _('*', bang)                                                                 \
   _(':', midi)                                                                 \
+  _(';', udp)                                                                  \
   _('=', osc)
 
 #define ALPHA_OPERATORS(_)                                                     \
@@ -367,6 +368,32 @@
   oe->note = note_num;
   oe->velocity = midi_velocity_of(velocity_g);
   oe->bar_divisor = (U8)(index_of(length_g) + 1);
+END_OPERATOR
+
+BEGIN_OPERATOR(udp)
+  Usz n = width - x - 1;
+  if (n > 16)
+    n = 16;
+  Glyph const* restrict gline = gbuffer + y * width + x + 1;
+  Mark* restrict mline = mbuffer + y * width + x + 1;
+  Glyph cpy[Oevent_udp_string_count];
+  Usz i;
+  for (i = 0; i < n; ++i) {
+    Glyph g = gline[i];
+    if (g == '.')
+      break;
+    cpy[i] = g;
+    mline[i] |= Mark_flag_lock;
+  }
+  n = i;
+  STOP_IF_NOT_BANGED;
+  Oevent_udp_string* oe =
+      (Oevent_udp_string*)oevent_list_alloc_item(extra_params->oevent_list);
+  oe->oevent_type = (U8)Oevent_type_udp_string;
+  oe->count = (U8)n;
+  for (i = 0; i < n; ++i) {
+    oe->chars[i] = cpy[i];
+  }
 END_OPERATOR
 
 BEGIN_OPERATOR(osc)
--- a/tui_main.c
+++ b/tui_main.c
@@ -102,6 +102,7 @@
     return Glyph_class_movement;
   case '!':
   case ':':
+  case ';':
   case '=':
     return Glyph_class_lowercase;
   case '*':
@@ -587,6 +588,13 @@
         wprintw(win, " %d", eo->numbers[i]);
       }
     } break;
+    case Oevent_type_udp_string: {
+      Oevent_udp_string const* eo = &ev->udp_string;
+      wprintw(win, "UDP\tcount %d\t", (int)eo->count);
+      for (Usz j = 0; j < (Usz)eo->count; ++j) {
+        waddch(win, (chtype)eo->chars[j]);
+      }
+    } break;
     }
   }
 }
@@ -967,6 +975,12 @@
         ints[inum] = eo->numbers[inum];
       }
       oosc_send_int32s(oosc_dev, path_buff, ints, nnum);
+    } break;
+    case Oevent_type_udp_string: {
+      if (!oosc_dev)
+        continue;
+      Oevent_udp_string const* eo = &e->udp_string;
+      oosc_send_datagram(oosc_dev, eo->chars, eo->count);
     } break;
     }
   }