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;
}
}