ref: 448e84898530e6f597db845c72ea66e372374558
parent: 5bcb2fe1d68844ca15df83fb205b94fb3873e227
author: Tevo <estevan.cps@gmail.com>
date: Tue Dec 22 22:30:33 EST 2020
Use a decoder instance per Fid
--- a/cue.y
+++ b/cue.y
@@ -6,12 +6,7 @@
Cuesheet *cursheet;
-/*
- * FIXME find a way to "fix" the grammar so that it
- * doesn't do right-hand recursion (and overflow the
- * stack) instead of just growing it and pretending
- * it's not a problem
- */
+/* maybe it doesn't matter */
#define YYMAXDEPTH 8192
%}
--- a/fs.c
+++ b/fs.c
@@ -12,6 +12,12 @@
int outfmt;
} Fsprops;
+typedef struct
+{
+ int fd, pid;
+ vlong curoff;
+} Decoder;
+
void pcmserve(Entry*, Req*);
void (*servefmt[])(Entry*, Req*) =
@@ -29,9 +35,10 @@
[WAVE] = "audio/wavdec"
};
-int
-pipedec(AFile *f, double sec)
+Decoder*
+pipedec(AFile *f, double sec, vlong off)
{
+ Decoder *ret;
int fd[2], afd;
char *dec;
@@ -42,7 +49,11 @@
if(pipe(fd) < 0)
sysfatal("pipedec: can't decode: pipe: %r");
- switch(rfork(RFPROC|RFFDG|RFREND|RFNOTEG))
+ ret = emalloc(sizeof(*ret));
+ ret->fd = fd[0];
+ ret->curoff = off;
+
+ switch(ret->pid = rfork(RFPROC|RFFDG|RFREND|RFNOTEG))
{
case 0:
if((afd = open(f->name, OREAD)) < 0)
@@ -72,21 +83,56 @@
sysfatal("pipedec: can't decode: rfork: %r");
}
close(fd[1]);
- return fd[0];
+ return ret;
}
void
+closedec(Decoder *dec)
+{
+ char *path;
+ int fd;
+
+ if(dec == nil)
+ return;
+
+ close(dec->fd);
+
+ if((path = smprint("/proc/%d/notepg", dec->pid)) == nil)
+ sysfatal("smprint: %r");
+ if((fd = open(path, OWRITE)) < 0)
+ sysfatal("open: %r");
+ write(fd, "kill", strlen("kill"));
+ close(fd);
+
+ free(dec);
+}
+
+long
+readdec(Decoder *dec, void *buf, long count)
+{
+ long ret;
+
+ ret = read(dec->fd, buf, count);
+ dec->curoff += ret;
+
+ return ret;
+}
+
+void
pcmserve(Entry *e, Req *r)
{
+ Decoder *dec;
double sec;
- int dec;
- sec = t2sec(e->starts[0]);
- sec += of2sec(44100, 16, 2, r->ifcall.offset);
+ sec = t2sec(e->starts[0]) + 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);
+ if((dec = r->fid->aux) == nil || dec->curoff != r->ifcall.offset)
+ {
+ closedec(dec);
+ dec = r->fid->aux = pipedec(e->file, sec, r->ifcall.offset);
+ }
+
+ r->ofcall.count = readdec(dec, r->ofcall.data, r->ifcall.count);
respond(r, nil);
}
@@ -97,6 +143,13 @@
}
void
+fsclose(Fid *fid)
+{
+ if(fid->aux != nil)
+ closedec(fid->aux);
+}
+
+void
fsread(Req *r)
{
void (*func)(Entry*, Req*);
@@ -125,10 +178,11 @@
Srv fs =
{
- .open = fsopen,
- .read = fsread,
+ .open = fsopen,
+ .read = fsread,
+ .destroyfid = fsclose,
- .end = fsend
+ .end = fsend
};
void
@@ -147,6 +201,7 @@
for(Entry *e = sheet->entries; e != nil; e = e->next)
{
debug("%d: %d\n", e->index, e->starts[0].frames);
+ /* TODO make the format customizable */
s = smprint("%02d - %s.%s", e->index, e->title, formatext(p->outfmt));
strreplace(s, '/', '-');
createfile(fs.tree->root, s, nil, 0444, e);