From: Martin Mares Date: Sat, 13 Dec 2014 14:30:29 +0000 (+0100) Subject: Generalized client groups X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=9ca652775db56e25bd82396cdd15076bc49fc9c4;p=ursary.git Generalized client groups --- diff --git a/ursaryd.c b/ursaryd.c index 857ca5f..d5b498f 100644 --- a/ursaryd.c +++ b/ursaryd.c @@ -33,7 +33,7 @@ * 4 MPD mute play/pause/stop * 5 Albireo mute - * 6 Ogion mute - - * 7 Ursula mute - + * 7 Ursula/Havrana mute - * * center all sinks * slider - @@ -106,44 +106,49 @@ static void update_sink_mute_from_button(int on, const char *sink_name) /*** Client controls ***/ struct client_map { - int rotary; + int group; const char *client; const char *host; - double range; }; static struct client_map client_map[] = { - { 4, "Music Player Daemon", "albireo", 1.5 }, - { 5, NULL, "albireo", 1.5 }, - { 6, NULL, "ogion", 1.5 }, - { 7, NULL, "ursula", 1.5 }, + { 4, "Music Player Daemon", "albireo", }, + { 5, NULL, "albireo", }, + { 6, NULL, "ogion", }, + { 7, NULL, "ursula", }, + { 7, NULL, "havrana", }, }; -#define NUM_CLIENTS ARRAY_SIZE(client_map) +#define CLIENT_MAP_SIZE ARRAY_SIZE(client_map) + +struct group_config { + bool enabled; + double range; +}; -struct client_state { +struct group_state { double volume; bool have_muted[2]; }; -static struct client_state client_state[NUM_CLIENTS]; +#define NUM_GROUPS 9 -static int find_client_by_rotary(int rotary) -{ - uns i; - for (i=0; i < NUM_CLIENTS; i++) - if (client_map[i].rotary == rotary) - return i; - return -1; -} +static struct group_config group_config[NUM_GROUPS] = { + [4] = { .enabled = 1, .range = 1.5 }, + [5] = { .enabled = 1, .range = 1.5 }, + [6] = { .enabled = 1, .range = 1.5 }, + [7] = { .enabled = 1, .range = 1.5 }, +}; + +static struct group_state group_state[NUM_GROUPS]; -static void calc_clients(void) +static void calc_groups(void) { - bzero(client_state, sizeof(client_state)); + bzero(group_state, sizeof(group_state)); CLIST_FOR_EACH(struct pulse_sink_input *, s, pulse_sink_input_list) { - s->noct_client_idx = -1; + s->noct_group_idx = -1; if (s->client_idx < 0 || s->sink_idx < 0) continue; @@ -152,67 +157,74 @@ static void calc_clients(void) if (!c) continue; - for (uns i=0; i < NUM_CLIENTS; i++) + for (uns i=0; i < CLIENT_MAP_SIZE; i++) { struct client_map *cm = &client_map[i]; - struct client_state *cs = &client_state[i]; if ((!cm->client || !strcmp(cm->client, c->name)) && (!cm->host || !strcmp(cm->host, c->host))) { - // DBG("@@ Client #%d, sink input #%d -> rotary %d", s->client_idx, s->idx, cm->rotary); - s->noct_client_idx = i; - cs->volume = MAX(cs->volume, s->volume); - cs->have_muted[!!s->mute] = 1; + int g = cm->group; + struct group_state *gs = &group_state[g]; + DBG("@@ Client #%d, sink input #%d -> group %d", s->client_idx, s->idx, g); + s->noct_group_idx = g; + gs->volume = MAX(gs->volume, s->volume); + gs->have_muted[!!s->mute] = 1; break; } } } } -static void update_clients(void) +static void update_groups(void) { - calc_clients(); + calc_groups(); - for (uns i=0; i < NUM_CLIENTS; i++) + for (uns i=0; i < NUM_GROUPS; i++) { - struct client_map *cm = &client_map[i]; - struct client_state *cs = &client_state[i]; - if (!cs->have_muted[0] && !cs->have_muted[1]) + struct group_config *gc = &group_config[i]; + struct group_state *gs = &group_state[i]; + if (!gc->enabled) + continue; + + DBG("@@ Group #%d: mute=%d/%d volume=%.3f/%.3f", i, gs->have_muted[0], gs->have_muted[1], volume_from_pa(gs->volume), gc->range); + + if (!gs->have_muted[0] && !gs->have_muted[1]) { - noct_set_ring(cm->rotary, RING_MODE_LEFT, 0); - noct_set_button(cm->rotary, 0); + noct_set_ring(i, RING_MODE_LEFT, 0); + noct_set_button(i, 0); } - else if (!cs->have_muted[0]) + else if (!gs->have_muted[0]) { - noct_set_ring(cm->rotary, RING_MODE_SINGLE_ON, 0x7f); - noct_set_button(cm->rotary, 1); + noct_set_ring(i, RING_MODE_SINGLE_ON, 0x7f); + noct_set_button(i, 1); } else { - double vol = CLAMP(volume_from_pa(cs->volume), 0, cm->range); - int val = 0x7f * vol / cm->range; + double vol = CLAMP(volume_from_pa(gs->volume), 0, gc->range); + int val = 0x7f * vol / gc->range; val = CLAMP(val, 12, 0x7f); - noct_set_ring(cm->rotary, RING_MODE_LEFT, val); - noct_set_button(cm->rotary, 0); + noct_set_ring(i, RING_MODE_LEFT, val); + noct_set_button(i, 0); } } } -static void update_client_from_rotary(int rotary, int delta) +static void update_group_from_rotary(int i, int delta) { - int i = find_client_by_rotary(rotary); - if (i < 0) + if (i >= NUM_GROUPS) + return; + struct group_config *gc = &group_config[i]; + struct group_state *gs = &group_state[i]; + if (!gc->enabled) return; - struct client_map *cm = &client_map[i]; - struct client_state *cs = &client_state[i]; - calc_clients(); - double vol = volume_from_pa(cs->volume) + delta*0.02; - pa_volume_t pavol = volume_to_pa(CLAMP(vol, 0, cm->range)); + calc_groups(); + double vol = volume_from_pa(gs->volume) + delta*0.02; + pa_volume_t pavol = volume_to_pa(CLAMP(vol, 0, gc->range)); CLIST_FOR_EACH(struct pulse_sink_input *, s, pulse_sink_input_list) { - if (s->noct_client_idx == i && s->volume != pavol) + if (s->noct_group_idx == i && s->volume != pavol) { DBG("@@ Client #%d, sink input #%d: setting volume=%u", s->client_idx, s->idx, pavol); pa_cvolume cvol; @@ -222,24 +234,25 @@ static void update_client_from_rotary(int rotary, int delta) } } -static void update_client_from_button(int button, int on) +static void update_group_from_button(int i, int on) { - if (button >= 8 || !on) + if (!on) return; - - int i = find_client_by_rotary(button); - if (i < 0) + if (i >= NUM_GROUPS) + return; + struct group_config *gc = &group_config[i]; + struct group_state *gs = &group_state[i]; + if (!gc->enabled) return; - struct client_state *cs = &client_state[i]; - calc_clients(); - if (!cs->have_muted[0] && !cs->have_muted[1]) + calc_groups(); + if (!gs->have_muted[0] && !gs->have_muted[1]) return; - uns mute = !cs->have_muted[1]; + uns mute = !gs->have_muted[1]; CLIST_FOR_EACH(struct pulse_sink_input *, s, pulse_sink_input_list) { - if (s->noct_client_idx == i) + if (s->noct_group_idx == i) { DBG("@@ Client #%d, sink input #%d: setting mute=%u", s->client_idx, s->idx, mute); pulse_sink_input_set_mute(s->idx, mute); @@ -251,8 +264,8 @@ static int find_touched_client(void) { int touched = -1; - for (uns i=0; i < NUM_CLIENTS; i++) - if (noct_rotary_touched[client_map[i].rotary]) + for (uns i=0; i < NUM_GROUPS; i++) + if (group_config[i].enabled && noct_rotary_touched[i]) { if (touched >= 0) return -1; @@ -268,7 +281,7 @@ static const char *get_client_sink(int i) const char *sink = NULL; CLIST_FOR_EACH(struct pulse_sink_input *, s, pulse_sink_input_list) - if (s->noct_client_idx == i) + if (s->noct_group_idx == i) { struct pulse_sink *sk = (s->sink_idx >= 0) ? pulse_sink_by_idx(s->sink_idx) : NULL; const char *ss = sk ? sk->name : NULL; @@ -360,7 +373,7 @@ static void update_default_sink_from_button(int button, int on) return; CLIST_FOR_EACH(struct pulse_sink_input *, s, pulse_sink_input_list) - if (s->noct_client_idx == i) + if (s->noct_group_idx == i) { DBG("Moving input #%d to sink #%d", s->idx, sk->idx); pulse_sink_input_move(s->idx, sk->idx); @@ -557,7 +570,7 @@ static void do_update(struct main_timer *t) // Everything normal update_ring_from_sink(0, "ursarium"); update_ring_from_sink(1, "catarium"); - update_clients(); + update_groups(); update_default_sink(); update_mpd(); } @@ -603,7 +616,7 @@ void notify_rotary(int rotary, int delta) update_sink_from_rotary(delta, "catarium"); break; default: - update_client_from_rotary(rotary, delta); + update_group_from_rotary(rotary, delta); } } @@ -629,7 +642,7 @@ void notify_button(int button, int on) update_mpd_from_button(button, on); break; default: - update_client_from_button(button, on); + update_group_from_button(button, on); } } diff --git a/ursaryd.h b/ursaryd.h index 0d44a7f..20a2a2c 100644 --- a/ursaryd.h +++ b/ursaryd.h @@ -67,7 +67,7 @@ struct pulse_sink_input { uint channels; uint volume; bool mute; - int noct_client_idx; // Used by the high-level logic below + int noct_group_idx; // Used by the high-level logic below }; extern clist pulse_client_list, pulse_sink_list, pulse_sink_input_list;