shithub: libtags

Download patch

ref: 2bb82e2c7a462e42d66ec78b7a50e2575f62f0a3
parent: 48c67225f53b4dc58ad5862b183bab41376c6a5c
author: Sigrid Solveig Haflínudóttir <[email protected]>
date: Mon Nov 2 03:23:57 EST 2020

add WAV support

--- a/README.md
+++ b/README.md
@@ -12,6 +12,7 @@
 | FLAC           | yes             | no               | yes              |
 | m4a            | yes             | no               | yes              |
 | opus           | yes             | no               | yes              |
+| WAV            | yes             | no               | yes              |
 | replay gain    | yes             | no               | ???              |
 | size           | tiny            | bloated          | more bloated     |
 | license        | MIT             | LGPL             | LGPL/MPL         |
--- a/flac.c
+++ b/flac.c
@@ -2,8 +2,6 @@
 #include "tagspriv.h"
 
 #define beu3(d)   ((d)[0]<<16 | (d)[1]<<8  | (d)[2]<<0)
-#define beuint(d) (uint)((d)[0]<<24 | (d)[1]<<16 | (d)[2]<<8 | (d)[3]<<0)
-#define leuint(d) (uint)((d)[3]<<24 | (d)[2]<<16 | (d)[1]<<8 | (d)[0]<<0)
 
 int
 tagflac(Tagctx *ctx)
--- a/id3v2.c
+++ b/id3v2.c
@@ -12,7 +12,6 @@
 #include "tagspriv.h"
 
 #define synchsafe(d) (uint)(((d)[0]&127)<<21 | ((d)[1]&127)<<14 | ((d)[2]&127)<<7 | ((d)[3]&127)<<0)
-#define beuint(d) (uint)((d)[0]<<24 | (d)[1]<<16 | (d)[2]<<8 | (d)[3]<<0)
 
 static int
 v2cb(Tagctx *ctx, char *k, char *v)
--- a/m4a.c
+++ b/m4a.c
@@ -2,7 +2,6 @@
 /* https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html */
 #include "tagspriv.h"
 
-#define beuint(d) (uint)((d)[0]<<24 | (d)[1]<<16 | (d)[2]<<8 | (d)[3]<<0)
 #define beuint16(d) (ushort)((d)[0]<<8 | (d)[1]<<0)
 
 int
--- a/mkfile
+++ b/mkfile
@@ -12,6 +12,7 @@
 	tags.$O\
 	utf16.$O\
 	vorbis.$O\
+	wav.$O\
 
 HFILES=\
 	/sys/include/tags.h\
--- a/opus.c
+++ b/opus.c
@@ -1,7 +1,5 @@
 #include "tagspriv.h"
 
-#define leuint(d) (uint)(((uchar*)(d))[3]<<24 | ((uchar*)(d))[2]<<16 | ((uchar*)(d))[1]<<8 | ((uchar*)(d))[0]<<0)
-
 int
 tagopus(Tagctx *ctx)
 {
--- a/tags.c
+++ b/tags.c
@@ -14,6 +14,7 @@
 extern int tagid3v1(Tagctx *ctx);
 extern int tagm4a(Tagctx *ctx);
 extern int tagopus(Tagctx *ctx);
+extern int tagwav(Tagctx *ctx);
 
 static const Getter g[] =
 {
@@ -23,6 +24,7 @@
 	{tagflac, Fflac},
 	{tagm4a, Fm4a},
 	{tagopus, Fopus},
+	{tagwav, Fwav},
 };
 
 void
--- a/tags.h
+++ b/tags.h
@@ -31,6 +31,9 @@
 	Fflac,
 	Fm4a,
 	Fopus,
+	Fwav,
+
+	Fmax,
 };
 
 /* Tag parser context. You need to set it properly before parsing an audio file using libtags. */
--- a/tagspriv.h
+++ b/tagspriv.h
@@ -20,6 +20,9 @@
 	Numgenre = 192,
 };
 
+#define beuint(d) (uint)((d)[0]<<24 | (d)[1]<<16 | (d)[2]<<8 | (d)[3]<<0)
+#define leuint(d) (uint)((d)[3]<<24 | (d)[2]<<16 | (d)[1]<<8 | (d)[0]<<0)
+
 extern const char *id3genres[Numgenre];
 
 /*
--- a/vorbis.c
+++ b/vorbis.c
@@ -4,8 +4,6 @@
  */
 #include "tagspriv.h"
 
-#define leuint(d) (uint)(((uchar*)(d))[3]<<24 | ((uchar*)(d))[2]<<16 | ((uchar*)(d))[1]<<8 | ((uchar*)(d))[0]<<0)
-
 void
 cbvorbiscomment(Tagctx *ctx, char *k, char *v){
 	if(*v == 0)
--- /dev/null
+++ b/wav.c
@@ -1,0 +1,75 @@
+#include "tagspriv.h"
+
+#define le16u(d) (u16int)((d)[0] | (d)[1]<<8)
+
+int
+tagwav(Tagctx *ctx)
+{
+	uchar *d;
+	int i;
+	u32int sz, csz;
+
+	d = (uchar*)ctx->buf;
+
+	sz = 1;
+	for(i = 0; i < 8 && sz > 0; i++){
+		if(ctx->read(ctx, d, 4+4+(i?0:4)) != 4+4+(i?0:4))
+			return -1;
+		if(i == 0){
+			if(memcmp(d, "RIFF", 4) != 0 || memcmp(d+8, "WAVE", 4) != 0)
+				return -1;
+			if((sz = beuint(d+4)) < 4)
+				return -1;
+			sz -= 4;
+			continue;
+		}else if(memcmp(d, "INFO", 4) == 0){
+			ctx->seek(ctx, -4, 1);
+			continue;
+		}
+
+		sz -= 4+4;
+		csz = leuint(d+4);
+		if(csz > sz)
+			return -1;
+		sz -= csz;
+
+		if(i == 1){
+			if(memcmp(d, "fmt ", 4) != 0 || csz < 16)
+				return -1;
+			if(ctx->read(ctx, d, 16) != 16)
+				return -1;
+			csz -= 16;
+			ctx->channels = le16u(d+2);
+			ctx->samplerate = leuint(d+4);
+			ctx->duration = sz*1000 / leuint(d+8);
+		}else if(memcmp(d, "LIST", 4) == 0){
+			sz = csz - 4;
+			continue;
+		}else if(memcmp(d, "IART", 4) == 0){
+			if(ctx->read(ctx, d, csz) != csz)
+				return -1;
+			d[csz] = 0;
+			txtcb(ctx, Tartist, "", d);
+			csz = 1;
+		}else if(memcmp(d, "IPRD", 4) == 0){
+			if(ctx->read(ctx, d, csz) != csz)
+				return -1;
+			d[csz] = 0;
+			txtcb(ctx, Talbum, "", d);
+			csz = 1;
+		}else if(memcmp(d, "INAM", 4) == 0){
+			if(ctx->read(ctx, d, csz) != csz)
+				return -1;
+			d[csz] = 0;
+			txtcb(ctx, Ttitle, "", d);
+			csz = 1;
+		}else if(memcmp(d, "data", 4) == 0){
+			break;
+		}
+
+		if(ctx->seek(ctx, csz, 1) < 0)
+			return -1;
+	}
+
+	return i > 0 ? 0 : -1;
+}