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);
}