⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 playlist.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>#include <thread.h>#include <draw.h>#include <keyboard.h>#include <mouse.h>#include <control.h>#include "playlist.h"#include "../debug.h"char *playlistfile = "/mnt/playlist";char *playctlfile = "/mnt/playctl";char *playvolfile = "/mnt/playvol";char *volumefile = "/dev/audioctl";Playlist	playlist;int		playctlfd;voidplaylistproc(void*){	int fd, m, n, nf;	static char buf[8192+1];	char *p, *q, *fields[4];	threadsetname("playlistproc");	fd = open(playlistfile, OREAD);	if(fd < 0)		sysfatal("%s: %r", playlistfile);	p = buf;	n = 0;	if(debug & DBGPLAY)		fprint(2, "playlistproc: starting\n");	for(;;){		m = read(fd, buf+n, sizeof buf - 1 - n);		if(m == 0){			if(debug & DBGPLAY)				fprint(2, "playlistproc: empty read\n");			continue;		}		if(m < 0){			rerrstr(buf, sizeof(buf));			if(strcmp(buf, "reading past eof"))				sysfatal("%s: %r", playlistfile);			for(n = 0; n < playlist.nentries; n++){				free(playlist.entry[n].file);				free(playlist.entry[n].onum);			}			if(debug & DBGPLAY)				fprint(2, "playlistproc: trunc\n");			playlist.nentries = 0;			free(playlist.entry);			playlist.entry = nil;			updateplaylist(1);			seek(fd, 0, 0);			p = buf;			n = 0;			continue;		}		if(debug & DBGPLAY)			fprint(2, "playlistproc: read %d bytes\n", m);		n += m;		p[n] = '\0';		while(q = strchr(p, '\n')){			*q = 0;			nf = tokenize(p, fields, nelem(fields));			if(nf){				playlist.entry = realloc(playlist.entry, (playlist.nentries+1)*sizeof playlist.entry[0]);				if(playlist.entry == nil)					sysfatal("realloc %r");				playlist.entry[playlist.nentries].file = strdup(fields[0]);				if(nf > 1){					playlist.entry[playlist.nentries].onum = strdup(fields[1]);					if(debug & DBGPLAY)						fprint(2, "playlistproc: [%d]: %q %q\n", playlist.nentries,							playlist.entry[playlist.nentries].file,							playlist.entry[playlist.nentries].onum);				}else{					playlist.entry[playlist.nentries].onum = nil;					if(debug & DBGPLAY)						fprint(2, "playlistproc: [%d]: %q nil\n", playlist.nentries,							playlist.entry[playlist.nentries].file);				}				updateplaylist(0);	// this will also update nentries			}			q++;			n -= q-p;			p = q;		}		if(n)			memmove(buf, p, n);		p = buf;	}}voidsendplaylist(char *file, char *onum){	static int fd = -1;	char *b;	if(file == nil){		if(fd >= 0)			close(fd);		fd = open(playlistfile, OWRITE|OTRUNC);		if(fd < 0)			sysfatal("%s: truncate: %r", playlistfile);		return;	}	if(fd < 0){		fd = open(playlistfile, OWRITE);		if(fd < 0)			sysfatal("%s: %r", playlistfile);	}	b = smprint("%q	%q\n", file, onum);	if(debug & DBGPLAY)		fprint(2, "sendplaylist @%s@\n", b);	if(write(fd , b, strlen(b)) != strlen(b))		sysfatal("sendplaylist: %r");}voidplayctlproc(void*a){	int fd, n, nf;	static char buf[512+1];	char *fields[4];	Channel *chan;	threadsetname("playctlproc");	chan = a;	fd = open(playctlfile, OREAD);	if(fd < 0)		sysfatal("%s: %r", playctlfile);	for(;;){		n = read(fd, buf, sizeof buf -1);		if(n == 0)			continue;		if(n < 0)			sysfatal("%s: %r", playctlfile);		buf[n] = '\0';		nf = tokenize(buf, fields, nelem(fields));		if(nf == 0)			continue;		switch (nf){		default:			sysfatal("playctlproc: [%d]: %s", nf, fields[0]);		case 3:			chanprint(chan, "playctlproc: error %lud %q", strtoul(fields[1], nil, 0), fields[2]);			if(strcmp(fields[0], "error") == 0)				break;			// fall through		case 2:			chanprint(chan, "playctlproc: %s %lud", fields[0], strtoul(fields[1], nil, 0));		}	}}voidsendplayctl(char *fmt, ...){	va_list arg;	static int fd = -1;	va_start(arg, fmt);	if(debug & DBGPLAY){		fprint(2, "sendplayctl: fmt=%s: ", fmt);		fprint(2, fmt, arg);		fprint(2, "\n");	}	fprint(fd, fmt, arg);	va_end(arg);}voidsetvolume(char *volume){	static int fd;	if(fd == 0){		fd = open(playvolfile, OWRITE);		if(fd < 0){			fprint(2, "can't open %s, (%r) opening %s instead\n", playvolfile, "/dev/volume");			if((fd = open("/dev/volume", OWRITE)) < 0){				fprint(2, "setvolume: open: %r\n");				return;			}		}	}	if(fd < 0)		return;	fprint(fd, "volume %s", volume);}voidvolumeproc(void *arg){	int fd, n, nf, nnf, i, nlines;	static char buf[1024];	char *lines[32];	char *fields[8];	char *subfields[8];	Channel *ctl;	int volume, minvolume, maxvolume, nvolume;	ctl = arg;	threadsetname("volumeproc");	fd = open(volumefile, OREAD);	if(fd < 0){		fprint(2, "%s: %r\n", volumefile);		threadexits(nil);	}	for(;;){		n = read(fd, buf, sizeof buf -1);		if(n == 0)			continue;		if(n < 0){			fprint(2, "volumeproc: read: %r\n");			threadexits("volumeproc");		}		buf[n] = '\0';		nlines = getfields(buf, lines, nelem(lines), 1, "\n");		for(i = 0; i < nlines; i++){			nf = tokenize(lines[i], fields, nelem(fields));			if(nf == 0)				continue;			if(nf != 6 || strcmp(fields[0], "volume") || strcmp(fields[1], "out"))				continue;			minvolume = strtol(fields[3], nil, 0);			maxvolume = strtol(fields[4], nil, 0);			if(minvolume >= maxvolume)				continue;			nnf = tokenize(fields[2], subfields, nelem(subfields));			if(nnf <= 0 || nnf > 8){				fprint(2, "volume format error\n");				threadexits(nil);			}			volume = 0;			nvolume = 0;			for(i = 0; i < nnf; i++){				volume += strtol(subfields[i], nil, 0);				nvolume++;			}			volume /= nvolume;			volume = 100*(volume - minvolume)/(maxvolume-minvolume);			chanprint(ctl, "volume value %d", volume);		}	}}voidplayvolproc(void*a){	int fd, n, nf, volume, nvolume, i;	static char buf[256+1];	static errors;	char *fields[3], *subfields[9];	Channel *chan;	threadsetname("playvolproc");	chan = a;	fd = open(playvolfile, OREAD);	if(fd < 0)		sysfatal("%s: %r", playvolfile);	for(;;){		n = read(fd, buf, sizeof buf -1);		if(n == 0)			continue;		if(n < 0){			fprint(2, "%s: %r\n", playvolfile);			threadexits("playvolproc");		}		buf[n] = '\0';		if(debug) fprint(2, "volumestring: %s\n", buf);		nf = tokenize(buf, fields, nelem(fields));		if(nf == 0)			continue;		if(nf != 2 || strcmp(fields[0], "volume")){			fprint(2, "playvolproc: [%d]: %s\n", nf, fields[0]);			if(errors++ > 32)				threadexits("playvolproc");			continue;		}		nvolume = tokenize(fields[1], subfields, nelem(subfields));		if(nvolume <= 0 || nvolume > 8){			fprint(2, "volume format error\n");			if(errors++ > 32)				threadexits("playvolproc");			continue;		}		volume = 0;		for(i = 0; i < nvolume; i++)			volume += strtol(subfields[i], nil, 0);		volume /= nvolume;		chanprint(chan, "volume value %d", volume);	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -