ref: 63b1d8e124c602cf5bec357e1f04653a86e6af52
parent: 17e82bf4cde80c08cf38d331bf0715d38e50971d
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
date: Thu Dec 19 16:18:23 EST 2019
optional TOC handler
--- a/examples/readtags.c
+++ b/examples/readtags.c
@@ -38,7 +38,7 @@
};
static void
-cb(Tagctx *ctx, int t, const char *k, const char *v, int offset, int size, Tagread f)
+tag(Tagctx *ctx, int t, const char *k, const char *v, int offset, int size, Tagread f)
{
USED(ctx); USED(k); USED(f);
if(t == Timage)
@@ -47,6 +47,12 @@
print("%-12s %s\n", t2s[t], v);
}
+static void
+toc(Tagctx *ctx, int ms, int offset)
+{
+ USED(ctx); USED(ms); USED(offset);
+}
+
static int
ctxread(Tagctx *ctx, void *buf, int cnt)
{
@@ -71,7 +77,8 @@
{
.read = ctxread,
.seek = ctxseek,
- .tag = cb,
+ .tag = tag,
+ .toc = toc,
.buf = buf,
.bufsz = sizeof(buf),
.aux = &aux,
--- a/id3v2.c
+++ b/id3v2.c
@@ -294,10 +294,10 @@
static void
getduration(Tagctx *ctx, int offset)
{
- uvlong n, framelen, samplespf;
+ uvlong n, framelen, samplespf, toc;
uchar *b;
uint x;
- int xversion, xlayer, xbitrate;
+ int xversion, xlayer, xbitrate, i;
if(ctx->read(ctx, ctx->buf, 256) != 256)
return;
@@ -330,10 +330,23 @@
if(ctx->duration == 0 && framelen > 0)
ctx->duration = n * samplespf * 1000 / framelen / ctx->samplerate;
- if((x & 4) != 0){ /* TOC is set */
- /* not doing anything yet */
+ if((x & 4) != 0 && ctx->toc != nil){ /* TOC is set */
+ toc = offset + 100 + (char*)b - ctx->buf;
+ if((x & 8) != 0) /* VBR scale */
+ toc += 4;
+ for(i = 0; i < 100; i++){
+ /*
+ * offset = n * b[i] / 256
+ * ms = i * duration / 100
+ */
+ ctx->toc(ctx, i * ctx->duration / 100, toc + (n * b[i]) / 256);
+ }
+ b += 100;
+ if((x & 8) != 0) /* VBR scale */
+ b += 4;
}
}
+ offset += (char*)b - ctx->buf;
}else if(memcmp(&ctx->buf[0x24], "VBRI", 4) == 0){
n = beuint((uchar*)&ctx->buf[0x32]);
ctx->duration = n * samplespf * 1000 / ctx->samplerate;
--- a/tags.h
+++ b/tags.h
@@ -53,6 +53,9 @@
*/
void (*tag)(Tagctx *ctx, int type, const char *k, const char *s, int offset, int size, Tagread f);
+ /* Approximate millisecond-to-byte offsets within the file, if available. This callback is optional. */
+ void (*toc)(Tagctx *ctx, int ms, int offset);
+
/* Auxiliary data. Not used by libtags. */
void *aux;