shithub: qk1

Download patch

ref: 938b01600ead52d3cbe352846c98d9896bd6a52e
parent: 5beae2e46ce22ccb05749710f52b7e4964f01d68
author: qwx <qwx@sciops.net>
date: Sat Jul 24 06:19:06 EDT 2021

snd: fix playback from physical cd's and put it in its own proc

this is how playback from cd's is supposed to work, reading
from the cd without waiting for the rest of the code and mixing
it with the sound effects, and it also drastically improves
performance.  the rest of the program shouldn't have to wait
for the cd drive, and it's fine to leave mixing to mixfs rather
than having to sync and mix things ourselves (ioproc or
otherwise).

--- a/README
+++ b/README
@@ -134,7 +134,7 @@
 
 qk1 reads /mnt/cd/[au]NNN files as in cdfs(1) to play music.  The directory
 needn't be populated by cdfs(1), so long as the files are in the format
-described by audio(3).  Reading from actual cdroms is currently broken.
+described by audio(3).  CD playback requires mixfs(1).
 
 
 Known bugs
--- a/cl_parse.c
+++ b/cl_parse.c
@@ -878,9 +878,9 @@
 			cl.cdtrack = MSG_ReadByte ();
 			MSG_ReadByte();	/* looptrack */
 			if((cls.demoplayback || cls.demorecording) && cls.forcetrack > 0)
-				startcd(cls.forcetrack, 1);
+				playcd(cls.forcetrack, 1);
 			else
-				startcd(cl.cdtrack, 1);
+				playcd(cl.cdtrack, 1);
 			break;
 
 		case svc_intermission:
--- a/fns.h
+++ b/fns.h
@@ -8,7 +8,7 @@
 void	stopcd(void);
 void	pausecd(void);
 void	resumecd(void);
-void	startcd(int, int);
+void	playcd(int, int);
 void	stopallsfx(void);
 void	stopsfx(int, int);
 void	startsfx(int, int, Sfx *, vec3_t, float, float);
--- a/mkfile
+++ b/mkfile
@@ -4,6 +4,7 @@
 TARG=quake
 
 OFILES=\
+	cd.$O\
 	cl_demo.$O\
 	cl_input.$O\
 	cl_main.$O\
--- a/qw/cdaudio.h
+++ b/qw/cdaudio.h
@@ -1,5 +1,5 @@
 int	initcd(void);
-void	startcd(int, int);
+void	playcd(int, int);
 void	pausecd(void);
 void	resumecd(void);
 void	shutcd(void);
--- a/qw/cl_parse.c
+++ b/qw/cl_parse.c
@@ -1255,7 +1255,7 @@
 
 		case svc_cdtrack:
 			cl.cdtrack = MSG_ReadByte ();
-			startcd ((byte)cl.cdtrack, true);
+			playcd ((byte)cl.cdtrack, true);
 			break;
 
 		case svc_intermission:
--- a/qw/mkfile
+++ b/qw/mkfile
@@ -6,6 +6,7 @@
 	qwsv\
 
 CLOBJ=\
+	cd.$O\
 	cl_cam.$O\
 	cl_demo.$O\
 	cl_ents.$O\
--- a/qw/snd.c
+++ b/qw/snd.c
@@ -3,7 +3,6 @@
 #include <stdio.h>
 #include "quakedef.h"
 
-cvar_t bgmvolume = {"bgmvolume", "1", 1};
 cvar_t volume = {"volume", "0.7", 1};
 
 typedef struct Chan Chan;
@@ -47,11 +46,6 @@
 
 static sfx_t *ambsfx[NUM_AMBIENTS];
 
-static char cdfile[13];
-static int ntrk;
-static int cdfd = -1;
-static int cdread, cdloop, cdvol;
-
 typedef struct
 {
 	int 	length;
@@ -333,26 +327,19 @@
 	return sc;
 }
 
-void
-stepcd(void)
-{
-	cdvol = bgmvolume.value * 256;
-	cdread = cdfd >= 0 && cdvol > 0;
-}
-
 static void
 sndout(void)
 {
-	int v, vol, *pb, *pe;
+	int v, *pb, *pe;
 	uchar *p;
+	double vol;
 
-	vol = volume.value * 256;
+	vol = volume.value;
 	p = mixbuf;
 	pb = sampbuf;
 	pe = sampbuf + nsamp * 2;
 	while(pb < pe){
-		v = (short)(p[1] << 8 | p[0]) * cdvol >> 8;
-		v += *pb++ * vol >> 8;
+		v = *pb++ * vol;
 		if(v > 0x7fff)
 			v = 0x7fff;
 		else if(v < -0x8000)
@@ -442,47 +429,7 @@
 	sndout();
 }
 
-void
-stopcd(void)
-{
-	if(cdfd >= 0)
-		close(cdfd);
-	cdread = 0;
-	cdloop = 0;
-}
-
-void
-pausecd(void)
-{
-	cdread = 0;
-}
-
-void
-resumecd(void)
-{
-	cdread = 1;
-}
-
 static void
-readcd(int ns)
-{
-	int n;
-
-	if(cdfd < 0 || !cdread)
-		return;
-	if(n = readn(cdfd, mixbuf, ns), n != ns){
-		if(n < 0 || !cdloop)
-			stopcd();
-		else{
-			seek(cdfd, 0, 0);
-			ns -= n;
-			if(n = readn(cdfd, mixbuf+n, ns), n != ns)
-				stopcd();
-		}
-	}
-}
-
-static void
 spatialize(Chan *c)
 {
 	vec_t Δr, m;
@@ -593,8 +540,6 @@
 	if(nsamp > Ssamp)
 		nsamp = Ssamp;
 	ns = nsamp * Sblk;
-	memset(mixbuf, 0, ns);
-	readcd(ns);
 	samplesfx();
 	if(write(afd, mixbuf, ns) != ns){
 		fprint(2, "sndwrite: %r\n");
@@ -604,25 +549,6 @@
 }
 
 void
-startcd(int nt, int loop)
-{
-	if(ntrk < 1)
-		return;
-	nt -= 1;	/* d001 assumed part of track list */
-	if(nt < 1 || nt > ntrk){
-		fprint(2, "startcd: invalid track number %d\n", nt);
-		return;
-	}
-	if(cdfd = open(va("%s%03d", cdfile, nt), OREAD), cdfd < 0){
-		fprint(2, "startcd: open: %r\n");
-		return;
-	}
-	cdloop = loop;
-	if(cdvol > 0)
-		cdread = 1;
-}
-
-void
 stopallsfx(void)
 {
 	if(afd < 0)
@@ -799,33 +725,6 @@
 }
 
 static void
-cdcmd(void)
-{
-	char *c;
-
-	if(Cmd_Argc() < 2){
-usage:
-		Con_Printf("cd (play|loop|stop|pause|resume|info) [track]\n");
-		return;
-	}
-	c = Cmd_Argv(1);
-	if(cistrcmp(c, "play") == 0){
-		if(Cmd_Argc() < 2)
-			goto usage;
-		startcd(atoi(Cmd_Argv(2)), 0);
-	}else if(cistrcmp(c, "loop") == 0){
-		if(Cmd_Argc() < 2)
-			goto usage;
-		startcd(atoi(Cmd_Argv(2)), 1);
-	}else if(cistrcmp(c, "stop") == 0)
-		stopcd();
-	else if(cistrcmp(c, "pause") == 0)
-		pausecd();
-	else if(cistrcmp(c, "resume") == 0)
-		resumecd();
-}
-
-static void
 playsfx(void)
 {
 	static int hash = 345;
@@ -896,12 +795,6 @@
 }
 
 void
-shutcd(void)
-{
-	stopcd();
-}
-
-void
 shutsnd(void)
 {
 	if(afd < 0)
@@ -909,52 +802,7 @@
 	close(afd);
 }
 
-static int
-cdinfo(void)
-{
-	int fd, i, n, nt;
-	char *t, types[] = {'a', 'u', 0};
-	Dir *d;
-
-	ntrk = 0;
-	if(fd = open("/mnt/cd", OREAD), fd < 0)
-		return -1;
-	if(n = dirreadall(fd, &d), n < 0){
-		close(fd);
-		return -1;
-	}
-	close(fd);
-	t = types;
-	for(;;){
-		for(nt=0, i=0; i<n; i++)
-			if(strcmp(d[i].name, va("%c%03d", *t, ntrk+1)) == 0){
-				ntrk++;
-				nt = 1;
-			}
-		if(ntrk < 1){
-			if(*++t == 0){
-				werrstr("cdinfo: no tracks found");
-				break;
-			}
-		}else if(nt == 0){
-			snprint(cdfile, sizeof cdfile, "/mnt/cd/%c", *t);
-			break;
-		}
-	}
-	free(d);
-	return ntrk < 1 ? -1 : 0;
-}
-
 int
-initcd(void)
-{
-	if(cdinfo() < 0)
-		return -1;
-	Cmd_AddCommand("cd", cdcmd);
-	return 0;
-}
-
-int
 initsnd(quakeparms_t *q)
 {
 	int i, j, *p;
@@ -971,7 +819,6 @@
 	Cvar_RegisterVariable(&volume);
 	Cvar_RegisterVariable(&precache);
 	Cvar_RegisterVariable(&loadas8bit);
-	Cvar_RegisterVariable(&bgmvolume);
 	Cvar_RegisterVariable(&ambient_level);
 	Cvar_RegisterVariable(&ambient_fade);
 	if(q->memsize < 0x800000){
--- a/snd.c
+++ b/snd.c
@@ -4,7 +4,6 @@
 #include "quakedef.h"
 #include "fns.h"
 
-cvar_t bgmvolume = {"bgmvolume", "1", 1};
 cvar_t volume = {"volume", "0.7", 1};
 
 typedef struct Chan Chan;
@@ -46,11 +45,6 @@
 
 static Sfx *ambsfx[Namb];
 
-static char cdfile[13];
-static int ntrk;
-static int cdfd = -1;
-static int cdread, cdloop, cdvol;
-
 typedef struct
 {
 	int 	length;
@@ -329,26 +323,19 @@
 	return sc;
 }
 
-void
-stepcd(void)
-{
-	cdvol = bgmvolume.value * 256;
-	cdread = cdfd >= 0 && cdvol > 0;
-}
-
 static void
 sndout(void)
 {
-	int v, vol, *pb, *pe;
+	int v, *pb, *pe;
 	uchar *p;
+	double vol;
 
-	vol = volume.value * 256;
+	vol = volume.value;
 	p = mixbuf;
 	pb = sampbuf;
 	pe = sampbuf + nsamp * 2;
 	while(pb < pe){
-		v = (short)(p[1] << 8 | p[0]) * cdvol >> 8;
-		v += *pb++ * vol >> 8;
+		v = *pb++ * vol;
 		if(v > 0x7fff)
 			v = 0x7fff;
 		else if(v < -0x8000)
@@ -439,25 +426,6 @@
 }
 
 static void
-readcd(int ns)
-{
-	int n;
-
-	if(cdfd < 0 || !cdread)
-		return;
-	if(n = readn(cdfd, mixbuf, ns), n != ns){
-		if(n < 0 || !cdloop)
-			stopcd();
-		else{
-			seek(cdfd, 0, 0);
-			ns -= n;
-			if(n = readn(cdfd, mixbuf+n, ns), n != ns)
-				stopcd();
-		}
-	}
-}
-
-static void
 spatialize(Chan *c)
 {
 	vec_t Δr, m;
@@ -568,8 +536,6 @@
 	if(nsamp > Ssamp)
 		nsamp = Ssamp;
 	ns = nsamp * Sblk;
-	memset(mixbuf, 0, ns);
-	readcd(ns);
 	samplesfx();
 	sampt += nsamp;
 	if(write(afd, mixbuf, ns) != ns){
@@ -580,46 +546,6 @@
 }
 
 void
-stopcd(void)
-{
-	if(cdfd >= 0)
-		close(cdfd);
-	cdread = 0;
-	cdloop = 0;
-}
-
-void
-pausecd(void)
-{
-	cdread = 0;
-}
-
-void
-resumecd(void)
-{
-	cdread = 1;
-}
-
-void
-startcd(int nt, int loop)
-{
-	if(ntrk < 1)
-		return;
-	nt -= 1;	/* d001 assumed part of track list */
-	if(nt < 1 || nt > ntrk){
-		fprint(2, "startcd: invalid track number %d\n", nt);
-		return;
-	}
-	if(cdfd = open(va("%s%03d", cdfile, nt), OREAD), cdfd < 0){
-		fprint(2, "startcd: open: %r\n");
-		return;
-	}
-	cdloop = loop;
-	if(cdvol > 0)
-		cdread = 1;
-}
-
-void
 stopallsfx(void)
 {
 	if(afd < 0)
@@ -796,33 +722,6 @@
 }
 
 static void
-cdcmd(void)
-{
-	char *c;
-
-	if(Cmd_Argc() < 2){
-usage:
-		Con_Printf("cd (play|loop|stop|pause|resume|info) [track]\n");
-		return;
-	}
-	c = Cmd_Argv(1);
-	if(cistrcmp(c, "play") == 0){
-		if(Cmd_Argc() < 2)
-			goto usage;
-		startcd(atoi(Cmd_Argv(2)), 0);
-	}else if(cistrcmp(c, "loop") == 0){
-		if(Cmd_Argc() < 2)
-			goto usage;
-		startcd(atoi(Cmd_Argv(2)), 1);
-	}else if(cistrcmp(c, "stop") == 0)
-		stopcd();
-	else if(cistrcmp(c, "pause") == 0)
-		pausecd();
-	else if(cistrcmp(c, "resume") == 0)
-		resumecd();
-}
-
-static void
 playsfx(void)
 {
 	static int hash = 345;
@@ -893,12 +792,6 @@
 }
 
 void
-shutcd(void)
-{
-	stopcd();
-}
-
-void
 shutsnd(void)
 {
 	if(afd < 0)
@@ -906,52 +799,7 @@
 	close(afd);
 }
 
-static int
-cdinfo(void)
-{
-	int fd, i, n, nt;
-	char *t, types[] = {'a', 'u', 0};
-	Dir *d;
-
-	ntrk = 0;
-	if(fd = open("/mnt/cd", OREAD), fd < 0)
-		return -1;
-	if(n = dirreadall(fd, &d), n < 0){
-		close(fd);
-		return -1;
-	}
-	close(fd);
-	t = types;
-	for(;;){
-		for(nt=0, i=0; i<n; i++)
-			if(strcmp(d[i].name, va("%c%03d", *t, ntrk+1)) == 0){
-				ntrk++;
-				nt = 1;
-			}
-		if(ntrk < 1){
-			if(*++t == 0){
-				werrstr("cdinfo: no tracks found");
-				break;
-			}
-		}else if(nt == 0){
-			snprint(cdfile, sizeof cdfile, "/mnt/cd/%c", *t);
-			break;
-		}
-	}
-	free(d);
-	return ntrk < 1 ? -1 : 0;
-}
-
 int
-initcd(void)
-{
-	if(cdinfo() < 0)
-		return -1;
-	Cmd_AddCommand("cd", cdcmd);
-	return 0;
-}
-
-int
 initsnd(void)
 {
 	int i, j, *p;
@@ -968,7 +816,6 @@
 	Cvar_RegisterVariable(&volume);
 	Cvar_RegisterVariable(&precache);
 	Cvar_RegisterVariable(&loadas8bit);
-	Cvar_RegisterVariable(&bgmvolume);
 	Cvar_RegisterVariable(&ambient_level);
 	Cvar_RegisterVariable(&ambient_fade);