#include #include #include #include "types.h" #include "config.h" void snd_no_log(__attribute__((unused)) int prio, __attribute__((unused)) int interface, __attribute__((unused)) const char *file, __attribute__((unused)) int line, __attribute__((unused)) const char *function, __attribute__((unused)) int errcode, __attribute__((unused)) const char *fmt, __attribute__((unused)) va_list arg) {} void midi_open(MidiDevice *device, const char *name, bool log_error) { strlcpy(device->name, name, STR_LEN); device->connected = false; device->input = NULL; device->output = NULL; device->connected = snd_rawmidi_open(&device->input, &device->output, name, SND_RAWMIDI_SYNC) == 0 && device->input != NULL && device->output != NULL; if (log_error) { if (device->connected) { log_info("(%s) MIDI open", name); } else { log_warn("(%s) MIDI open failed", name); } } } void midi_write(MidiDevice device, unsigned char code, unsigned char value) { if (!device.connected) { return; } unsigned char buffer[3]; buffer[0] = 0xB0; buffer[1] = code; buffer[2] = value; snd_rawmidi_write(device.output, buffer, 3); } void midi_close(MidiDevice *device) { if (device->connected) { snd_rawmidi_close(device->input); snd_rawmidi_close(device->output); device->connected = false; } } void *midi_background_listen(void *args) { MidiBackgroundListenArgs *process_args = (MidiBackgroundListenArgs *)args; MidiDevice *device = process_args->device; Context *context = process_args->context; int bytes_read; snd_rawmidi_info_t *info; unsigned char buffer[3]; log_info("(%s) background acquisition started", device->name); snd_rawmidi_info_malloc(&info); if (info == NULL) { log_error("(%s) failed to allocate MIDI info", device->name); free(process_args); pthread_exit(NULL); } while (!context->stop && snd_rawmidi_info(device->output, info) == 0) { bytes_read = snd_rawmidi_read(device->input, buffer, 3); if (bytes_read == 3) { process_args->event_callback(buffer[1], buffer[2]); } } snd_rawmidi_info_free(info); if (context->stop) { log_info("(%s) background acquisition stopped by main thread", device->name); } else { log_info("(%s) background acquisition stopped after error", device->name); midi_close(device); } free(process_args); pthread_exit(NULL); }