diff options
-rw-r--r-- | apps/dolmetschctl.c | 18 | ||||
-rw-r--r-- | apps/mixer.c | 41 | ||||
-rw-r--r-- | apps/mixer.h | 5 |
3 files changed, 44 insertions, 20 deletions
diff --git a/apps/dolmetschctl.c b/apps/dolmetschctl.c index b704109..6a0bed9 100644 --- a/apps/dolmetschctl.c +++ b/apps/dolmetschctl.c @@ -42,6 +42,11 @@ void print_version() #endif } +void print_string(void* str) +{ + printf("%s\n", (char*)str); +} + int main_loop(mixer_t* x, midi_t* m, osc_t* o) { int ret = 0; @@ -67,20 +72,19 @@ int main_loop(mixer_t* x, midi_t* m, osc_t* o) return -1; } - 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); - mixer_print_langs(x); - - mixer_switch_lang(x, "en", NULL, NULL); - mixer_switch_lang(x, "de", free, &npfds); + mixer_switch_lang(x, "en", &print_string, "hello world!"); + mixer_switch_lang(x, "de", &print_string, "hallo welt!"); mixer_print_tasks(x); 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"); diff --git a/apps/mixer.c b/apps/mixer.c index 098a329..558e632 100644 --- a/apps/mixer.c +++ b/apps/mixer.c @@ -121,6 +121,7 @@ int mixer_init(mixer_t* x, const char* name, const char* device) x->name_ = name; x->output_ = NULL; + x->pfd_count_ = 0; 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); @@ -187,8 +188,8 @@ int mixer_switch_lang(mixer_t* x, const char* lang, void (*done_cb)(void*), void 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; + task->done_cb_ = done_cb; + task->done_data_ = done_data; assert(slist_add(&(x->tasks_), task)); } return 0; @@ -215,23 +216,32 @@ void mixer_print_tasks(mixer_t* x) 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)); + 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) { - return snd_rawmidi_poll_descriptors_count(x->output_); + return (x->pfd_count_ = snd_rawmidi_poll_descriptors_count(x->output_)); } int mixer_get_poll_fds(mixer_t* x, struct pollfd *pfds, int npfds) { - return snd_rawmidi_poll_descriptors(x->output_, pfds, npfds); + if(slist_length(&(x->tasks_))) + return snd_rawmidi_poll_descriptors(x->output_, pfds, npfds); + else { + int i; + for(i = 0; i < x->pfd_count_; ++i) + pfds[i].fd = -1; + } + return x->pfd_count_; } int mixer_handle_revents(mixer_t* x, struct pollfd *pfds, int npfds) { + assert(x); + int err; unsigned short revents; if((err = snd_rawmidi_poll_descriptors_revents(x->output_, pfds, npfds, &revents)) < 0) { @@ -245,18 +255,27 @@ int mixer_handle_revents(mixer_t* x, struct pollfd *pfds, int npfds) if(!(revents & POLLOUT)) return 0; - u_int8_t buf[3] = { 0xB0, 0x00, 0x02 }; - int ret = snd_rawmidi_write(x->output_, buf, sizeof(buf)); + 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_); if(ret == -EAGAIN) return 0; if(ret < 0) { error(0, 0, "MIXER: cannot write to midi port: %s", snd_strerror(ret)); return -1; } - assert(ret == sizeof(buf)); // TODO: try again?? - if((err = snd_rawmidi_drain(x->output_)) < 0) { - error(0, 0, "MIXER: cannot drain output: %s", snd_strerror(err)); - 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; diff --git a/apps/mixer.h b/apps/mixer.h index 17b3282..ffa3104 100644 --- a/apps/mixer.h +++ b/apps/mixer.h @@ -39,13 +39,14 @@ typedef struct { u_int8_t* buf_; int len_; int write_idx_; - void (*done_cb)(void*); - void* done_data; + void (*done_cb_)(void*); + void* done_data_; } task_t; typedef struct { const char* name_; snd_rawmidi_t* output_; + int pfd_count_; slist_t langs_; slist_t tasks_; } mixer_t; |