aux/cddb: Provide -e option to print commands to rip audio with tags.

Also parse title/track artist and year.
This commit is contained in:
Jacob Moody 2021-07-17 18:56:11 +00:00
parent 2204634275
commit be36c092ac
2 changed files with 80 additions and 20 deletions

View file

@ -19,6 +19,9 @@ cdfs, cddb \- optical disc (CD, DVD, BD) track reader and writer file system
] [ ] [
.B -s .B -s
.I server .I server
] [
.B -e
.I dir
] ]
.B query .B query
.I diskid .I diskid
@ -175,7 +178,7 @@ reading and writing speeds.
Additional lines may further describe the current disc. Additional lines may further describe the current disc.
.PP .PP
.I Aux/cddb .I Aux/cddb
takes 4 optional arguments. takes 5 optional arguments.
The The
.B -s .B -s
option makes option makes
@ -183,7 +186,7 @@ option makes
use use
.I server .I server
for the query instead of for the query instead of
.LR freedb.freedb.org . .LR gnudb.org .
The The
.B -D .B -D
option causes the raw database response from the server to be dumped option causes the raw database response from the server to be dumped
@ -195,6 +198,12 @@ option causes the time of each track to be appended to the normal output.
is like is like
.B -t .B -t
but prints a final line with the total time. but prints a final line with the total time.
The
.B -e
option will print rc commands using
.IR audio/flacenc (1)
to encode and tag audio tracks from the disc to output directory
.I dir .
.SH EXAMPLES .SH EXAMPLES
Backup to a BD-R disc: Backup to a BD-R disc:
.br .br

View file

@ -9,11 +9,13 @@ int debug;
#define DPRINT if(debug)fprint #define DPRINT if(debug)fprint
int tflag; int tflag;
int Tflag; int Tflag;
char *eflag;
typedef struct Track Track; typedef struct Track Track;
struct Track { struct Track {
int n; int n;
char *title; char *title;
char *artist;
}; };
enum { enum {
@ -25,6 +27,8 @@ struct Toc {
ulong diskid; ulong diskid;
int ntrack; int ntrack;
char *title; char *title;
char *year;
char *artist;
Track track[MTRACK]; Track track[MTRACK];
}; };
@ -55,17 +59,23 @@ dumpcddb(Toc *t)
{ {
int i, n, s; int i, n, s;
print("title %s\n", t->title); print("title\t%s\n", t->title);
if(t->year[0] != 0)
print("year\t%s\n", t->year);
if(t->artist[0] != 0)
print("artist\t%s\n", t->artist);
for(i=0; i<t->ntrack; i++){ for(i=0; i<t->ntrack; i++){
print("%d\t%s", i+1, t->track[i].title);
if(tflag){ if(tflag){
n = t->track[i+1].n; n = t->track[i+1].n;
if(i == t->ntrack-1) if(i == t->ntrack-1)
n *= 75; n *= 75;
s = (n - t->track[i].n)/75; s = (n - t->track[i].n)/75;
print("%d\t%s\t%d:%2.2d\n", i+1, t->track[i].title, s/60, s%60); print("\t%d:%2.2d", s/60, s%60);
} }
else if(t->track[i].artist[0] != 0)
print("%d\t%s\n", i+1, t->track[i].title); print("\t%s", t->track[i].artist);
print("\n");
} }
if(Tflag){ if(Tflag){
s = t->track[i].n; s = t->track[i].n;
@ -73,15 +83,32 @@ dumpcddb(Toc *t)
} }
} }
char* static void
append(char *a, char *b) dumpencode(Toc *t)
{ {
char *c; int i;
c = emalloc(strlen(a)+strlen(b)+1); quotefmtinstall();
strcpy(c, a); for(i=0; i < t->ntrack; i++){
strcat(c, b); print("</mnt/cd/a%03d audio/flacenc ", i);
return c; print("-T 'title='^%q -T 'trackno=%d' ", t->track[i].title, i+1);
if(t->year[0] != 0)
print("-T 'year='^%q ", t->year);
if(t->track[i].artist[0] != 0 || t->artist[0] != 0)
print("-T 'artist='^%q ", t->track[i].artist[0] != 0 ? t->track[i].artist : t->artist);
print(">%q/a%03d.flac\n", eflag, i);
}
}
static char*
split(char *s)
{
char *p;
if((p = strchr(s, '/')) == nil)
return nil;
p[-1] = 0;
return p+2;
} }
static int static int
@ -89,7 +116,7 @@ cddbfilltoc(Toc *t)
{ {
int fd; int fd;
int i; int i;
char *p, *q; char *p, *q, *a;
Biobuf bin; Biobuf bin;
char *f[10]; char *f[10];
int nf; int nf;
@ -183,8 +210,12 @@ cddbfilltoc(Toc *t)
} }
t->title = ""; t->title = "";
for(i=0; i<t->ntrack; i++) t->artist = "";
t->year = "";
for(i=0; i<t->ntrack; i++) {
t->track[i].title = ""; t->track[i].title = "";
t->track[i].artist = "";
}
/* fetch results for this cd */ /* fetch results for this cd */
fprint(fd, "cddb read %s %s\r\n", categ, id); fprint(fd, "cddb read %s %s\r\n", categ, id);
@ -195,8 +226,18 @@ cddbfilltoc(Toc *t)
while(isspace(*q)) while(isspace(*q))
*q-- = 0; *q-- = 0;
DPRINT(2, "cddb %s\n", p); DPRINT(2, "cddb %s\n", p);
if(strncmp(p, "DTITLE=", 7) == 0) if(strncmp(p, "DTITLE=", 7) == 0) {
t->title = append(t->title, p+7); p += 7;
a = split(p);
if(a != nil) {
t->artist = estrdup(p);
p = a;
}
t->title = estrdup(p);
}
else if(strncmp(p, "DYEAR=", 6) == 0) {
t->year = estrdup(p+6);
}
else if(strncmp(p, "TTITLE", 6) == 0 && isdigit(p[6])) { else if(strncmp(p, "TTITLE", 6) == 0 && isdigit(p[6])) {
i = atoi(p+6); i = atoi(p+6);
if(i < t->ntrack) { if(i < t->ntrack) {
@ -205,8 +246,12 @@ DPRINT(2, "cddb %s\n", p);
p++; p++;
if(*p == '=') if(*p == '=')
p++; p++;
a = split(p);
t->track[i].title = append(t->track[i].title, estrdup(p)); if(a != nil) {
t->track[i].artist = estrdup(p);
p = a;
}
t->track[i].title = estrdup(p);
} }
} }
} while(*p != '.'); } while(*p != '.');
@ -238,6 +283,9 @@ main(int argc, char **argv)
case 's': case 's':
server = EARGF(usage()); server = EARGF(usage());
break; break;
case 'e':
eflag = EARGF(usage());
break;
case 'T': case 'T':
Tflag = 1; Tflag = 1;
/*FALLTHROUGH*/ /*FALLTHROUGH*/
@ -260,6 +308,9 @@ main(int argc, char **argv)
if(cddbfilltoc(&toc) < 0) if(cddbfilltoc(&toc) < 0)
exits("whoops"); exits("whoops");
dumpcddb(&toc); if(eflag != nil)
dumpencode(&toc);
else
dumpcddb(&toc);
exits(nil); exits(nil);
} }