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