xref: /plan9-contrib/sys/src/games/music/playlistfs/volume.c (revision b94bb474148e9d24a82a427863d9c9eb4c20f4ae)
1 #include <u.h>
2 #include <libc.h>
3 #include <thread.h>
4 #include <fcall.h>
5 #include "pool.h"
6 #include "playlist.h"
7 
8 int	minvolume, maxvolume;
9 
10 void
11 volumeproc(void *)
12 {
13 	int fd, n, nf, i, nlines;
14 	static char buf[1024];
15 	char *lines[32];
16 	char *fields[8];
17 	char *subfields[9];
18 	int volume[8], nvolumes;
19 
20 	threadsetname("volumeproc");
21 	close(srvfd[1]);
22 	fd = open("/dev/audioctl", OREAD);
23 	if (fd < 0)
24 		threadexits(nil);
25 	for(;;){
26 		n = read(fd, buf, sizeof buf -1);
27 		if (n == 0)
28 			continue;
29 		if (n < 0){
30 			fprint(2, "volumeproc: read: %r\n");
31 			threadexits("volumeproc");
32 		}
33 		buf[n] = '\0';
34 		nlines = getfields(buf, lines, nelem(lines), 1, "\n");
35 		for(i = 0; i < nlines; i++){
36 			nf = tokenize(lines[i], fields, nelem(fields));
37 			if (nf == 0)
38 				continue;
39 			if (nf != 6 || strcmp(fields[0], "volume") || strcmp(fields[1], "out"))
40 				continue;
41 			minvolume = strtol(fields[3], nil, 0);
42 			maxvolume = strtol(fields[4], nil, 0);
43 			if (minvolume >= maxvolume)
44 				continue;
45 			nvolumes = tokenize(fields[2], subfields, nelem(subfields));
46 			if (nvolumes <= 0 || nvolumes > 8)
47 				sysfatal("bad volume data");
48 			if (debug)
49 				fprint(2, "volume changed to '");
50 			for (i = 0; i < nvolumes; i++){
51 				volume[i] = strtol(subfields[i], nil, 0);
52 				volume[i]= 100*(volume[i]- minvolume)/(maxvolume-minvolume);
53 				if (debug)
54 					fprint(2, " %d", volume[i]);
55 			}
56 			if (debug)
57 				fprint(2, "'\n");
58 			while (i < 8)
59 				volume[i++] = Undef;
60 			send(volumechan, volume);
61 		}
62 	}
63 }
64 
65 void
66 volumeset(int *v)
67 {
68 	int fd, i;
69 	char buf[256], *p;
70 
71 	fd = open("/dev/audioctl", OWRITE);
72 	if (fd < 0){
73 		fd = open("/dev/volume", OWRITE);
74 		if (fd < 0){
75 			fprint(2, "Can't set volume: %r");
76 			return;
77 		}
78 		fprint(fd, "audio out %d",  v[0]);
79 		send(volumechan, v);
80 	} else {
81 		p = buf;
82 		for (i = 0; i < 8; i++){
83 			if (v[i] == Undef) break;
84 			p = seprint(p, buf+sizeof buf, (p==buf)?"volume out '%d":" %d",
85 				minvolume + v[i] * (maxvolume-minvolume) / 100);
86 		}
87 		p = seprint(p, buf+sizeof buf, "'\n");
88 		write(fd, buf, p-buf);
89 	}
90 	close(fd);
91 }
92