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);