ncmixer

ncurses audio mixer with cross-fade support
git clone git://git.2f30.org/ncmixer.git
Log | Files | Refs | README | LICENSE

commit d0d873a3faf9379ceb65551c40c94afed4032def
parent 6f4c25194a01382ef8dcf3b1a7ad210e2b46eae1
Author: sin <sin@2f30.org>
Date:   Fri Jun  3 16:51:54 +0100

Group inputs together in an array

Diffstat:
ncmixer.c | 179++++++++++++++++++++++++++++++++++---------------------------------------------
1 file changed, 77 insertions(+), 102 deletions(-)
diff --git a/ncmixer.c b/ncmixer.c @@ -51,15 +51,18 @@ int speed = 10; int xfading; int xftimeout; /* in milliseconds */ enum { NONE, LEFT, RIGHT } direction; -int ch0_active; -int ch1_active; -int ch0_monitor; -int ch1_monitor; -short ch0_buf[NSAMPLES]; -int ch0_nsamples; -short ch1_buf[NSAMPLES]; -int ch1_nsamples; +struct input { + int listenfd; + int clifd; + short buf[NSAMPLES]; + int nsamples; + int active; + int monitor; +} inputs[] = { + { .listenfd = -1, .clifd = -1 }, + { .listenfd = -1, .clifd = -1 } +}; struct output { char *name; @@ -67,8 +70,8 @@ struct output { short buf[NSAMPLES]; int nsamples; } outputs[] = { - { .name = MASTER_DEV, .sio_hdl = NULL, .buf = { 0 }, .nsamples = 0 }, - { .name = MONITOR_DEV, .sio_hdl = NULL, .buf = { 0 }, .nsamples = 0 } + { .name = MASTER_DEV }, + { .name = MONITOR_DEV } }; struct sio_hdl * @@ -195,64 +198,50 @@ key_cb(int fd) speed++; break; case '1': - ch0_monitor = !ch0_monitor; + inputs[0].monitor = !inputs[0].monitor; break; case '2': - ch1_monitor = !ch1_monitor; + inputs[1].monitor = !inputs[1].monitor; break; } return 0; } int -ch0_cb(int fd) +input_read(struct input *in) { int n; - memset(ch0_buf, 0, sizeof(ch0_buf)); + memset(in->buf, 0, sizeof(in->buf)); do { - n = read(fd, ch0_buf, sizeof(ch0_buf)); + n = read(in->clifd, in->buf, sizeof(in->buf)); } while (n == -1 && errno == EINTR); if (n == 0 || n == -1) return -1; - ch0_nsamples = n / 2; - return 0; -} - -int -ch1_cb(int fd) -{ - int n; - - memset(ch1_buf, 0, sizeof(ch1_buf)); - do { - n = read(fd, ch1_buf, sizeof(ch1_buf)); - } while (n == -1 && errno == EINTR); - if (n == 0 || n == -1) - return -1; - ch1_nsamples = n / 2; - return 0; + in->nsamples = n / 2; + return in->nsamples; } -/* XXX: attenuate channel 0 and channel 1 based on cross-fader */ void attenuate(void) { } int -mix(short *buf) +mix(struct input *in1, struct input *in2, struct output *out) { - short *ch0 = (short *)ch0_buf; - short *ch1 = (short *)ch1_buf; - int i, nsamples; - - nsamples = MAX(ch0_nsamples, ch1_nsamples); - for (i = 0; i < nsamples; i++) { + short *ch0 = (short *)in1->buf; + short *ch1 = (short *)in2->buf; + short *buf = (short *)out->buf; + int i; + + memset(out->buf, 0, sizeof(out->buf)); + out->nsamples = MAX(in1->nsamples, in2->nsamples); + for (i = 0; i < out->nsamples; i++) { *buf = *ch0 * 0.707 + *ch1 * 0.707; ch0++, ch1++, buf++; } - return nsamples; + return out->nsamples; } int @@ -282,8 +271,8 @@ void draw(void) { erase(); - printw("ch0_monitor: %d\n", ch0_monitor); - printw("ch1_monitor: %d\n", ch1_monitor); + printw("ch0_monitor: %d\n", inputs[0].monitor); + printw("ch1_monitor: %d\n", inputs[1].monitor); printw("speed: %d\n", speed); printw("pos: %0.2f\n", xfpos); printw("xfading: %d\n", xfading); @@ -305,25 +294,25 @@ loop(void) { struct sockaddr_un sun; socklen_t len; - struct pollfd pfd[5]; + struct pollfd pfd[64]; + struct input *in; struct output *out; int i, ret, clifd, nready; -#define CH0_LISTEN 1 -#define CH1_LISTEN 2 -#define CH0_CLIENT 3 -#define CH1_CLIENT 4 + for (i = 0; i < LEN(pfd); i++) { + pfd[0].fd = -1; + pfd[0].events = 0; + } + + inputs[0].listenfd = server_listen(CH0_NAME); + inputs[1].listenfd = server_listen(CH1_NAME); pfd[0].fd = 0; pfd[0].events = POLLIN; - pfd[CH0_LISTEN].fd = server_listen(CH0_NAME); - pfd[CH0_LISTEN].events = POLLIN; - pfd[CH1_LISTEN].fd = server_listen(CH1_NAME); - pfd[CH1_LISTEN].events = POLLIN; - pfd[CH0_CLIENT].fd = -1; /* ch0 source */ - pfd[CH0_CLIENT].events = 0; - pfd[CH1_CLIENT].fd = -1; /* ch1 source */ - pfd[CH1_CLIENT].events = 0; + pfd[inputs[0].listenfd].fd = inputs[0].listenfd; + pfd[inputs[0].listenfd].events = POLLIN; + pfd[inputs[1].listenfd].fd = inputs[1].listenfd; + pfd[inputs[1].listenfd].events = POLLIN; for (;;) { nready = poll(pfd, LEN(pfd), 1000 / FPS); @@ -339,58 +328,45 @@ loop(void) if (pfd[i].revents & POLLERR) errx(1, "bad fd"); + /* handle key presses */ if (pfd[0].revents & POLLIN) key_cb(pfd[0].fd); - if (pfd[CH0_LISTEN].revents & POLLIN) { - len = sizeof(sun); - clifd = accept(pfd[CH0_LISTEN].fd, (SA *)&sun, &len); - if (clifd == -1) { - if (errno != EINTR) - err(1, "accept"); - continue; - } - if (pfd[CH0_CLIENT].fd == -1) { - pfd[CH0_CLIENT].fd = clifd; - pfd[CH0_CLIENT].events = POLLIN; + /* accept new connections on sockets */ + for (i = 0; i < LEN(inputs); i++) { + in = &inputs[i]; + if (pfd[in->listenfd].revents & POLLIN) { + len = sizeof(sun); + clifd = accept(in->listenfd, (SA *)&sun, &len); + if (clifd == -1) { + if (errno != EINTR) + err(1, "accept"); + continue; + } + if (in->clifd != -1) { + close(clifd); + continue; + } + in->clifd = clifd; + pfd[in->clifd].fd = clifd; + pfd[in->clifd].events = POLLIN; puts("channel 0 connected"); - } else { - /* disallow further connections on the socket */ - close(clifd); } } - if (pfd[CH1_LISTEN].revents & POLLIN) { - len = sizeof(sun); - clifd = accept(pfd[CH1_LISTEN].fd, (SA *)&sun, &len); - if (clifd == -1) { - if (errno != EINTR) - err(1, "accept"); + /* read pcm data from sockets */ + for (i = 0; i < LEN(inputs); i++) { + in = &inputs[i]; + if (in->clifd == -1) continue; - } - if (pfd[CH1_CLIENT].fd == -1) { - pfd[CH1_CLIENT].fd = clifd; - pfd[CH1_CLIENT].events = POLLIN; - puts("channel 1 connected"); - } else { - /* disallow further connections on the socket */ - close(clifd); - } - } - - if (pfd[CH0_CLIENT].revents & (POLLIN | POLLHUP)) { - if (ch0_cb(pfd[CH0_CLIENT].fd) == -1) { - pfd[CH0_CLIENT].fd = -1; - pfd[CH0_CLIENT].events = 0; - puts("channel 0 disconnected"); - } - } - - if (pfd[CH1_CLIENT].revents & (POLLIN | POLLHUP)) { - if (ch1_cb(pfd[CH1_CLIENT].fd) == -1) { - pfd[CH1_CLIENT].fd = -1; - pfd[CH1_CLIENT].events = 0; - puts("channel 1 disconnected"); + if (pfd[in->clifd].revents & (POLLIN | POLLHUP)) { + if (input_read(in) == -1) { + pfd[in->clifd].fd = -1; + pfd[in->clifd].events = 0; + close(in->clifd); + in->clifd = -1; + puts("channel 0 disconnected"); + } } } @@ -401,8 +377,7 @@ loop(void) if (out->sio_hdl == NULL) continue; } - memset(out->buf, 0, sizeof(out->buf)); - out->nsamples = mix(out->buf); + mix(&inputs[0], &inputs[1], out); ret = audio_play(out->sio_hdl, out->buf, out->nsamples * 2); if (ret == -1)