code: plan9front

Download patch

ref: eaef2887f5787ec4740b9223589c94be64c5f061
parent: 2417e3f61def0443d8f75bcc5003a63e02fe880b
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Tue Aug 30 14:09:32 EDT 2022

libtags: try other formats after id3v2 is found

Even though a valid id3v2 tag header may be present, the file format
itself might not be mp3. Instead, retry other format parsers on the
file after seeking right past the id3v2 header. This fixes FLACs that
are ID3v2-tagged (the reasoning behind that is left with no comment).

Also convert "TLEN" into duration while at it.

--- a/sys/src/cmd/audio/libtags/flac.c
+++ b/sys/src/cmd/audio/libtags/flac.c
@@ -25,7 +25,7 @@
 	ctx->duration = g * 1000 / ctx->samplerate;
 
 	/* skip the rest of the stream info */
-	if(ctx->seek(ctx, sz-18, 1) != 8+sz)
+	if(ctx->seek(ctx, sz-18, 1) != ctx->restart+8+sz)
 		return -1;
 
 	for(last = 0; !last;){
--- a/sys/src/cmd/audio/libtags/id3v2.c
+++ b/sys/src/cmd/audio/libtags/id3v2.c
@@ -27,6 +27,8 @@
 		txtcb(ctx, Tdate, k-1, v);
 	else if(strcmp(k, "RK") == 0 || strcmp(k, "RCK") == 0)
 		txtcb(ctx, Ttrack, k-1, v);
+	else if(strcmp(k, "LEN") == 0)
+		ctx->duration = atoi(v);
 	else if(strcmp(k, "CO") == 0 || strcmp(k, "CON") == 0){
 		for(; v[0]; v++){
 			if(v[0] == '(' && v[1] <= '9' && v[1] >= '0'){
@@ -387,6 +389,8 @@
 
 	if(ver == 2 && (d[5] & (1<<6)) != 0) /* compression */
 		return -1;
+
+	ctx->restart = sizeof(d)+sz;
 
 	if(ver > 2){
 		if((d[5] & (1<<4)) != 0) /* footer */
--- a/sys/src/cmd/audio/libtags/tags.c
+++ b/sys/src/cmd/audio/libtags/tags.c
@@ -65,6 +65,7 @@
 	ctx->channels = ctx->samplerate = ctx->bitrate = ctx->duration = 0;
 	ctx->found = 0;
 	ctx->format = Funknown;
+	ctx->restart = 0;
 	res = -1;
 	for(i = 0; i < nelem(g); i++){
 		ctx->num = 0;
@@ -72,7 +73,7 @@
 			ctx->format = g[i].format;
 			res = 0;
 		}
-		ctx->seek(ctx, 0, 0);
+		ctx->seek(ctx, ctx->restart, 0);
 	}
 
 	return res;
--- a/sys/src/cmd/audio/libtags/tags.h
+++ b/sys/src/cmd/audio/libtags/tags.h
@@ -81,6 +81,7 @@
 	/* Private, don't touch. */
 	int found;
 	int num;
+	int restart;
 };
 
 /* Parse the file using this function. Returns 0 on success. */