diff options
author | Magnus Holmgren <magnushol@gmail.com> | 2007-04-24 19:22:21 +0000 |
---|---|---|
committer | Magnus Holmgren <magnushol@gmail.com> | 2007-04-24 19:22:21 +0000 |
commit | ab707b836209dd799176579c06196962f320351e (patch) | |
tree | e92522cfea93849972be1cabb74f2b1df9f2dc66 /apps/metadata.c | |
parent | 72e6dd5e0c5bb9fc0b2de176adb98dce43c273be (diff) | |
download | rockbox-ab707b836209dd799176579c06196962f320351e.tar.gz rockbox-ab707b836209dd799176579c06196962f320351e.zip |
AAC: Improve SBR detection, to fix incorrect frequency on some files (and hopefully not break others :).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13255 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/metadata.c')
-rw-r--r-- | apps/metadata.c | 67 |
1 files changed, 53 insertions, 14 deletions
diff --git a/apps/metadata.c b/apps/metadata.c index e5c8ad6500..b544a0c410 100644 --- a/apps/metadata.c +++ b/apps/metadata.c | |||
@@ -1255,14 +1255,17 @@ static bool read_mp4_esds(int fd, struct mp3entry* id3, | |||
1255 | unsigned long bits; | 1255 | unsigned long bits; |
1256 | unsigned int length; | 1256 | unsigned int length; |
1257 | unsigned int index; | 1257 | unsigned int index; |
1258 | int type; | 1258 | unsigned int type; |
1259 | 1259 | ||
1260 | /* Read the (leading part of the) decoder config. */ | 1260 | /* Read the (leading part of the) decoder config. */ |
1261 | length = read_mp4_length(fd, size); | 1261 | length = read_mp4_length(fd, size); |
1262 | length = MIN(length, *size); | 1262 | length = MIN(length, *size); |
1263 | length = MIN(length, sizeof(buf)); | 1263 | length = MIN(length, sizeof(buf)); |
1264 | memset(buf, 0, sizeof(buf)); | ||
1264 | read(fd, buf, length); | 1265 | read(fd, buf, length); |
1265 | *size -= length; | 1266 | *size -= length; |
1267 | |||
1268 | /* Maybe time to write a simple read_bits function... */ | ||
1266 | 1269 | ||
1267 | /* Decoder config format: | 1270 | /* Decoder config format: |
1268 | * Object type - 5 bits | 1271 | * Object type - 5 bits |
@@ -1270,9 +1273,9 @@ static bool read_mp4_esds(int fd, struct mp3entry* id3, | |||
1270 | * Channel configuration - 4 bits | 1273 | * Channel configuration - 4 bits |
1271 | */ | 1274 | */ |
1272 | bits = get_long_be(buf); | 1275 | bits = get_long_be(buf); |
1273 | type = bits >> 27; | 1276 | type = bits >> 27; /* Object type - 5 bits */ |
1274 | index = (bits >> 23) & 0xf; | 1277 | index = (bits >> 23) & 0xf; /* Frequency index - 4 bits */ |
1275 | 1278 | ||
1276 | if (index < (sizeof(sample_rates) / sizeof(*sample_rates))) | 1279 | if (index < (sizeof(sample_rates) / sizeof(*sample_rates))) |
1277 | { | 1280 | { |
1278 | id3->frequency = sample_rates[index]; | 1281 | id3->frequency = sample_rates[index]; |
@@ -1280,29 +1283,65 @@ static bool read_mp4_esds(int fd, struct mp3entry* id3, | |||
1280 | 1283 | ||
1281 | if (type == 5) | 1284 | if (type == 5) |
1282 | { | 1285 | { |
1286 | DEBUGF("MP4: SBR\n"); | ||
1287 | unsigned int old_index = index; | ||
1288 | |||
1283 | sbr = true; | 1289 | sbr = true; |
1284 | /* Extended frequency index - 4 bits */ | 1290 | index = (bits >> 15) & 0xf; /* Frequency index - 4 bits */ |
1285 | index = (bits >> 15) & 0xf; | ||
1286 | 1291 | ||
1287 | if (index == 15) | 1292 | if (index == 15) |
1288 | { | 1293 | { |
1289 | /* 17 bits read so far... */ | 1294 | /* 17 bits read so far... */ |
1290 | bits = get_long_be(&buf[2]); | 1295 | bits = get_long_be(&buf[2]); |
1291 | id3->frequency = (bits >> 7) & 0x00FFFFFF; | 1296 | id3->frequency = (bits >> 7) & 0x00ffffff; |
1292 | } | 1297 | } |
1293 | else if (index < (sizeof(sample_rates) / sizeof(*sample_rates))) | 1298 | else if (index < (sizeof(sample_rates) / sizeof(*sample_rates))) |
1294 | { | 1299 | { |
1295 | id3->frequency = sample_rates[index]; | 1300 | id3->frequency = sample_rates[index]; |
1296 | } | 1301 | } |
1302 | |||
1303 | if (old_index == index) | ||
1304 | { | ||
1305 | /* Downsampled SBR */ | ||
1306 | id3->frequency *= 2; | ||
1307 | } | ||
1297 | } | 1308 | } |
1298 | else if (id3->frequency < 24000) | 1309 | /* TODO: Should check that there is at least 16 bits left */ |
1310 | /* Skip 13 bits from above, plus 3 bits, then read 11 bits */ | ||
1311 | else if (((bits >> 5) & 0x7ff) == 0x2b7) /* extensionAudioObjectType */ | ||
1299 | { | 1312 | { |
1300 | /* SBR not indicated, but the file might still contain SBR. | 1313 | DEBUGF("MP4: extensionAudioType\n"); |
1301 | * MPEG specification says that one should assume SBR if | 1314 | type = bits & 0x1f; /* Object type - 5 bits*/ |
1302 | * samplerate <= 24000 Hz. | 1315 | bits = get_long_be(&buf[4]); |
1303 | */ | 1316 | |
1304 | id3->frequency *= 2; | 1317 | if (type == 5) |
1305 | sbr = true; | 1318 | { |
1319 | sbr = bits >> 31; | ||
1320 | |||
1321 | if (sbr) | ||
1322 | { | ||
1323 | unsigned int old_index = index; | ||
1324 | |||
1325 | /* 1 bit read so far */ | ||
1326 | index = (bits >> 27) & 0xf; /* Frequency index - 4 bits */ | ||
1327 | |||
1328 | if (index == 15) | ||
1329 | { | ||
1330 | /* 5 bits read so far */ | ||
1331 | id3->frequency = (bits >> 3) & 0x00ffffff; | ||
1332 | } | ||
1333 | else if (index < (sizeof(sample_rates) / sizeof(*sample_rates))) | ||
1334 | { | ||
1335 | id3->frequency = sample_rates[index]; | ||
1336 | } | ||
1337 | |||
1338 | if (old_index == index) | ||
1339 | { | ||
1340 | /* Downsampled SBR */ | ||
1341 | id3->frequency *= 2; | ||
1342 | } | ||
1343 | } | ||
1344 | } | ||
1306 | } | 1345 | } |
1307 | } | 1346 | } |
1308 | 1347 | ||