summaryrefslogtreecommitdiff
path: root/apps/mixer.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/mixer.c')
-rw-r--r--apps/mixer.c284
1 files changed, 0 insertions, 284 deletions
diff --git a/apps/mixer.c b/apps/mixer.c
deleted file mode 100644
index 54df1b4..0000000
--- a/apps/mixer.c
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * 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 <string.h>
-#include <error.h>
-#include <poll.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <dirent.h>
-
-#include "mixer.h"
-
-static void free_lang_entry(void* ptr)
-{
- lang_t* l = ptr;
- assert(l);
- free(l->name_);
- slist_clear(&(l->cmds_));
- free(l);
-}
-
-static void free_task_entry(void* ptr)
-{
- task_t* t = ptr;
- assert(t);
- free(t->buf_);
- free(t);
-}
-
-static int mixer_read_config_file(mixer_t* x, int dirfd, const char* filename)
-{
- assert(dirfd > 0);
-
- int fd = openat(dirfd, filename, O_RDONLY);
- if(fd < 0) {
- error(0, errno, "erorr open('%s')", filename);
- return -1;
- }
- FILE* conf = fdopen(fd, "r");
- if(conf == NULL) {
- error(0, errno, "erorr fdopen('%s')", filename);
- return -1;
- }
-
- lang_t* lang = malloc(sizeof(lang_t));
- assert(lang);
- assert((lang->name_ = strdup(filename)));
- slist_init(&(lang->cmds_), free);
- assert(slist_add(&(x->langs_), lang));
-
- char buf[256];
- while(fgets(buf, sizeof(buf), conf) != NULL) {
- midi_cmd_t* cmd = malloc(sizeof(midi_cmd_t));
- if(!cmd) {
- error(0, ENOMEM, "can't create midi command stucture");
- break;
- }
- if(sscanf(buf, "%02hhx %02hhx %02hhx", &((*cmd)[0]), &((*cmd)[1]), &((*cmd)[2])) != 3) {
- continue;
- }
- assert(slist_add(&(lang->cmds_), cmd));
- }
-
- fclose(conf);
- return 0;
-}
-
-static int mixer_read_config(mixer_t* x)
-{
- char path[1024];
- int ret = snprintf(path, sizeof(path), "%s/%s", ETCDIR, x->name_);
- assert(ret < sizeof(path));
-
- DIR* d = opendir(path);
- if(d == NULL) {
- error(0, errno, "MIXER: cannot open config directory '%s'", path);
- return -1;
- }
-
- struct dirent* entry;
- while((entry = readdir(d))) {
- if(entry->d_type == DT_REG) {
- if((ret = mixer_read_config_file(x, dirfd(d), entry->d_name)))
- break;
- }
- }
-
- if(closedir(d) < 0) {
- error(0, errno, "MIXER: cannot closeconfig directory '%s'", path);
- return -1;
- }
-
- return ret;
-}
-
-int mixer_init(mixer_t* x, const char* name, const char* device)
-{
- assert(x != NULL);
-
- x->name_ = name;
- x->output_ = NULL;
- slist_init(&(x->langs_), free_lang_entry);
- slist_init(&(x->tasks_), free_task_entry);
- int ret = snd_rawmidi_open(NULL, &(x->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 mixer_read_config(x);;
-}
-
-static void mixer_print_midi_cmds(slist_t cmds)
-{
- if(!slist_length(&(cmds)))
- printf("<no commands>\n");
- else {
- slist_element_t* tmp;
- for(tmp = cmds.first_; tmp; tmp = tmp->next_) {
- midi_cmd_t* c = (midi_cmd_t*)(tmp->data_);
- printf(" 0x%02X 0x%02X 0x%02X\n", (*c)[0], (*c)[1], (*c)[2]);
- }
- }
-}
-
-void mixer_print_langs(mixer_t* x)
-{
- assert(x);
-
- printf("languages:\n");
- if(!slist_length(&(x->langs_)))
- printf(" <no languages>\n");
- else {
- slist_element_t* tmp;
- for(tmp = x->langs_.first_; tmp; tmp = tmp->next_) {
- lang_t* l = (lang_t*)(tmp->data_);
- printf(" %s:\n", l->name_);
- mixer_print_midi_cmds(l->cmds_);
- }
- }
-}
-
-static u_int8_t* mixer_create_task_buf(slist_t cmds, int len)
-{
- u_int8_t* buf = malloc(len);
- slist_element_t* tmp;
- int i;
- for(tmp = cmds.first_, i=0; tmp; tmp = tmp->next_, i+=sizeof(midi_cmd_t)) {
- midi_cmd_t* c = (midi_cmd_t*)(tmp->data_);
- memcpy(&(buf[i]), (*c), sizeof(midi_cmd_t));
- }
- return buf;
-}
-
-int mixer_switch_lang(mixer_t* x, const char* lang, void (*done_cb)(void*), void* done_data)
-{
- slist_element_t* tmp;
- for(tmp = x->langs_.first_; tmp; tmp = tmp->next_) {
- lang_t* l = (lang_t*)(tmp->data_);
- if(!strcmp(lang, l->name_)) {
- int len = slist_length(&(l->cmds_));
- if(len > 0) {
- task_t* task = malloc(sizeof(task_t));
- assert(task);
- task->len_ = sizeof(midi_cmd_t) * len;
- assert((task->buf_ = mixer_create_task_buf(l->cmds_, task->len_)));
- task->write_idx_ = 0;
- task->done_cb_ = done_cb;
- task->done_data_ = done_data;
- assert(slist_add(&(x->tasks_), task));
- }
- return 0;
- }
- }
- error(0, 0, "requested language '%s' not found ... ignoring request", lang);
- return 0;
-}
-
-void mixer_print_tasks(mixer_t* x)
-{
- assert(x);
-
- printf("tasks:\n");
- if(!slist_length(&(x->tasks_)))
- printf(" <no tasks>\n");
- else {
- slist_element_t* tmp;
- for(tmp = x->tasks_.first_; tmp; tmp = tmp->next_) {
- task_t* t = (task_t*)(tmp->data_);
- int i;
- printf(" buf(%d) = ", t->len_);
- for(i = 0; i < t->len_; ++i) {
- printf("0x%02X%s", t->buf_[i], (i && !((i+1) % 3)) ? ", " : " ");
- }
- printf("\n write_idx = %d\n done = %016lX ( %016lX )\n\n", t->write_idx_, (int64_t)(t->done_cb_), (int64_t)(t->done_data_));
- }
- }
-}
-
-int mixer_get_poll_fd_count(mixer_t* x)
-{
- assert(x);
-
- return snd_rawmidi_poll_descriptors_count(x->output_);
-}
-
-int mixer_get_poll_fds(mixer_t* x, struct pollfd *pfds, int npfds)
-{
- assert(x && pfds && npfds);
-
- int ret = snd_rawmidi_poll_descriptors(x->output_, pfds, npfds);
- if(!slist_length(&(x->tasks_))) {
- int i;
- for(i = 0; i < ret; ++i)
- pfds[i].events = 0;
- }
- return ret;
-}
-
-int mixer_handle_revents(mixer_t* x, struct pollfd *pfds, int npfds)
-{
- assert(x && pfds && npfds);
-
- int err;
- unsigned short revents;
- if((err = snd_rawmidi_poll_descriptors_revents(x->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;
-
- assert(x->tasks_.first_);
- task_t* task = (task_t*)(x->tasks_.first_->data_);
- assert(task);
- assert(task->buf_);
-
- int ret = snd_rawmidi_write(x->output_, &(task->buf_[task->write_idx_]), task->len_ - task->write_idx_);
- if(ret == -EAGAIN)
- return 0;
- if(ret < 0) {
- error(0, 0, "MIXER: cannot write to midi port: %s", snd_strerror(ret));
- return -1;
- }
- task->write_idx_ += ret;
- if(task->write_idx_ >= task->len_) {
- if((err = snd_rawmidi_drain(x->output_)) < 0) {
- error(0, 0, "MIXER: cannot drain output: %s", snd_strerror(err));
- return -1;
- }
- if(task->done_cb_)
- task->done_cb_(task->done_data_);
-
- slist_remove(&(x->tasks_), task);
- }
-
- return 0;
-}