shithub: aplay

Download patch

ref: 954e3c07cf9e0d2801c046780c17f2636b8a5ec6
parent: 96e75173c2cc5a167e5437d24c2d22f8c4c86bfc
author: Benjamin Scher Purcell <ben@spew.club>
date: Mon Jan 18 11:03:22 EST 2016

add volume, fix bug on devaudio not ready

--- a/aplay.c
+++ b/aplay.c
@@ -32,18 +32,19 @@
 int codecpid, pause;
 Image *back;
 
-void resized(int new);
-void mousethread(void*);
-void kbdthread(void*);
+void codecproc(void*);
 void inproc(void*);
+void kbdthread(void*);
+void mousethread(void*);
 void outproc(void*);
-void timerproc(void*);
-void codecproc(void*);
-void waitforaudio(void);
-void usage(void);
+void resized(int new);
 void shutdown(char*);
+void start(Codecargs*);
 void startstop(Codecargs*);
 void threadsfatal(void);
+void timerproc(void*);
+void usage(void);
+void waitforaudio(void);
 
 void
 threadmain(int argc, char **argv)
@@ -91,8 +92,7 @@
 	threadcreate(kbdthread, &kbdargs, STACK);
 	timer = 500;
 	proccreate(timerproc, &timer, STACK);
-	pause = 1;
-	startstop(&codecargs);
+	start(&codecargs);
 	resized(0);
 	shutdown(recvp(kbdargs.exit));
 }
@@ -123,7 +123,7 @@
 		case ' ':
 			startstop(cargs);
 //			if(pause)
-//				curoff -= 16384;
+//				curoff -= 327680;
 //			resized(0);
 			break;
 		}
@@ -177,34 +177,6 @@
 }
 
 void
-startstop(Codecargs *codecargs)
-{
-	static int inpid;
-	static Channel *inchan;
-
-	if(inchan == nil)
-		inchan = chancreate(sizeof(int), 0);
-	if(pause == 0){
-		assert(codecpid != 0 && inpid != 0);
-		postnote(PNPROC, codecpid, "die yankee pig dog");
-		threadkill(inpid);
-		codecpid = inpid = 0;
-	}else{
-		waitforaudio();
-		assert(codecpid == 0 && inpid == 0);
-		if(pipe(codecargs->infd) < 0)
-			threadsfatal();
-		proccreate(codecproc, codecargs, STACK);
-		codecpid = recvul(codecargs->pidchan);
-		inpid = proccreate(inproc, inchan, STACK);
-		send(inchan, &codecargs->infd[1]);
-		close(codecargs->infd[0]);
-		close(codecargs->infd[1]);
-	}
-	pause ^= 1;
-}
-
-void
 inproc(void *a)
 {
 	Channel *c;
@@ -248,13 +220,11 @@
 	threadsetname("codecproc");
 	rfork(RFFDG);
 	codecargs = a;
-
 	close(codecargs->infd[1]);
 	if(dup(codecargs->infd[0], 0) < 0){
 		threadsfatal();
 	}
 	close(codecargs->infd[0]);
-
 	for(i = 3; i < 20; i++)
 		close(i);
 	args[0] = codecargs->codec;
@@ -323,7 +293,7 @@
 	}
 	free(d);
 }
-	
+
 void
 usage(void)
 {
@@ -344,4 +314,45 @@
 {
 	fprint(2, "%r\n");
 	shutdown("error");
+}
+
+Channel *inchan;
+int inpid;
+
+void
+start(Codecargs *codecargs)
+{
+	inchan = chancreate(sizeof(int), 0);
+	assert(codecpid == 0 && inpid == 0);
+	if(pipe(codecargs->infd) < 0)
+		threadsfatal();
+	proccreate(codecproc, codecargs, STACK);
+	codecpid = recvul(codecargs->pidchan);
+	inpid = proccreate(inproc, inchan, STACK);
+	send(inchan, &codecargs->infd[1]);
+	close(codecargs->infd[0]);
+	close(codecargs->infd[1]);
+}
+
+void
+startstop(Codecargs *codecargs)
+{
+	if(pause == 0){
+		assert(codecpid != 0 && inpid != 0);
+		postnote(PNPROC, codecpid, "die yankee pig dog");
+		threadkill(inpid);
+		codecpid = inpid = 0;
+	}else{
+		waitforaudio();
+		assert(codecpid == 0 && inpid == 0);
+		if(pipe(codecargs->infd) < 0)
+			threadsfatal();
+		proccreate(codecproc, codecargs, STACK);
+		codecpid = recvul(codecargs->pidchan);
+		inpid = proccreate(inproc, inchan, STACK);
+		send(inchan, &codecargs->infd[1]);
+		close(codecargs->infd[0]);
+		close(codecargs->infd[1]);
+	}
+	pause ^= 1;
 }
--- a/mkfile
+++ b/mkfile
@@ -1,7 +1,9 @@
 </$objtype/mkfile
 
-TARG=aplay
-OFILES=$TARG.$O
+TARG=\
+	aplay\
+	volume\
+
 BIN=$home/bin/$objtype
 
-</sys/src/cmd/mkone
+</sys/src/cmd/mkmany
--- /dev/null
+++ b/volume.c
@@ -1,0 +1,101 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <event.h>
+#include <keyboard.h>
+
+char volstr[] = "volume";
+char mutestr[] = "muted";
+int volume, muted;
+Image *back;
+
+void
+eresized(int new)
+{
+	Rectangle r1, r2;
+	
+	if(new && getwindow(display, Refnone) < 0)
+		sysfatal("Cannot get window: %r");
+	r1 = screen->r;
+	r2 = r1;
+	r1.min.y = r1.max.y - ((vlong)Dy(r2) * volume) / 100;
+	r2.max.y = r1.min.y;
+	draw(screen, r1, back, nil, ZP);
+	draw(screen, r2, display->white, nil, ZP);
+	r2.min = ZP;
+	r2.max = stringsize(display->defaultfont, muted ? mutestr : volstr);
+	r1 = rectsubpt(screen->r, screen->r.min);
+	r2 = rectaddpt(r2, subpt(divpt(r1.max, 2), divpt(r2.max, 2)));
+	r2 = rectaddpt(r2, screen->r.min);
+	r1 = insetrect(r2, -4);
+	draw(screen, r1, display->white, nil, ZP);
+	border(screen, insetrect(r1, 1), 2, display->black, ZP);
+	string(screen, r2.min, display->black, ZP, display->defaultfont, muted ? mutestr : volstr);
+	flushimage(display, 1);
+}
+
+void
+mute(int fd)
+{
+	static int oldvol, t;
+
+	fprint(fd, "%d\n", oldvol);
+	t = oldvol;
+	oldvol = volume;
+	volume = t;
+	muted ^= 1;
+}
+
+void
+main()
+{
+	int f;
+	Mouse m;
+	Event e;
+	char buf[256], *toks[2];
+	vlong o;
+
+	f = open("/dev/volume", ORDWR);
+	if(f < 0)
+		sysfatal ("open volume failed");
+	read(f, buf, sizeof(buf));
+	gettokens(buf, toks, 2, " ");
+	volume = atoi(toks[1]);
+	if(initdraw(0, 0, "volume") < 0)
+		sysfatal("initdraw failed: %r");
+	einit(Emouse|Ekeyboard);
+	back = allocimagemix(display, DPalebluegreen, DWhite);
+	eresized(0);
+	for(;;) switch(event(&e)){
+	default:
+		break;
+	case Emouse:
+		if(muted)
+			break;
+		m = e.mouse;
+		if(m.buttons & 1) {
+			o = screen->r.max.y - m.xy.y;
+			if(o < 0) o = 0LL;
+			o *= 100;
+			o /= Dy(screen->r);
+			volume = o;
+			eresized(0);
+			fprint(f, "%d\n", volume);
+		}
+		break;
+	case Ekeyboard:
+		switch(e.kbdc){
+		default:
+			break;
+		case 'm':
+			mute(f);
+			eresized(0);
+			break;
+		case 'q':
+		case Kdel:
+			exits(0);
+			break;
+		}
+		break;
+	}
+}