ref: a09c84877de96f042e6ac545c4a7420b5049e694
parent: 378b374451a8c94aa85821fd18ddec4f7e88eab0
author: cancel <cancel@cancel.fm>
date: Mon Jan 20 14:32:52 EST 2020
Add MIDI pitch bend operator
--- a/bank.h
+++ b/bank.h
@@ -4,6 +4,7 @@
typedef enum {
Oevent_type_midi_note,
Oevent_type_midi_cc,
+ Oevent_type_midi_pb,
Oevent_type_osc_ints,
Oevent_type_udp_string,
} Oevent_types;
@@ -22,6 +23,11 @@
U8 channel, control, value;
} Oevent_midi_cc;
+typedef struct {
+ U8 oevent_type;
+ U8 channel, lsb, msb;
+} Oevent_midi_pb;
+
enum { Oevent_osc_int_count = 16 };
typedef struct {
@@ -43,6 +49,7 @@
Oevent_any any;
Oevent_midi_note midi_note;
Oevent_midi_cc midi_cc;
+ Oevent_midi_pb midi_pb;
Oevent_osc_ints osc_ints;
Oevent_udp_string udp_string;
} Oevent;
--- a/sim.c
+++ b/sim.c
@@ -187,7 +187,8 @@
_('*', bang) \
_(':', midi) \
_(';', udp) \
- _('=', osc)
+ _('=', osc) \
+ _('?', midipb)
#define ALPHA_OPERATORS(_) \
_('A', add) \
@@ -274,14 +275,12 @@
Usz channel = index_of(channel_g);
if (channel > 15)
return;
- Usz control = index_of(control_g);
- Usz value = safe_index_of(value_g) * 127 / 35;
Oevent_midi_cc *oe =
(Oevent_midi_cc *)oevent_list_alloc_item(extra_params->oevent_list);
oe->oevent_type = Oevent_type_midi_cc;
oe->channel = (U8)channel;
- oe->control = (U8)control;
- oe->value = (U8)value;
+ oe->control = (U8)index_of(control_g);
+ oe->value = (U8)(safe_index_of(value_g) * 127 / 35); // 0~35 -> 0~127
END_OPERATOR
BEGIN_OPERATOR(comment)
@@ -400,6 +399,27 @@
oe->numbers[i] = buff[i];
}
}
+END_OPERATOR
+
+BEGIN_OPERATOR(midipb)
+ for (Usz i = 1; i < 4; ++i) {
+ PORT(0, (Isz)i, IN);
+ }
+ STOP_IF_NOT_BANGED;
+ Glyph channel_g = PEEK(0, 1);
+ Glyph msb_g = PEEK(0, 2);
+ Glyph lsb_g = PEEK(0, 3);
+ if (channel_g == '.')
+ return;
+ Usz channel = index_of(channel_g);
+ if (channel > 15)
+ return;
+ Oevent_midi_pb *oe =
+ (Oevent_midi_pb *)oevent_list_alloc_item(extra_params->oevent_list);
+ oe->oevent_type = Oevent_type_midi_pb;
+ oe->channel = (U8)channel;
+ oe->msb = (U8)(safe_index_of(msb_g) * 127 / 35); // 0~35 -> 0~127
+ oe->lsb = (U8)(safe_index_of(lsb_g) * 127 / 35);
END_OPERATOR
BEGIN_OPERATOR(add)
--- a/tui_main.c
+++ b/tui_main.c
@@ -93,6 +93,7 @@
case ':':
case ';':
case '=':
+ case '?':
return Glyph_class_lowercase;
case '*':
return Glyph_class_bang;
@@ -641,6 +642,12 @@
(int)ec->channel, (int)ec->control, (int)ec->value);
break;
}
+ case Oevent_type_midi_pb: {
+ Oevent_midi_pb const *ep = &ev->midi_pb;
+ wprintw(win, "MIDI PB\tchannel %d\tmsb %d\tlsb %d", (int)ep->channel,
+ (int)ep->msb, (int)ep->lsb);
+ break;
+ }
case Oevent_type_osc_ints: {
Oevent_osc_ints const *eo = &ev->osc_ints;
wprintw(win, "OSC\t%c\tcount: %d ", eo->glyph, eo->count, eo->count);
@@ -1106,6 +1113,36 @@
}
break;
}
+ case Oevent_type_midi_pb: {
+ Oevent_midi_pb const *ep = &e->midi_pb;
+ // Same caveat regarding ordering with MIDI CC also applies here.
+ switch (midi_mode_type) {
+ case Midi_mode_type_null:
+ break;
+ case Midi_mode_type_osc_bidule: {
+ // TODO ok this is getting highly redundant
+ if (!oosc_dev)
+ break; // not sure if needed
+ I32 ints[3];
+ ints[0] = (0xe << 4) | ep->channel;
+ ints[1] = ep->lsb;
+ ints[2] = ep->msb;
+ oosc_send_int32s(oosc_dev, midi_mode->osc_bidule.path, ints,
+ ORCA_ARRAY_COUNTOF(ints));
+ }
+#ifdef FEAT_PORTMIDI
+ case Midi_mode_type_portmidi: {
+ int istatus = (0xe << 4) | (int)ep->channel;
+ PmError pme =
+ Pm_WriteShort(midi_mode->portmidi.stream, 0,
+ Pm_Message(istatus, (int)ep->lsb, (int)ep->msb));
+ (void)pme;
+ break;
+ }
+#endif
+ }
+ break;
+ }
case Oevent_type_osc_ints: {
// kinda lame
if (!oosc_dev)
@@ -2161,7 +2198,7 @@
// {'*', "self", "Sends ORCA command."},
{':', "midi", "Sends MIDI note."},
{'!', "cc", "Sends MIDI control change."},
- // {'?', "pb", "Sends MIDI pitch bend."},
+ {'?', "pb", "Sends MIDI pitch bend."},
// {'%', "mono", "Sends MIDI monophonic note."},
{'=', "osc", "Sends OSC message."},
{';', "udp", "Sends UDP message."},
@@ -3557,7 +3594,12 @@
ged_input_cmd(&t.ged, Ged_input_cmd_toggle_append_mode);
break;
case '/':
- // Currently unused. Formerly 'piano'/trigger mode toggle.
+ // Formerly 'piano'/trigger mode toggle. We're repurposing it here to
+ // input a '?' instead of a '/' because '?' opens the help guide, and it
+ // might be a bad idea to take that away, since orca will take over the
+ // TTY and may leave users confused. I know of at least 1 person who was
+ // saved by pressing '?' after they didn't know what to do. Hmm.
+ ged_input_character(&t.ged, '?');
break;
case '<':
ged_adjust_bpm(&t.ged, -1);