shithub: cuefs

Download patch

ref: 3f6f039bf673f3ecaba6aa26abd3b89d363facfb
parent: 82b09422d20fadb595f0bde7d388441047944255
author: Tevo <estevan.cps@gmail.com>
date: Mon Nov 23 19:17:03 EST 2020

Filesystem progress (currently broken)

--- a/cue.c
+++ b/cue.c
@@ -13,6 +13,12 @@
 	return (Timestamp){frames};
 }
 
+double
+t2sec(Timestamp t)
+{
+	return (double)t.frames/75.0;
+}
+
 Cuesheet*
 newsheet(void)
 {
@@ -45,6 +51,8 @@
 		return;
 	recfreefiles(s, cur->next);
 	maybefree(nil, cur->name);
+	if(cur->fd >= 0)
+		close(cur->fd);
 }
 
 void
@@ -123,9 +131,11 @@
 	lastfile(c);
 
 	new = emalloc(sizeof(*new));
-	new->name = strdup(name);
-	new->type = format;
-	new->next = nil;
+	new->name	= strdup(name);
+	new->type	= format;
+	new->actual	= actualformat(new);
+	new->next	= nil;
+	new->fd		= -1;
 
 	if(c->files == nil)
 		c->files = new;
@@ -166,6 +176,36 @@
 }
 
 char*
+extension(char *f)
+{
+	char *ext = "";
+
+	for(char *c = f; *c != 0; c++)
+		if(*c == '.')
+			ext = c+1;
+
+	return ext;
+}
+
+int
+actualformat(AFile *f)
+{
+	char *ext;
+
+	if(f->type != WAVE)
+		return f->type;
+
+	ext = extension(f->name);
+
+	if(strcmp(ext, "wav") == 0)
+		return WAVE;
+	if(strcmp(ext, "flac") == 0 || strcmp(ext, "fla") == 0)
+		return FLAC;
+
+	return UNKNOWN;
+}
+
+char*
 formatext(AFile *f)
 {
 	char *tab[] =
@@ -172,7 +212,7 @@
 	{
 		[MP3]		= "mp3",
 		[AIFF]		= "aiff",
-		[BINARY]	= "pcm",
+		[BINARY]	= "bin",
 		[MOTOROLA]	= ""		/* not sure */
 	};
 
@@ -179,5 +219,5 @@
 	if(f->type != WAVE)
 		return tab[f->type];
 
-	return "wav";	/* FIXME */
+	return extension(f->name);
 }
--- a/cue.l
+++ b/cue.l
@@ -5,7 +5,7 @@
 %}
 
 %%
-\".*\"		{
+\".*\"			{
 					yylval.str = strdup(yytext+1);
 
 					if(yylval.str[yyleng-2] != '"')
--- a/cue.y
+++ b/cue.y
@@ -4,6 +4,8 @@
 
 #include "cuefs.h"
 
+Cuesheet *cursheet;
+
 /*
  * FIXME find a way to "fix" the grammar so that it
  * doesn't do right-hand recursion (and overflow the
--- a/cuefs.h
+++ b/cuefs.h
@@ -13,6 +13,7 @@
 void* emalloc(ulong);
 
 char* setstr(char*, char**, char*);
+char* strreplace(char*, char, char);
 
 void parserwarn(char*, ...);
 void parserfatal(char*, ...);
@@ -21,7 +22,9 @@
 
 enum
 {
-	WAVE, MP3, AIFF, BINARY, MOTOROLA
+	WAVE, MP3, AIFF, BINARY, MOTOROLA,
+	/**/
+	FLAC, UNKNOWN
 };
 
 typedef struct
@@ -31,15 +34,15 @@
 
 typedef struct AFile
 {
-	char *name;
-	int type;
+	int type, actual, fd;
 	struct AFile *next;
+	char *name;
 } AFile;
 
 typedef struct
 {
-	u8int maxindex;
 	Timestamp *starts;
+	u8int maxindex;
 } Timestamps;
 
 typedef struct Entry
@@ -61,6 +64,7 @@
 extern Cuesheet *cursheet;
 
 Timestamp parsetime(int, int, int);
+double t2sec(Timestamp);
 
 Cuesheet* newsheet(void);
 void freesheet(Cuesheet*);
@@ -72,5 +76,9 @@
 void settimestamp(Cuesheet*, int, Timestamp);
 
 char* formatext(AFile*);
+int actualformat(AFile*);
+
+static char *Estub = "not yet";
+static char *Eunsupported = "unsupported format";
 
 void cuefsinit(Cuesheet*, char*);
--- a/fs.c
+++ b/fs.c
@@ -5,13 +5,80 @@
 #include <9p.h>
 
 #include "cuefs.h"
-#include "y.tab.h"
 
-char *Estub = "not yet";
+typedef struct {
+	Cuesheet* sheet;
+	int outfmt;
+} Fsprops;
 
-Cuesheet *cursheet;
+void wavserve(Entry*, Req*);
 
+void (*servefmt[])(Entry*, Req*) =
+{
+	[WAVE]	= wavserve,
+
+	[UNKNOWN] = nil
+};
+
+char *decoder[] =
+{
+	[MP3]	= "audio/mp3dec",
+	[FLAC]	= "audio/flacdec",
+	[WAVE]	= "audio/wavedec"
+};
+
+int
+pipedec(AFile *f, Timestamp t)
+{
+	int fd[2];
+	double sec;
+	char *dec;
+
+	dec = decoder[f->actual];
+	sec = t2sec(t);
+
+	if(pipe(fd) < 0)
+		sysfatal("pipedec: can't decode: pipe: %r");
+
+	switch(rfork(RFFDG|RFPROC|RFMEM|RFNAMEG|RFNOTEG|RFREND))
+	{
+	case 0:
+		close(0);
+		close(1);
+		dup(f->fd, 0);
+		dup(fd[1], 1);
+		close(f->fd);
+		close(fd[1]);
+		dec = strdup(dec);
+		{
+			char *argv[] = { dec };
+			if(argv[2] == nil)
+				sysfatal("pipedec: can't decode: smprint: %r");
+			exec(dec, argv);
+			dec = smprint("/bin/%s", dec);
+			if(dec == nil)
+				sysfatal("pipedec: can't decode: smprint: %r");
+			exec(dec, argv);
+			sysfatal("pipedec: can't decode: exec: %r");
+		}
+		break;
+	case -1:
+		sysfatal("pipedec: can't decode: rfork: %r");
+	}
+	return fd[0];
+}
+
 void
+wavserve(Entry *e, Req *r)
+{
+	int dec;
+
+	dec = pipedec(e->file, e->starts[0]);
+	r->ofcall.count = readn(dec, r->ofcall.data, r->ifcall.count);
+	respond(r, Estub);
+}
+
+void
 fsopen(Req *r)
 {
 	respond(r, nil);
@@ -20,13 +87,28 @@
 void
 fsread(Req *r)
 {
-	respond(r, Estub);
+	void (*func)(Entry*, Req*);
+	extern Srv fs;
+	Fsprops *p;
+
+	p = fs.aux;
+
+	func = servefmt[p->outfmt];
+
+	if(func != nil)
+		func(r->fid->file->aux, r);
+	else
+		respond(r, Eunsupported);
 }
 
 void
 fsend(Srv *s)
 {
-	freesheet(s->aux);
+	Fsprops *p;
+
+	p = s->aux;
+	freesheet(p->sheet);
+	free(p);
 }
 
 Srv fs =
@@ -40,14 +122,24 @@
 void
 cuefsinit(Cuesheet *sheet, char *mtpt)
 {
+	Fsprops *p;
 	char *s;
 
-	fs.aux	= sheet;
+	p = emalloc(sizeof(*p));
+	p->sheet  = sheet;
+	p->outfmt = WAVE;	/* 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));
+		strreplace(s, '/', '-');
 		createfile(fs.tree->root, s, nil, 0444, e);
 		free(s);
 	}
--- a/main.c
+++ b/main.c
@@ -35,7 +35,8 @@
 	if(argc == 1)
 	{
 		fname = argv[0];
-		infd = open(fname, OREAD);
+		if((infd = open(fname, OREAD)) < 0)
+			sysfatal("open: %r");
 	}
 
 	cursheet = newsheet();
--- a/misc.c
+++ b/misc.c
@@ -50,6 +50,15 @@
 	return str;
 }
 
+char*
+strreplace(char *str, char a, char b)
+{
+	for(char *c = str; *c != 0; c++)
+		if(*c == a)
+			*c = b;
+	return str;
+}
+
 void
 parserwarn(char *fmt, ...)
 {
--- a/mkfile
+++ b/mkfile
@@ -7,7 +7,8 @@
 	cue.y
 
 HFILES=\
-	cuefs.h
+	cuefs.h		\
+	y.tab.h
 
 OFILES=\
 	lex.yy.$O	\
@@ -17,6 +18,6 @@
 	cue.$O		\
 	fs.$O
 
-LFLAGS=-9
-
 </sys/src/cmd/mkone
+
+LFLAGS=-9