shithub: cuefs

Download patch

ref: 5bcb2fe1d68844ca15df83fb205b94fb3873e227
parent: 3f6f039bf673f3ecaba6aa26abd3b89d363facfb
author: Tevo <estevan.cps@gmail.com>
date: Tue Dec 22 19:55:52 EST 2020

Many changes

Should've commited them separately, but changes include:
• debug messages
• open a fd per decoder
• more formats (kinda)
• file descriptors not exploding anymore
• spawning a decoder actually  works 
• seeking (somewhat)

--- a/cue.c
+++ b/cue.c
@@ -7,9 +7,10 @@
 Timestamp
 parsetime(int min, int sec, int frames)
 {
+	debug("parsing %d:%d:%d into ", min, sec, frames);
 	sec += min*60;
 	frames += sec*75;
-
+	debug("%d frames\n", frames);
 	return (Timestamp){frames};
 }
 
@@ -16,9 +17,18 @@
 double
 t2sec(Timestamp t)
 {
-	return (double)t.frames/75.0;
+	debug("returning %fs for %ud frames\n", t.frames/75.0, t.frames);
+	return t.frames/75.0;
 }
 
+double
+of2sec(uint rate, uint size, uint chans, vlong offset)
+{
+	int bs;
+	bs = (size/8)*chans;
+	return (double)offset/(double)bs/(double)rate;
+}
+
 Cuesheet*
 newsheet(void)
 {
@@ -51,8 +61,6 @@
 		return;
 	recfreefiles(s, cur->next);
 	maybefree(nil, cur->name);
-	if(cur->fd >= 0)
-		close(cur->fd);
 }
 
 void
@@ -135,7 +143,6 @@
 	new->type	= format;
 	new->actual	= actualformat(new);
 	new->next	= nil;
-	new->fd		= -1;
 
 	if(c->files == nil)
 		c->files = new;
@@ -172,6 +179,7 @@
 		parserfatal("timestamp outside of track");
 
 	atleast(c->curentry, i);
+	debug("setting timestamp[%d] for %d as %ud frames\n", i, c->curentry->index, t.frames);
 	c->curentry->starts[i] = t;
 }
 
@@ -206,18 +214,28 @@
 }
 
 char*
-formatext(AFile *f)
+formatext(int f)
 {
 	char *tab[] =
 	{
+		[WAVE]		= "wav",
 		[MP3]		= "mp3",
 		[AIFF]		= "aiff",
 		[BINARY]	= "bin",
+		[FLAC]		= "flac",
+		[OGG]		= "ogg",
+		[OPUS]		= "opus",
 		[MOTOROLA]	= ""		/* not sure */
 	};
 
-	if(f->type != WAVE)
-		return tab[f->type];
+	return tab[f];
+}
+
+char*
+fileext(AFile *f)
+{
+	if(f->actual != UNKNOWN)
+		return formatext(f->actual);
 
 	return extension(f->name);
 }
--- a/cuefs.h
+++ b/cuefs.h
@@ -15,9 +15,17 @@
 char* setstr(char*, char**, char*);
 char* strreplace(char*, char, char);
 
+#pragma varargk argpos parserwarn 1
+#pragma varargk argpos parserfatal 1
+#pragma varargk argpos debug 1
+
 void parserwarn(char*, ...);
 void parserfatal(char*, ...);
 
+void debug(char*, ...);
+
+extern int verbosity;
+
 /*****/
 
 enum
@@ -24,7 +32,7 @@
 {
 	WAVE, MP3, AIFF, BINARY, MOTOROLA,
 	/**/
-	FLAC, UNKNOWN
+	FLAC, OGG, OPUS, UNKNOWN
 };
 
 typedef struct
@@ -34,7 +42,7 @@
 
 typedef struct AFile
 {
-	int type, actual, fd;
+	int type, actual;
 	struct AFile *next;
 	char *name;
 } AFile;
@@ -65,6 +73,7 @@
 
 Timestamp parsetime(int, int, int);
 double t2sec(Timestamp);
+double of2sec(uint, uint, uint, vlong);
 
 Cuesheet* newsheet(void);
 void freesheet(Cuesheet*);
@@ -75,7 +84,8 @@
 void addnewtrack(Cuesheet*, int);
 void settimestamp(Cuesheet*, int, Timestamp);
 
-char* formatext(AFile*);
+char* formatext(int);
+char* fileext(AFile*);
 int actualformat(AFile*);
 
 static char *Estub = "not yet";
--- a/fs.c
+++ b/fs.c
@@ -6,16 +6,18 @@
 
 #include "cuefs.h"
 
-typedef struct {
+typedef struct
+{
 	Cuesheet* sheet;
 	int outfmt;
 } Fsprops;
 
-void wavserve(Entry*, Req*);
+void pcmserve(Entry*, Req*);
 
 void (*servefmt[])(Entry*, Req*) =
 {
-	[WAVE]	= wavserve,
+//	[WAVE]		= wavserve,
+	[BINARY]	= pcmserve,
 
 	[UNKNOWN] = nil
 };
@@ -24,34 +26,38 @@
 {
 	[MP3]	= "audio/mp3dec",
 	[FLAC]	= "audio/flacdec",
-	[WAVE]	= "audio/wavedec"
+	[WAVE]	= "audio/wavdec"
 };
 
 int
-pipedec(AFile *f, Timestamp t)
+pipedec(AFile *f, double sec)
 {
-	int fd[2];
-	double sec;
+	int fd[2], afd;
 	char *dec;
 
 	dec = decoder[f->actual];
-	sec = t2sec(t);
 
+	debug("decoding %s starting at %f\n", f->name, sec);
+
 	if(pipe(fd) < 0)
 		sysfatal("pipedec: can't decode: pipe: %r");
 
-	switch(rfork(RFFDG|RFPROC|RFMEM|RFNAMEG|RFNOTEG|RFREND))
+	switch(rfork(RFPROC|RFFDG|RFREND|RFNOTEG))
 	{
 	case 0:
-		close(0);
-		close(1);
-		dup(f->fd, 0);
+		if((afd = open(f->name, OREAD)) < 0)
+			sysfatal("pipedec: can't decode: open: %r");
+		dup(afd, 0);
 		dup(fd[1], 1);
-		close(f->fd);
+		close(afd);
 		close(fd[1]);
-		dec = strdup(dec);
+		seek(0, 0, 0);
 		{
-			char *argv[] = { dec };
+			char *argv[] = { dec, "-s", smprint("%f", sec), nil };
+ 			debug("command line: ");
+			for(char **a = argv; *a != nil; a++)
+				debug("'%s' ", *a);
+			debug("\n");
 			if(argv[2] == nil)
 				sysfatal("pipedec: can't decode: smprint: %r");
 			exec(dec, argv);
@@ -65,17 +71,23 @@
 	case -1:
 		sysfatal("pipedec: can't decode: rfork: %r");
 	}
+	close(fd[1]);
 	return fd[0];
 }
 
 void
-wavserve(Entry *e, Req *r)
+pcmserve(Entry *e, Req *r)
 {
+	double sec;
 	int dec;
 
-	dec = pipedec(e->file, e->starts[0]);
-	r->ofcall.count = readn(dec, r->ofcall.data, r->ifcall.count);
-	respond(r, Estub);
+	sec  = t2sec(e->starts[0]);
+	sec += of2sec(44100, 16, 2, r->ifcall.offset);
+
+	dec = pipedec(e->file, sec);
+	r->ofcall.count = read(dec, r->ofcall.data, r->ifcall.count);
+	close(dec);
+	respond(r, nil);
 }
 
 void
@@ -127,18 +139,15 @@
 
 	p = emalloc(sizeof(*p));
 	p->sheet  = sheet;
-	p->outfmt = WAVE;	/* STUB */
+	p->outfmt = BINARY;	/* STUB */
 
 	fs.aux	= p;
 	fs.tree	= alloctree(nil, nil, DMDIR | 0444, nil);
 
-	for(AFile *f = sheet->files; f != nil; f = f->next)
-		if(f->fd = open(f->name, OREAD) < 0)
-			sysfatal("open: %r");
-
 	for(Entry *e = sheet->entries; e != nil; e = e->next)
 	{
-		s = smprint("%02d - %s.%s", e->index, e->title, formatext(e->file));
+		debug("%d: %d\n",  e->index, e->starts[0].frames);
+		s = smprint("%02d - %s.%s", e->index, e->title, formatext(p->outfmt));
 		strreplace(s, '/', '-');
 		createfile(fs.tree->root, s, nil, 0444, e);
 		free(s);
--- a/main.c
+++ b/main.c
@@ -25,6 +25,9 @@
 	case 'm':
 		mtpt = EARGF(usage());
 		break;
+	case 'v':
+		verbosity++;
+		break;
 	default:
 		usage();
 	} ARGEND;
@@ -42,7 +45,8 @@
 	cursheet = newsheet();
 	yyparse();
 
-	close(infd);
+	if(infd != 0)
+		close(infd);
 
 	cuefsinit(cursheet, mtpt);
 
--- a/misc.c
+++ b/misc.c
@@ -4,6 +4,8 @@
 #include "cuefs.h"
 #include "y.tab.h"
 
+int verbosity = 0;
+
 void*
 erealloc(void *p, ulong s)
 {
@@ -84,4 +86,17 @@
 	free(str);
 	va_end(args);
 	exits("cantparse");
+}
+
+void
+debug(char *fmt, ...)
+{
+	va_list args;
+
+	if(verbosity < 3)
+		return;
+
+	va_start(args, fmt);
+	vfprint(2, fmt, args);
+	va_end(args);
 }