Browse Source

Add MIDI pitch bend operator

master
cancel 5 years ago
parent
commit
a09c84877d
  1. 7
      bank.h
  2. 30
      sim.c
  3. 46
      tui_main.c

7
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 @@ typedef struct {
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 @@ typedef union {
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;

30
sim.c

@ -187,7 +187,8 @@ static void oper_poke_and_stun(Glyph *restrict gbuffer, Mark *restrict mbuffer,
_('*', bang) \
_(':', midi) \
_(';', udp) \
_('=', osc)
_('=', osc) \
_('?', midipb)
#define ALPHA_OPERATORS(_) \
_('A', add) \
@ -274,14 +275,12 @@ BEGIN_OPERATOR(midicc)
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)
@ -402,6 +401,27 @@ BEGIN_OPERATOR(osc)
}
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)
LOWERCASE_REQUIRES_BANG;
PORT(0, -1, IN | PARAM);

46
tui_main.c

@ -93,6 +93,7 @@ static Glyph_class glyph_class_of(Glyph glyph) {
case ':':
case ';':
case '=':
case '?':
return Glyph_class_lowercase;
case '*':
return Glyph_class_bang;
@ -641,6 +642,12 @@ void draw_oevent_list(WINDOW *win, Oevent_list const *oevent_list) {
(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);
@ -1102,6 +1109,36 @@ void send_output_events(Oosc_dev *oosc_dev, Midi_mode const *midi_mode, Usz bpm,
(void)pme;
break;
}
#endif
}
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;
@ -2161,7 +2198,7 @@ void push_opers_guide_msg(void) {
// {'*', "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 @@ int main(int argc, char **argv) {
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);

Loading…
Cancel
Save