diff options
-rw-r--r-- | apps/Makefile | 1 | ||||
-rw-r--r-- | apps/dolmetschctl.c | 32 | ||||
-rw-r--r-- | apps/midi.c | 3 | ||||
-rw-r--r-- | apps/mixer.c | 83 | ||||
-rw-r--r-- | apps/mixer.h | 39 |
5 files changed, 148 insertions, 10 deletions
diff --git a/apps/Makefile b/apps/Makefile index 90ad0fb..c19eaa9 100644 --- a/apps/Makefile +++ b/apps/Makefile @@ -28,6 +28,7 @@ EXECUTABLE := dolmetschctl C_OBJS := osc.o \ midi.o \ + mixer.o \ dolmetschctl.o C_SRCS := $(C_OBJS:%.o=%.c) diff --git a/apps/dolmetschctl.c b/apps/dolmetschctl.c index 9e3b3d5..5365c22 100644 --- a/apps/dolmetschctl.c +++ b/apps/dolmetschctl.c @@ -25,8 +25,9 @@ #include <stdio.h> #include <error.h> -#include "osc.h" +#include "mixer.h" #include "midi.h" +#include "osc.h" void print_version() @@ -41,13 +42,17 @@ void print_version() #endif } -int main_loop(osc_t* o, midi_t* m) +int main_loop(mixer_t* x, midi_t* m, osc_t* o) { int ret = 0; printf("main_loop just started\n"); - int midi_npfds_offset = 0; + int mixer_npfds_offset = 0; + int mixer_npfds = mixer_get_poll_fd_count(x); + assert(mixer_npfds > 0); + + int midi_npfds_offset = mixer_npfds_offset + mixer_npfds; int midi_npfds = midi_get_poll_fd_count(m); assert(midi_npfds > 0); @@ -55,17 +60,18 @@ int main_loop(osc_t* o, midi_t* m) int osc_npfds = osc_get_poll_fd_count(o); assert(osc_npfds > 0); - int npfds = midi_npfds + osc_npfds; + int npfds = midi_npfds + osc_npfds + mixer_npfds; struct pollfd *pfds = alloca(npfds * sizeof(struct pollfd)); + mixer_get_poll_fds(x, &(pfds[mixer_npfds_offset]), mixer_npfds); midi_get_poll_fds(m, &(pfds[midi_npfds_offset]), midi_npfds); osc_get_poll_fds(o, &(pfds[osc_npfds_offset]), osc_npfds); printf("main_loop running...\n"); for (;;) { int err = poll(pfds, npfds, 200); - if(err < 0 || errno != EINTR) { + if(err < 0 && errno != EINTR) { error(0, errno, "poll failed"); break; } @@ -74,6 +80,10 @@ int main_loop(osc_t* o, midi_t* m) continue; } + ret = mixer_handle_revents(x, &(pfds[mixer_npfds_offset]), mixer_npfds); + if(ret) + break; + ret = midi_handle_revents(m, &(pfds[midi_npfds_offset]), midi_npfds); if(ret) break; @@ -88,15 +98,19 @@ int main_loop(osc_t* o, midi_t* m) int main(int argc, char* argv[]) { - osc_t o; - if(osc_init(&o, "1200")) + mixer_t x; + if(mixer_init(&x, "qu24", "hw:1,0,0")) return -1; midi_t m; - if(midi_init(&m, "hw:2,0,0")) + if(midi_init(&m, "hw:1,0,0")) + return -1; + + osc_t o; + if(osc_init(&o, "1200")) return -1; - int ret = main_loop(&o, &m); + int ret = main_loop(&x, &m, &o); return ret; } diff --git a/apps/midi.c b/apps/midi.c index 77a6de6..955796e 100644 --- a/apps/midi.c +++ b/apps/midi.c @@ -34,6 +34,7 @@ int midi_init(midi_t* m, const char* device) { assert(m != NULL); + m->input_ = NULL; int ret = snd_rawmidi_open(&(m->input_), NULL, device, SND_RAWMIDI_NONBLOCK); if(ret < 0) { error(0, 0, "MIDI: cannot open port '%s': %s", device, snd_strerror(ret)); @@ -70,7 +71,7 @@ int midi_handle_revents(midi_t* m, struct pollfd *pfds, int npfds) u_int8_t buf[256]; int ret = snd_rawmidi_read(m->input_, buf, sizeof(buf)); - if (ret == -EAGAIN) + if(ret == -EAGAIN) return 0; if(ret < 0) { error(0, 0, "MIDI: cannot read from midi port: %s", snd_strerror(ret)); diff --git a/apps/mixer.c b/apps/mixer.c new file mode 100644 index 0000000..1e3287f --- /dev/null +++ b/apps/mixer.c @@ -0,0 +1,83 @@ +/* + * dolmetschctl + * + * + * Copyright (C) 2015 Christian Pointner <equinox@spreadspace.org> + * + * This file is part of dolmetschctl. + * + * dolmetschctl is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * dolmetschctl is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with dolmetschctl. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <stdio.h> +#include <error.h> +#include <poll.h> +#include <assert.h> + +#include "mixer.h" + + +int mixer_init(mixer_t* m, const char* name, const char* device) +{ + assert(m != NULL); + + m->name_ = name; + m->output_ = NULL; + int ret = snd_rawmidi_open(NULL, &(m->output_), device, SND_RAWMIDI_NONBLOCK); + if(ret < 0) { + error(0, 0, "MIXER: cannot open midi port '%s': %s", device, snd_strerror(ret)); + return ret; + } + + return 0; +} + +int mixer_get_poll_fd_count(mixer_t* m) +{ + return snd_rawmidi_poll_descriptors_count(m->output_); +} + +int mixer_get_poll_fds(mixer_t* m, struct pollfd *pfds, int npfds) +{ + return snd_rawmidi_poll_descriptors(m->output_, pfds, npfds); +} + +int mixer_handle_revents(mixer_t* m, struct pollfd *pfds, int npfds) +{ + int err; + unsigned short revents; + if((err = snd_rawmidi_poll_descriptors_revents(m->output_, pfds, npfds, &revents)) < 0) { + error(0, 0, "MIXER: cannot get poll events: %s", snd_strerror(errno)); + return -1; + } + if(pfds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) { + error(0, 0, "MIXER: got POLLERR, POLLHUP or POLLNVAL"); + return -1; + } + if(!(revents & POLLOUT)) + return 0; + + u_int8_t buf[3] = { 0xB0, 0x00, 0x02 }; + int ret = snd_rawmidi_write(m->output_, buf, sizeof(buf)); + if(ret == -EAGAIN) + return 0; + if(ret < 0) { + error(0, 0, "MIXER: cannot write to midi port: %s", snd_strerror(ret)); + return -1; + } + + return 0; +} diff --git a/apps/mixer.h b/apps/mixer.h new file mode 100644 index 0000000..fdd1197 --- /dev/null +++ b/apps/mixer.h @@ -0,0 +1,39 @@ +/* + * dolmetschctl + * + * + * Copyright (C) 2015 Christian Pointner <equinox@spreadspace.org> + * + * This file is part of dolmetschctl. + * + * dolmetschctl is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * dolmetschctl is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with dolmetschctl. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef DOLMETSCHCTL_mixer_h_INCLUDED +#define DOLMETSCHCTL_mixer_h_INCLUDED + +#include <alsa/asoundlib.h> +#include <poll.h> + +typedef struct { + const char* name_; + snd_rawmidi_t* output_; +} mixer_t; + +int mixer_init(mixer_t* m, const char* name, const char* device); +int mixer_get_poll_fd_count(mixer_t* m); +int mixer_get_poll_fds(mixer_t* m, struct pollfd *pfds, int npfds); +int mixer_handle_revents(mixer_t* m, struct pollfd *pfds, int npfds); + +#endif |