shithub: cuefs

Download patch

ref: 34b8565a804d8f43da7a22eba580300a9b5db4e6
parent: 6bd9dbecc52670bb62de1154415df8872cc3fc3b
author: Tevo <estevan.cps@gmail.com>
date: Sat Dec 26 18:42:50 EST 2020

Broken wavserve prototype

--- a/BUGS
+++ b/BUGS
@@ -4,3 +4,4 @@
 • can only serve .wav and raw pcm files (no flac encoder)
 • everything will get resampled to 44100kHz/16bit/2channel
 • the codebase is a mess
+• reading concurrently from the same fid might break decoding logic, or be unecessarily slow (does that ever happen?)
--- a/cue.c
+++ b/cue.c
@@ -45,6 +45,7 @@
 {
 	Entry *e;
 	AFile *f;
+	Start *st;
 
 	/* free entries */
 	while((e = s->entries) != nil)
@@ -52,7 +53,7 @@
 		s->entries = e->next;
 
 		/* free starts */
-		for(Start *st = e->starts; st != nil; st = e->starts)
+		while((st = e->starts) != nil)
 		{
 			e->starts = st->next;
 			free(st);
--- a/fs.c
+++ b/fs.c
@@ -18,11 +18,35 @@
 	vlong curoff, end;
 } Decoder;
 
+/* from http://soundfile.sapp.org/doc/WaveFormat/ */
+
+/* TODO maybe this should be packed on some architectures? */
+typedef struct
+{
+		/* RIFF header */
+	u32int id;			/* BE */	/* RIFF */
+	u32int size;		/* LE */
+	u32int fmt;			/* BE */	/* WAVE */
+		/* fmt section */
+	u32int fmtid;		/* BE */	/* fmt  */
+	u32int fmtsize;		/* LE */
+	u16int format;		/* LE */
+	u16int chans;		/* LE */
+	u32int srate;		/* LE */
+	u32int brate;		/* LE */
+	u16int ballign;		/* LE */
+	u16int ssize;		/* LE */
+		/* data section */
+	u32int dataid;		/* BE */	/* data */
+	u32int datasize;	/* LE */
+} Wavehdr;
+
 void pcmserve(Entry*, Req*);
+void wavserve(Entry*, Req*);
 
 void (*servefmt[])(Entry*, Req*) =
 {
-//	[WAVE]		= wavserve,
+	[WAVE]		= wavserve,
 	[BINARY]	= pcmserve,
 
 	[UNKNOWN] = nil
@@ -30,9 +54,11 @@
 
 char *decoder[] =
 {
+	[OGG]	= "audio/oggdec",
 	[MP3]	= "audio/mp3dec",
+	[OPUS]	= "audio/opusdec",	/* might not exist */
 	[FLAC]	= "audio/flacdec",
-	[WAVE]	= "audio/wavdec"
+	[WAVE]	= "audio/wavdec",
 };
 
 /* 
@@ -159,7 +185,83 @@
 	respond(r, nil);
 }
 
+u32int
+s2i(char *s)
+{
+	return (s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]);
+}
+
 void
+fillwavehdr(Wavehdr *hdr, u16int chans, u32int srate, u16int ssize, u32int dsize)
+{
+	hdr->id		= s2i("RIFF");
+	hdr->size	= 36 + dsize;
+	hdr->fmt	= s2i("WAVE");
+
+	hdr->fmtid		= s2i("fmt ");
+	hdr->fmtsize	= 16;
+	hdr->format		= 1;	/* raw pcm */
+	hdr->chans		= chans;
+	hdr->srate		= srate;
+	hdr->brate		= srate * chans * ssize/8;
+	hdr->ssize		= ssize;
+
+	hdr->dataid		= s2i("data");
+	hdr->datasize	= dsize;
+}
+
+void
+wavserve(Entry *e, Req *r)
+{
+	Wavehdr hdr;
+	Decoder *dec;
+	double sec;
+	ulong end, offset, count, hcount;
+
+	offset = r->ifcall.offset;
+	count = r->ifcall.count;
+
+	debug("wavserve: offset → %lu, count → %lu\n", offset, count);
+
+	/* 44 == start of pcm data */
+	if(offset < 44)
+	{
+		hcount = 44 - offset;
+		count -= hcount;
+		offset = 0;
+		debug("wavserve: serving %lu bytes of wav header\n", hcount);
+		fillwavehdr(hdr, 2, 44100, 16, count);
+		memcpy(r->ofcall.data, hdr, hcount);
+	}
+
+	if(count == 0)
+	{
+		respond(r, nil);
+		return;
+	}
+
+	debug("wavserve: %lu to go\n", count);
+
+	sec = t2sec(e->starts[0]) + of2sec(44100, 16, 2, offset);
+
+	/*
+	 * see comment on pcmserve
+	 */
+	if((dec = r->fid->aux) == nil || dec->curoff != offset)
+	{
+		/* amount of samples between songs... */
+		end = (e->next->starts->frames - e->starts->frames) * (44100/75);
+		/* ...*2 channels, 2 bytes per sample */
+		end *= 2*2;
+		closedec(dec);
+		dec = r->fid->aux = pipedec(e->file, sec, offset, end);
+	}
+
+	r->ofcall.count = readdec(dec, r->ofcall.data, count);
+	respond(r, nil);
+}
+
+void
 fsopen(Req *r)
 {
 	respond(r, nil);
@@ -216,7 +318,7 @@
 
 	p = emalloc(sizeof(*p));
 	p->sheet  = sheet;
-	p->outfmt = BINARY;	/* STUB */
+	p->outfmt = WAVE;	/* STUB */
 
 	fs.aux	= p;
 	fs.tree	= alloctree(nil, nil, DMDIR | 0444, nil);