diff options
Diffstat (limited to 'apps/mixer.c')
-rw-r--r-- | apps/mixer.c | 41 |
1 files changed, 30 insertions, 11 deletions
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; |