591bfbe0aa
Clang Lint CI / lint-no-video (push) Successful in 55s
Clang Build CI / run-no-video (push) Successful in 1m36s
Clang Build CI / run-video (push) Successful in 1m37s
Clang Build CI / build-release (push) Successful in 1m57s
Clang Lint CI / lint-video (push) Successful in 2m5s
96 lines
2.6 KiB
C
96 lines
2.6 KiB
C
#include <alsa/asoundlib.h>
|
|
#include <log.h>
|
|
#include <pthread.h>
|
|
|
|
#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);
|
|
}
|