diff options
-rw-r--r-- | src/mixer.c | 71 | ||||
-rw-r--r-- | src/stubs.h | 6 |
2 files changed, 70 insertions, 7 deletions
diff --git a/src/mixer.c b/src/mixer.c index 317f12c..3213995 100644 --- a/src/mixer.c +++ b/src/mixer.c @@ -7,6 +7,7 @@ struct _snd_mixer_elem { snd_mixer_elem_t *next; + snd_mixer_t *mixer; char name[SYSEX_NAMELEN]; unsigned int index, vol; }; @@ -33,6 +34,7 @@ onsysex(unsigned char *buf, unsigned len, snd_mixer_elem_t controls[MIXER_MAX_CH if (u.x.type == SYSEX_TYPE_RT && u.x.id0 == SYSEX_CONTROL && u.x.id1 == SYSEX_MASTER) { if (len == SYSEX_SIZE(master)) { + controls[0].index = 0; controls[0].vol = u.x.u.master.coarse; snprintf(controls[0].name, sizeof(controls[0].name), "master"); } @@ -48,6 +50,7 @@ onsysex(unsigned char *buf, unsigned len, snd_mixer_elem_t controls[MIXER_MAX_CH if (cn >= MIXER_MAX_CHANNELS || !memchr(u.x.u.mixinfo.name, '\0', SYSEX_NAMELEN)) return false; + controls[cn + 1].index = cn + 1; snprintf(controls[cn + 1].name, sizeof(controls[cn + 1].name), "%s", u.x.u.mixinfo.name); break; } @@ -146,11 +149,32 @@ get_controls(snd_mixer_t *mixer) if (!controls[i].name[0]) continue; + controls[i].mixer = mixer; *tail = &controls[i]; tail = &(*tail)->next; } } +static void +setvol(snd_mixer_t *mixer, unsigned cn, unsigned vol) +{ + if (!cn) { + struct sysex msg = { + .start = SYSEX_START, + .type = SYSEX_TYPE_RT, + .id0 = SYSEX_CONTROL, + .id1 = SYSEX_MASTER, + .u.master.fine = 0, + .u.master.coarse = vol, + .u.master.end = SYSEX_END, + }; + mio_write(mixer->hdl, &msg, SYSEX_SIZE(master)); + } else { + unsigned char msg[3] = { MIDI_CTL | (cn - 1), MIDI_CTLVOL, vol }; + mio_write(mixer->hdl, msg, sizeof(msg)); + } +} + int snd_mixer_open(snd_mixer_t **mixer, int mode) { @@ -159,7 +183,7 @@ snd_mixer_open(snd_mixer_t **mixer, int mode) return -1; } - if (!((*mixer)->hdl = mio_open("snd/0", MIO_OUT | MIO_IN, 0))) { + if (!((*mixer)->hdl = mio_open("snd/0", MIO_OUT | MIO_IN, false))) { WARNX1("mio_open failed"); goto fail; } @@ -180,6 +204,38 @@ snd_mixer_close(snd_mixer_t *mixer) return 0; } +int +snd_mixer_poll_descriptors_count(snd_mixer_t *mixer) +{ + return mio_nfds(mixer->hdl); +} + +int +snd_mixer_poll_descriptors(snd_mixer_t *mixer, struct pollfd *pfds, unsigned int space) +{ + if (space > (unsigned int)mio_nfds(mixer->hdl)) + return -1; + + return mio_pollfd(mixer->hdl, pfds, POLLOUT | POLLIN); +} + +int +snd_mixer_poll_descriptors_revents(snd_mixer_t *mixer, struct pollfd *pfds, unsigned int nfds, unsigned short *revents) +{ + if (!revents || nfds > (unsigned int)mio_nfds(mixer->hdl)) + return -1; + + *revents = mio_revents(mixer->hdl, pfds) | POLLIN; + return 0; +} + +int +snd_mixer_handle_events(snd_mixer_t *mixer) +{ + get_controls(mixer); + return 0; +} + struct _snd_mixer_selem_id { char noop; }; @@ -232,6 +288,13 @@ snd_mixer_selem_get_playback_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_ } int +snd_mixer_selem_set_playback_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value, int dir) +{ + setvol(elem->mixer, elem->index, value + 0x7f); + return 0; +} + +int snd_mixer_selem_get_playback_dB_range(snd_mixer_elem_t *elem, long *min, long *max) { if (max) *max = 0; @@ -262,3 +325,9 @@ snd_mixer_selem_has_playback_switch_joined(snd_mixer_elem_t *elem) { return true; } + +int +snd_mixer_selem_is_active(snd_mixer_elem_t *elem) +{ + return true; +} diff --git a/src/stubs.h b/src/stubs.h index f52e19e..6e9391e 100644 --- a/src/stubs.h +++ b/src/stubs.h @@ -345,15 +345,11 @@ char *snd_input_gets(snd_input_t *input, char *str, size_t size) { WARNX1("stub" int snd_input_getc(snd_input_t *input) { WARNX1("stub"); return 0; } int snd_input_ungetc(snd_input_t *input, int c) { WARNX1("stub"); return 0; } snd_mixer_elem_t *snd_mixer_last_elem(snd_mixer_t *mixer) { WARNX1("stub"); return NULL; } -int snd_mixer_handle_events(snd_mixer_t *mixer) { WARNX1("stub"); return 0; } int snd_mixer_attach(snd_mixer_t *mixer, const char *name) { WARNX1("stub"); return 0; } int snd_mixer_attach_hctl(snd_mixer_t *mixer, snd_hctl_t *hctl) { WARNX1("stub"); return 0; } int snd_mixer_detach(snd_mixer_t *mixer, const char *name) { WARNX1("stub"); return 0; } int snd_mixer_detach_hctl(snd_mixer_t *mixer, snd_hctl_t *hctl) { WARNX1("stub"); return 0; } int snd_mixer_get_hctl(snd_mixer_t *mixer, const char *name, snd_hctl_t **hctl) { WARNX1("stub"); return 0; } -int snd_mixer_poll_descriptors_count(snd_mixer_t *mixer) { WARNX1("stub"); return 0; } -int snd_mixer_poll_descriptors(snd_mixer_t *mixer, struct pollfd *pfds, unsigned int space) { WARNX1("stub"); return 0; } -int snd_mixer_poll_descriptors_revents(snd_mixer_t *mixer, struct pollfd *pfds, unsigned int nfds, unsigned short *revents) { WARNX1("stub"); return 0; } int snd_mixer_load(snd_mixer_t *mixer) { WARNX1("stub"); return 0; } void snd_mixer_free(snd_mixer_t *mixer) { WARNX1("stub"); } int snd_mixer_wait(snd_mixer_t *mixer, int timeout) { WARNX1("stub"); return 0; } @@ -396,7 +392,6 @@ int snd_mixer_selem_register(snd_mixer_t *mixer, struct snd_mixer_selem_regopt * void snd_mixer_selem_get_id(snd_mixer_elem_t *element, snd_mixer_selem_id_t *id) { WARNX1("stub"); } unsigned int snd_mixer_selem_get_index(snd_mixer_elem_t *elem) { WARNX1("stub"); return 0; } snd_mixer_elem_t *snd_mixer_find_selem(snd_mixer_t *mixer, const snd_mixer_selem_id_t *id) { WARNX1("stub"); return NULL; } -int snd_mixer_selem_is_active(snd_mixer_elem_t *elem) { WARNX1("stub"); return 0; } int snd_mixer_selem_is_playback_mono(snd_mixer_elem_t *elem) { WARNX1("stub"); return 0; } int snd_mixer_selem_has_playback_channel(snd_mixer_elem_t *obj, snd_mixer_selem_channel_id_t channel) { WARNX1("stub"); return 0; } int snd_mixer_selem_is_capture_mono(snd_mixer_elem_t *elem) { WARNX1("stub"); return 0; } @@ -419,7 +414,6 @@ int snd_mixer_selem_get_playback_switch(snd_mixer_elem_t *elem, snd_mixer_selem_ int snd_mixer_selem_get_capture_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int *value) { WARNX1("stub"); return 0; } int snd_mixer_selem_set_playback_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value) { WARNX1("stub"); return 0; } int snd_mixer_selem_set_capture_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value) { WARNX1("stub"); return 0; } -int snd_mixer_selem_set_playback_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value, int dir) { WARNX1("stub"); return 0; } int snd_mixer_selem_set_capture_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value, int dir) { WARNX1("stub"); return 0; } int snd_mixer_selem_set_playback_volume_all(snd_mixer_elem_t *elem, long value) { WARNX1("stub"); return 0; } int snd_mixer_selem_set_capture_volume_all(snd_mixer_elem_t *elem, long value) { WARNX1("stub"); return 0; } |