203 lines · 3.3 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <stdio.h>#include <thread.h>#include <regexp.h>#include "dat.h"#include "fns.h" static int cdread, cdloop;static double cdvol;static int ntrk, trk, chtrk;static char trtype;static int cpid = -1;static cvar_t *ccdvol; static intcdinfo(void){	int fd, i, n;	Dir *d;	Reprog *pat; 	ntrk = 0; 	if((fd = open("/mnt/cd", OREAD)) < 0)		return -1;	n = dirreadall(fd, &d);	close(fd);	if(n < 0)		return -1;	pat = regcomp("[au][0-9][0-9][0-9]");	for(i = 0; i < n; i++)		if(regexec(pat, d[i].name, nil, 0)){			if(!trtype)				trtype = d[i].name[0];			ntrk++;		}	free(pat);	free(d);	if(ntrk < 1)		return -1;	return 0;} static voidcproc(void *){	int a, n, afd, fd;	char s[24];	uchar buf[Nsbuf];	short *p, *e; 	if((afd = open("/dev/audio", OWRITE)) < 0){		fprint(2, "cd: open: %r\n");		return;	}	fd = -1;	for(;;){		if(chtrk > 0){			close(fd);			trk = chtrk;			snprint(s, sizeof s, "/mnt/cd/%c%03ud", trtype, trk);			if((fd = open(s, OREAD)) < 0)				fprint(2, "cd: open: %r\n");			chtrk = 0;		}		if(!cdread || fd < 0){			sleep(1);			continue;		}		if((n = read(fd, buf, sizeof buf)) < 0)			break;		if(n == 0){			if(cdloop)				seek(fd, 0, 0);			else{				close(fd);				fd = -1;			}			continue;		}		p = (short *)buf;		e = (short *)(buf + n);		while(p < e){			a = *p * cdvol;			*p++ = a;		}		if(write(afd, buf, n) != n)			break;		/* threadkill requires that a libthread function be used		 * somewhere: thread(2), errors notes and resources */		yield();	}} voidCDAudio_Play(int nt, qboolean loop){	if(cpid < 0)		return;	nt -= 1;	/* d001 was assumed part of the track list */	if(nt < 1 || nt > ntrk){		Com_Printf("cd: invalid track number %d\n", nt);		return;	} 	chtrk = nt;	cdloop = loop;	cdvol = ccdvol->value;	if(cdvol > 0)		cdread = 1;} voidCDAudio_Stop(void){	cdread = 0;	cdloop = 0;} voidCDAudio_Pause(void){	cdread = 0;} voidCDAudio_Resume(void){	cdread = 1;} voidCD_f(void){	char *cmd; 	if(Cmd_Argc() < 2){usage:		Com_Printf("cd (play|loop|stop|pause|resume|info) [track]\n");		return;	}	cmd = Cmd_Argv(1);	if(cistrcmp(cmd, "play") == 0){		if(Cmd_Argc() < 3)			goto usage;		CDAudio_Play(atoi(Cmd_Argv(2)), false);	}else if(cistrcmp(cmd, "loop") == 0){		if(Cmd_Argc() < 3)			goto usage;		CDAudio_Play(atoi(Cmd_Argv(2)), true);	}else if(cistrcmp(cmd, "stop") == 0)		CDAudio_Stop();	else if(cistrcmp(cmd, "pause") == 0)		CDAudio_Pause();	else if(cistrcmp(cmd, "resume") == 0)		CDAudio_Resume();	else if(cistrcmp(cmd, "info") == 0)		Com_Printf("track %d/%d; loop %d; vol %.1f\n", trk, ntrk, cdloop, cdvol);	else		goto usage;} voidCDAudio_Update(void){	if(cpid < 0)		return;	if(ccdvol->value <= 0.0 || cdread == 0)		return;	cdvol = ccdvol->value;	cdread = cdvol > 0.0;} intCDAudio_Init(void){	int tid; 	if(cdinfo() < 0)		return -1;	ccdvol = Cvar_Get("cdvol", "1", CVAR_ARCHIVE);	if((tid = proccreate(cproc, nil, 16384)) < 0)		sysfatal("proccreate: %r");	cpid = threadpid(tid);	Cmd_AddCommand("cd", CD_f); 	Com_Printf("CD Audio Initialized\n");	return 0;} voidCDAudio_Shutdown(void){	if(cpid < 0)		return; 	CDAudio_Stop();	if(postnote(PNPROC, cpid, "die die die") < 0)		fprint(2, "CDAudio_Shutdown: postnote: %r\n");	cpid = -1;	cdread = cdloop = 0;}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t