ref: 47b84290b4018b31efc03a04b370fee6479f1315
parent: 33be62f22485182a477a71097d07cd9405186aed
author: cancel <cancel@cancel.fm>
date: Sun Dec 30 13:26:54 EST 2018
Add basic init of portmidi device
--- a/tui_main.c
+++ b/tui_main.c
@@ -667,6 +667,7 @@
typedef struct {
Midi_mode_type type;
PmDeviceID device_id;
+ PortMidiStream* stream;
} Midi_mode_portmidi;
#endif
@@ -679,10 +680,35 @@
} Midi_mode;
void midi_mode_init_null(Midi_mode* mm) { mm->any.type = Midi_mode_type_null; }
-void midi_mode_set_osc_bidule(Midi_mode* mm, char const* path) {
+void midi_mode_init_osc_bidule(Midi_mode* mm, char const* path) {
mm->osc_bidule.type = Midi_mode_type_osc_bidule;
mm->osc_bidule.path = path;
}
+#ifdef FEAT_PORTMIDI
+PmError midi_mode_init_portmidi(Midi_mode* mm, PmDeviceID dev_id) {
+ PmError e = Pm_Initialize();
+ if (e)
+ return e;
+ e = Pm_OpenOutput(&mm->portmidi.stream, dev_id, NULL, 0, NULL, NULL, 0);
+ if (e)
+ return e;
+ mm->portmidi.type = Midi_mode_type_portmidi;
+ mm->portmidi.device_id = dev_id;
+ return pmNoError;
+}
+#endif
+void midi_mode_deinit(Midi_mode* mm) {
+ switch (mm->any.type) {
+ case Midi_mode_type_null:
+ case Midi_mode_type_osc_bidule:
+ break;
+#ifdef FEAT_PORTMIDI
+ case Midi_mode_type_portmidi: {
+ Pm_Close(mm->portmidi.stream);
+ } break;
+#endif
+ }
+}
typedef struct {
Field field;
@@ -1759,6 +1785,7 @@
Argopt_strict_timing,
#ifdef FEAT_PORTMIDI
Argopt_portmidi_list_devices,
+ Argopt_portmidi_output_device,
#endif
};
@@ -1773,6 +1800,8 @@
{"strict-timing", no_argument, 0, Argopt_strict_timing},
#ifdef FEAT_PORTMIDI
{"portmidi-list-devices", no_argument, 0, Argopt_portmidi_list_devices},
+ {"portmidi-output-device", required_argument, 0,
+ Argopt_portmidi_output_device},
#endif
{NULL, 0, NULL, 0}};
char* input_file = NULL;
@@ -1790,10 +1819,10 @@
switch (c) {
case 'h':
usage();
- return 0;
+ exit(0);
case '?':
usage();
- return 1;
+ exit(1);
case Argopt_margins: {
margin_thickness = atoi(optarg);
if (margin_thickness < 0 ||
@@ -1802,7 +1831,7 @@
"Bad margins argument %s.\n"
"Must be 0 or positive integer.\n",
optarg);
- return 1;
+ exit(1);
}
} break;
case Argopt_undo_limit: {
@@ -1813,7 +1842,7 @@
"Bad undo-limit argument %s.\n"
"Must be 0 or positive integer.\n",
optarg);
- return 1;
+ exit(1);
}
} break;
case Argopt_osc_server: {
@@ -1823,7 +1852,8 @@
osc_port = optarg;
} break;
case Argopt_osc_midi_bidule: {
- midi_mode_set_osc_bidule(&midi_mode, optarg);
+ midi_mode_deinit(&midi_mode);
+ midi_mode_init_osc_bidule(&midi_mode, optarg);
} break;
case Argopt_strict_timing: {
strict_timing = true;
@@ -1844,8 +1874,26 @@
printf("No PortMIDI output devices detected.\n");
}
Pm_Terminate();
- return 0;
+ exit(0);
}
+ case Argopt_portmidi_output_device: {
+ int dev_id = atoi(optarg);
+ if (dev_id < 0 || (dev_id == 0 && strcmp(optarg, "0"))) {
+ fprintf(stderr,
+ "Bad portmidi-output-device argument %s.\n"
+ "Must be 0 or positive integer.\n",
+ optarg);
+ exit(1);
+ }
+ midi_mode_deinit(&midi_mode);
+ PmError pme = midi_mode_init_portmidi(&midi_mode, dev_id);
+ if (pme) {
+ fprintf(stderr, "PortMIDI error: %s\n", Pm_GetErrorText(pme));
+ exit(1);
+ }
+ // todo a bunch of places where we don't terminate pm on exit. Guess we
+ // should make a wrapper.
+ }
#endif
}
}
@@ -1854,7 +1902,7 @@
input_file = argv[optind];
} else if (optind < argc - 1) {
fprintf(stderr, "Expected only 1 file argument.\n");
- return 1;
+ exit(1);
}
qnav_init();
@@ -1913,7 +1961,7 @@
fprintf(stderr, "File load error: %s.\n", errstr);
ged_deinit(&ged_state);
qnav_deinit();
- return 1;
+ exit(1);
}
heapstr_init_cstr(&file_name, input_file);
} else {
@@ -2329,5 +2377,9 @@
endwin();
ged_deinit(&ged_state);
heapstr_deinit(&file_name);
+ midi_mode_deinit(&midi_mode);
+#ifdef FEAT_PORTMIDI
+ Pm_Terminate();
+#endif
return 0;
}