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;
+ }
+}