shithub: jacksense

Download patch

ref: b8559f471b8904b3033ca397e9582ae74da7056f
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
date: Tue Nov 17 11:23:47 EST 2020

wat.

--- /dev/null
+++ b/README.md
@@ -1,0 +1,9 @@
+# jacksense
+
+A small program to track whether headphones are connected to jack or
+not, and switch between speaker and headphones output accordingly.
+
+It tries to remember the last volume.  There are arguments to pass
+"safe" volumes for both speaker and headphones.
+
+Prerequisites: 9front, Intel HDA.
--- /dev/null
+++ b/jacksense.c
@@ -1,0 +1,86 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+
+static void
+usage(void)
+{
+	fprint(2, "usage: %s [-h hp_safe_volume] [-s sp_safe_volume]\n", argv0);
+	exits("usage");
+}
+
+void
+main(int argc, char **argv)
+{
+	int hp, sp, cmd, ctl, vol, lastvol, newvol;
+	int hpsafevol, spsafevol;
+	u32int x, y[4], has, had;
+	Biobuf *b;
+	char *s, *a[16], tmp[32];
+
+	hpsafevol = 65;
+	spsafevol = 70;
+	ARGBEGIN{
+	case 'h':
+		hpsafevol = atoi(EARGF(usage()));
+		break;
+	case 's':
+		spsafevol = atoi(EARGF(usage()));
+		break;
+	default:
+		usage();
+	}ARGEND
+
+	if((cmd = open("/dev/hdacmd", ORDWR)) < 0)
+		sysfatal("%r");
+	if((ctl = open("/dev/audioctl", OWRITE)) < 0)
+		sysfatal("%r");
+	if((vol = open("/dev/volume", ORDWR)) < 0)
+		sysfatal("%r");
+	if((b = Bopen("/dev/audiostat", OREAD)) == nil)
+		sysfatal("%r");
+	sp = -1;
+	hp = -1;
+	while((sp < 0 || hp < 0) && (s = Brdline(b, '\n')) != nil){
+		s[Blinelen(b)-1] = 0;
+		if(tokenize(s, a, nelem(a)) < 8)
+			continue;
+		if(strcmp(a[0], "pin") != 0 || strcmp(a[2], "out") != 0)
+			continue;
+		if(strcmp(a[3], "jack") == 0 && strcmp(a[6], "hpout") == 0)
+			hp = atoi(a[1]);
+		if(strcmp(a[3], "fix") == 0 && strcmp(a[6], "speaker") == 0)
+			sp = atoi(a[1]);
+	}
+	if(sp < 0 || hp < 0){
+		fprint(2, "couldn't detect pins\n");
+		exits("pins");
+	}
+
+	x = 0x0f0900 | (hp<<4)<<16 | (hp>>4)<<24;
+	had = -1;
+	lastvol = (spsafevol < hpsafevol ? spsafevol : hpsafevol)*2/3;
+	for(;;){
+		if(write(cmd, &x, 4) != 4 || read(cmd, y, sizeof(y)) < 4)
+			sysfatal("failed");
+		has = y[0] & (1<<31);
+		if(has != had){
+			newvol = lastvol;
+			if(pread(vol, tmp, sizeof(tmp)-1, 0) > 0 && strncmp(tmp, "master ", 7) == 0)
+				lastvol = atoi(tmp+7);
+			if(had == ~0)
+				newvol = lastvol;
+
+			/* SAVE MY EARS, OK? THANKS */
+			if(has && newvol > hpsafevol)
+				newvol = hpsafevol;
+			else if(!has && newvol > spsafevol)
+				newvol = spsafevol;
+
+			fprint(ctl, "pin %d\n", has ? hp : sp);
+			fprint(vol, "%d\n", newvol);
+		}
+		had = has;
+		sleep(300);
+	}
+}
--- /dev/null
+++ b/mkfile
@@ -1,0 +1,14 @@
+</$objtype/mkfile
+
+BIN=/$objtype/bin/audio
+TARG=jacksense
+CFLAGS=$CFLAGS -p
+
+HFILES=\
+
+OFILES=\
+	jacksense.$O\
+
+default:V: all
+
+</sys/src/cmd/mkone