summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJari Vetoniemi <mailroxas@gmail.com>2018-10-31 09:22:17 +0200
committerJari Vetoniemi <mailroxas@gmail.com>2018-10-31 09:22:17 +0200
commit64afeb7f84e686c62bb8261c40e54706569d2402 (patch)
treee1061af7a7763f96cc1b80b37ce2d6e3b35492c3
parente73e63d4eb46b865b8565909b04ad2894bf027f8 (diff)
alsamixer is now usable
-rw-r--r--src/mixer.c71
-rw-r--r--src/stubs.h6
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; }