summaryrefslogtreecommitdiff
path: root/apps/mixer.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/mixer.c')
-rw-r--r--apps/mixer.c41
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;