git: 9front

Download patch

ref: 65702299b3f1d4fa27bf14c471cda66078b0110e
parent: 00ccb44cce26472a18cf569a689850098ff13679
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Sun Aug 11 23:43:42 EDT 2013

esd: enlightenment sound daemon

this program allows one to stream audio from linux/windows
to plan9 /dev/audio. sometimes handy to augment vnc sessions
with sound.

--- /dev/null
+++ b/sys/src/cmd/aux/esd.c
@@ -1,0 +1,201 @@
+/*
+ * enlightenment sound daemon for plan9front
+ *
+ * usage: aux/listen1 -t 'tcp!*!16001' esd
+ */
+
+#include <u.h>
+#include <libc.h>
+
+int	bigendian = 0;
+
+void
+die(char *msg)
+{
+	exits(msg);
+}
+
+ulong
+get4(void)
+{
+	uchar buf[4];
+
+	if(readn(0, buf, 4) != 4)
+		die("read");
+	if(bigendian)
+		return buf[3] | buf[2]<<8 | buf[1]<<16 | buf[0]<<24;
+	else
+		return buf[0] | buf[1]<<8 | buf[2]<<16 | buf[3]<<24;
+}
+
+char*
+getname(char *buf)
+{
+	if(readn(0, buf, 128) != 128)
+		die("read");
+	return buf;
+}
+
+void
+put4(ulong v)
+{
+	uchar buf[4];
+
+	if(bigendian){
+		buf[3] = v & 0xFF, v >>= 8;
+		buf[2] = v & 0xFF, v >>= 8;
+		buf[1] = v & 0xFF, v >>= 8;
+		buf[0] = v & 0xFF;
+	} else {
+		buf[0] = v & 0xFF, v >>= 8;
+		buf[1] = v & 0xFF, v >>= 8;
+		buf[2] = v & 0xFF, v >>= 8;
+		buf[3] = v & 0xFF;
+	}
+	if(write(1, buf, 4) != 4)
+		die("write");
+}
+
+char*
+pcmfmt(ulong fmt, ulong rate)
+{
+	static char buf[32];
+
+	snprint(buf, sizeof(buf), "s%dc%dr%lud",
+		(fmt & 0x000F) == 0x01 ? 16 : 8,
+		(fmt & 0x00F0) == 0x20 ? 2 : 1,
+		rate);
+	return buf;
+}
+
+void
+main(void)
+{
+	ulong op, id, len, fmt, rate;
+	char buf[256];
+	int i, fd;
+
+Init:
+	/* initial protocol */
+	if(readn(0, buf, 16) != 16)	/* key */
+		die("read");
+	if((get4() & 0xFF) == 'E')	/* endian */
+		bigendian = 1;
+	put4(1);
+
+	for(;;){
+		op = get4();
+		switch(op){
+		case 0:		/* init */
+		case 1:		/* lock */
+		case 2:		/* unlock */
+			goto Init;
+		case 3:		/* stream-play */
+			fmt = get4();
+			rate = get4();
+			getname(buf);
+			fd = -1;
+			/* wait 2 seconds, device might be busy */
+			for(i=0; i<2000; i+=100){
+				fd = open("/dev/audio", OWRITE);
+				if(fd >= 0)
+					break;
+				sleep(100);
+			}
+			if(fd < 0)
+				die("open");
+			dup(fd, 1);
+			execl("/bin/audio/pcmconv", "pcmconv",
+				"-i", pcmfmt(fmt, rate), 0);
+			die("exec");
+			break;
+		case 4:
+		case 5:		/* stream-mon */
+			fmt = get4();
+			rate = get4();
+			getname(buf);
+			fd = open("/dev/audio", OREAD);
+			if(fd < 0)
+				die("open");
+			dup(fd, 0);
+			execl("/bin/audio/pcmconv", "pcmconv",
+				"-o", pcmfmt(fmt, rate), 0);
+			die("exec");
+			break;
+		case 6:		/* sample-cache */
+			fmt = get4();	/* format */
+			rate = get4();	/* rate */
+			len = get4();	/* size */
+			getname(buf);
+			id = get4();	/* sample-id */
+			if(fork() == 0){
+				/* TODO */
+				fd = open("/dev/null", OWRITE);
+				if(fd < 0)
+					die("open");
+				dup(fd, 1);
+				snprint(buf, sizeof(buf), "%lud", len);
+				execl("/bin/audio/pcmconv", "pcmconv",
+					"-l", buf,
+					"-i", pcmfmt(fmt, rate), 0);
+				die("exec");
+			}
+			waitpid();
+			put4(id);
+			break;
+		case 7:		/* sample-free */
+		case 8:		/* sample-play */
+		case 9:		/* sample-loop */
+		case 10:	/* sample-stop */
+		case 11:	/* sample-kill */
+			id = get4();
+			put4(id);
+			break;
+		case 12:	/* standby */
+		case 13:	/* resume */
+			goto Init;
+		case 14:	/* sample-getid */
+			getname(buf);
+			put4(0);/* sample-id */
+			break;
+		case 15:	/* stream-filter */
+			fmt = get4();
+			rate = get4();
+			USED(fmt);
+			USED(rate);
+			getname(buf);
+			put4(1);
+			break;
+		case 16:	/* server-info */
+		case 17:	/* server-all-info */
+			put4(1);	/* version */
+			put4(44100);	/* rate */
+			put4(0x0021);	/* fmt */
+			if(op == 16)
+				break;
+			put4(0);
+			memset(buf, 0, sizeof(buf));
+			if(write(1, buf, 32) != 32)
+				die("write");
+			break;
+		case 18:	/* subscribe */
+		case 19:	/* unsubscribe */
+			break;
+		case 20:	/* stream-pan */
+		case 21:	/* sample-pan */
+			id = get4();
+			USED(id);
+			get4();	/* left */
+			get4();	/* reight */
+			put4(1);
+			break;
+		case 22:	/* standby-mode */
+			get4();	/* version */
+			put4(0);/* mode */
+			put4(0);/* ok */
+			break;
+		case 23:	/* latency */
+			put4(0);
+		}
+	}
+}
--- a/sys/src/cmd/aux/mkfile
+++ b/sys/src/cmd/aux/mkfile
@@ -16,6 +16,7 @@
 	data2s\
 	depend\
 	disksim\
+	esd\
 	getflags\
 	icanhasmsi\
 	lines\
--