From f8b836304702dcea92996ae49b3fbc9c1e6b46d0 Mon Sep 17 00:00:00 2001
From: Tim Keller <tjk@tjkeller.xyz>
Date: Sat, 5 Oct 2024 12:02:46 -0500
Subject: add max volume and mute command

---
 pavolctld.c | 30 +++++++++++++++++++++++++-----
 1 file changed, 25 insertions(+), 5 deletions(-)

diff --git a/pavolctld.c b/pavolctld.c
index adb35e1..cbeefe3 100644
--- a/pavolctld.c
+++ b/pavolctld.c
@@ -3,6 +3,7 @@
 #include <pulse/pulseaudio.h>
 
 #define ROUND_POS(x) ((int)((x) + 0.5f))
+#define VOLUME_MAX (PA_VOLUME_NORM + (PA_VOLUME_NORM / 2)) // 150% max
 
 //TODO pa_operation_unref(o);
 
@@ -91,23 +92,42 @@ static void sink_info_set_volume_callback(pa_context *c, const pa_sink_info *i,
 	pa_volume_t vol = (pa_volume_t)(atof(&cmd[1]) / 100 * PA_VOLUME_NORM); // sneaky substring, super safe
 	if (eol) return;
 
-	switch(cmd[1]) {
-		case '\n': pa_context_get_sink_info_by_index(c, i->index, sink_info_volume_callback, userdata); return;
+	if (cmd[1] == '\n') {
+		pa_context_get_sink_info_by_index(c, i->index, sink_info_volume_callback, userdata);
+		return;
+	}
+
+	switch (cmd[1]) {
 		case '+': cvol = pa_cvolume_inc(cvol, vol); break;
 		case '-': cvol = pa_cvolume_dec(cvol, vol * -1); break; // should be no underflow w/ uint32 since 0dB is only 2^16
 		default : cvol = pa_cvolume_set(cvol, i->volume.channels, vol); break;
 	}
 
+	if (pa_cvolume_avg(cvol) > VOLUME_MAX)
+		cvol = pa_cvolume_set(cvol, i->volume.channels, VOLUME_MAX);
+
 	pa_context_set_sink_volume_by_index(c, i->index, cvol, NULL, NULL);
 }
 
+static void sink_info_set_mute_callback(pa_context *c, const pa_sink_info *i, int eol, void *userdata) {
+	char *cmd = (char *)userdata;
+	if (eol) return;
+
+
+	if (cmd[1] == '\n') {
+		pa_context_set_sink_mute_by_index(c, i->index, !i->mute, NULL, NULL);
+		return;
+	}
+
+	pa_context_set_sink_mute_by_index(c, i->index, atoi(&cmd[1]), NULL, NULL);
+}
+
 /* handle stdin commands */
 static void handle_command(pa_context *c, char *cmd) {
 	// send the command to each callback using userdata
 	switch (cmd[0]) {
-		case 'v':
-			pa_context_get_sink_info_by_index(c, command_sink_index, sink_info_set_volume_callback, (void *)cmd);
-			break;
+		case 'v': pa_context_get_sink_info_by_index(c, command_sink_index, sink_info_set_volume_callback, (void *)cmd); break;
+		case 'm': pa_context_get_sink_info_by_index(c, command_sink_index, sink_info_set_mute_callback,   (void *)cmd); break;
 	}
 }
 
-- 
cgit v1.2.3