diff options
author | Christian Pointner <equinox@spreadspace.org> | 2015-10-13 02:27:56 +0200 |
---|---|---|
committer | Christian Pointner <equinox@spreadspace.org> | 2015-10-13 02:28:01 +0200 |
commit | 6bc291c0fd3e1760ca4bfeaf33b38cbb4b21830c (patch) | |
tree | 887c41ec771a48d3323c9d2a2e0d7f6c86c36736 /app/dolmetschctl.c | |
parent | renamed files to prepare merge of code dirs (diff) |
merged app sources to single folder
Diffstat (limited to 'app/dolmetschctl.c')
-rw-r--r-- | app/dolmetschctl.c | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/app/dolmetschctl.c b/app/dolmetschctl.c new file mode 100644 index 0000000..3b20cb6 --- /dev/null +++ b/app/dolmetschctl.c @@ -0,0 +1,214 @@ +/* + * 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 <unistd.h> +#include <ctype.h> +#include <error.h> + +#include <lo/lo.h> +#include <alsa/asoundlib.h> + +#include "mixer.h" +#include "midi_server.h" +#include "osc_server.h" + + +void print_version() +{ + printf("%s\n", VERSION_STRING_0); +#if defined(__clang__) + printf("%s, using CLANG %s\n", VERSION_STRING_1, __clang_version__); +#elif defined(__GNUC__) + printf("%s, using GCC %d.%d.%d\n", VERSION_STRING_1, __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); +#else + printf("%s\n", VERSION_STRING_1); +#endif + + printf("linked against alsa-lib Version %s\n", snd_asoundlib_version()); + char verstr[32]; + lo_version(verstr, sizeof(verstr), 0, 0, 0, 0, 0, 0, 0); + printf("linked against liblo Version %s\n", verstr); +} + +void print_usage() +{ + printf("\ndolmetschctl <options>\n"); + printf(" -h print this and exit\n"); + printf(" -v print version information and exit\n"); + printf(" -x <name> the name of the mixer, dolmetschctl will look for\n"); + printf(" language files inside '%s/<name>/'\n", ETCDIR); + printf(" -d <dev> the mixer MIDI device name to use, i.e. hw:2,0,0\n"); + printf(" (use `amidi -l` to list all available devices)'\n"); + printf(" -m <dev> the MIDI control device name to use, this can be omitted to\n"); + printf(" only wait for OSC messages'\n"); + printf(" -o <port> the UDP port to listen on for OSC messages, this can be omitted\n"); + printf(" to only use the control MIDI interface'\n"); +} + +int main_loop(mixer_t* x, midi_t* m, osc_t* o) +{ + int ret = 0; + + printf("main_loop just started\n"); + + 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); + + int osc_npfds_offset = midi_npfds_offset + midi_npfds; + int osc_npfds = osc_get_poll_fd_count(o); + assert(osc_npfds >= 0); + + int npfds = midi_npfds + osc_npfds + mixer_npfds; + struct pollfd *pfds = alloca(npfds * sizeof(struct pollfd)); + if(!pfds) { + error(0, 0, "error while allocating poll fds - stack corrupted??"); + return -1; + } + + printf("main_loop running with %d pollfds...\n", npfds); + for (;;) { + 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); + + int err = poll(pfds, npfds, 200); + if(err < 0 && errno != EINTR) { + error(0, errno, "poll failed"); + break; + } + if(err <= 0) { + // timeout or EINTR + 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, x); + if(ret) + break; + + ret = osc_handle_revents(o, &(pfds[osc_npfds_offset]), osc_npfds, x); + if(ret) + break; + } + + return ret; +} + +int main(int argc, char* argv[]) +{ + int helpflag = 0; + int versionflag = 0; + char* mixer_name = NULL; + char* mixer_dev = NULL; + char* midi_dev = NULL; + char* osc_port = NULL; + + int c; + opterr = 0; + while ((c = getopt (argc, argv, "vhx:d:m:o:")) != -1) { + switch (c) { + case 'h': + helpflag = 1; + break; + case 'v': + versionflag = 1; + break; + case 'x': + mixer_name = optarg; + break; + case 'd': + mixer_dev = optarg; + break; + case 'm': + midi_dev = optarg; + break; + case 'o': + osc_port = optarg; + break; + case '?': + if (optopt == 'x' || optopt == 'd' || optopt == 'm' || optopt == 'o') + error(0, 0, "Option -%c requires an argument.\n", optopt); + else if (isprint (optopt)) + error(0, 0, "Unknown option `-%c'.\n", optopt); + else + error(0, 0, "Unknown option character `\\x%x'.\n", optopt); + return -1; + default: + return -1; + } + } + + if(helpflag) { + print_usage(); + return 0; + } + + if(versionflag) { + print_version(); + return 0; + } + + if(!mixer_name){ + error(0, 0, "mixer name must be set"); + print_usage(); + return -1; + } + + if(!mixer_dev){ + error(0, 0, "mixer device name must be set"); + print_usage(); + return -1; + } + + if(!midi_dev && !osc_port) { + error(0, 0, "either midi or osc (or both) must be specified"); + print_usage(); + return -1; + } + + mixer_t x; + if(mixer_init(&x, mixer_name, mixer_dev)) + return -1; + + midi_t m; + if(midi_init(&m, midi_dev)) + return -1; + + osc_t o; + if(osc_init(&o, osc_port)) + return -1; + + int ret = main_loop(&x, &m, &o); + + return ret; +} |