ref: 8674e9017cadc0a9f776de10940fc4cce03bd903
parent: b8408cefb2c8dd3c47fa0f4ca69ba519086334e6
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Thu Mar 7 17:57:40 EST 2024
m4a: add replay gain support
binary files a/input/noise.m4a b/input/noise.m4a differ
--- a/m4a.c
+++ b/m4a.c
@@ -10,6 +10,7 @@
uint64_t duration;
uint x;
uint8_t *d;
+ char *k, *v;
int sz, type, dtype, i, skip, n;
d = (uint8_t*)ctx->buf;
@@ -44,7 +45,8 @@
memcmp(d, "minf", 4) == 0 ||
memcmp(d, "moov", 4) == 0 ||
memcmp(d, "trak", 4) == 0 ||
- memcmp(d, "stbl", 4) == 0){
+ memcmp(d, "stbl", 4) == 0 ||
+ memcmp(d, "----", 4) == 0){
sz = 0;
continue;
}else if(memcmp(d, "stsd", 4) == 0){
@@ -118,6 +120,35 @@
duration = ((uint64_t)beuint(&d[20])<<32 | beuint(&d[24])) / (uint64_t)x;
}
ctx->duration = duration * 1000;
+ continue;
+ }else if(memcmp(d, "name", 4) == 0){
+ if(sz <= 16 || sz >= ctx->bufsz-1) /* 1 for '\0' */
+ continue;
+ if(ctx->read(ctx, d, sz) != sz)
+ return -1;
+ // FIXME - do first 4 bytes mean anything?
+ k = (char*)d + 4;
+ d[sz] = 0;
+ n = sz + 1;
+ v = (char*)d + n;
+
+ if(ctx->read(ctx, d, 4) != 4) /* size */
+ return -1;
+ sz = beuint(d);
+ if(sz <= 16 || 12 > ctx->bufsz-n || sz-16 >= ctx->bufsz-n-1){
+ sz -= 4;
+ continue;
+ }
+ sz -= 4+4+4+4;
+ if(ctx->read(ctx, v, 12) != 12) /* "data", data type (should be text) and 4 more bytes */
+ return -1;
+ if(memcmp(v, "data", 4) != 0 || beuint(v+4) != 1)
+ continue;
+ if(ctx->read(ctx, v, sz) != sz)
+ return -1;
+ v[sz] = 0;
+ cbvorbiscomment(ctx, k, v);
+ sz = 0;
continue;
}