diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/codecs/Makefile | 1 | ||||
-rw-r--r-- | apps/codecs/SOURCES | 1 | ||||
-rw-r--r-- | apps/metadata.c | 121 | ||||
-rw-r--r-- | apps/tree.c | 1 |
4 files changed, 124 insertions, 0 deletions
diff --git a/apps/codecs/Makefile b/apps/codecs/Makefile index fb1228d7fc..62312e2288 100644 --- a/apps/codecs/Makefile +++ b/apps/codecs/Makefile | |||
@@ -50,6 +50,7 @@ $(BUILDDIR)/%.a : % $(CODECDEPS) | |||
50 | 50 | ||
51 | $(OBJDIR)/wav.elf : $(OBJDIR)/wav.o | 51 | $(OBJDIR)/wav.elf : $(OBJDIR)/wav.o |
52 | $(OBJDIR)/sid.elf : $(OBJDIR)/sid.o | 52 | $(OBJDIR)/sid.elf : $(OBJDIR)/sid.o |
53 | $(OBJDIR)/adx.elf : $(OBJDIR)/adx.o | ||
53 | $(OBJDIR)/aiff.elf : $(OBJDIR)/aiff.o | 54 | $(OBJDIR)/aiff.elf : $(OBJDIR)/aiff.o |
54 | $(OBJDIR)/mpa.elf : $(OBJDIR)/mpa.o $(BUILDDIR)/libmad.a | 55 | $(OBJDIR)/mpa.elf : $(OBJDIR)/mpa.o $(BUILDDIR)/libmad.a |
55 | $(OBJDIR)/a52.elf : $(OBJDIR)/a52.o $(BUILDDIR)/liba52.a | 56 | $(OBJDIR)/a52.elf : $(OBJDIR)/a52.o $(BUILDDIR)/liba52.a |
diff --git a/apps/codecs/SOURCES b/apps/codecs/SOURCES index 3bd09b4dae..feadcde0ac 100644 --- a/apps/codecs/SOURCES +++ b/apps/codecs/SOURCES | |||
@@ -14,6 +14,7 @@ aac.c | |||
14 | shorten.c | 14 | shorten.c |
15 | aiff.c | 15 | aiff.c |
16 | sid.c | 16 | sid.c |
17 | adx.c | ||
17 | #if defined(HAVE_RECORDING) && !defined(SIMULATOR) | 18 | #if defined(HAVE_RECORDING) && !defined(SIMULATOR) |
18 | /* encoders */ | 19 | /* encoders */ |
19 | mp3_enc.c | 20 | mp3_enc.c |
diff --git a/apps/metadata.c b/apps/metadata.c index 676108116d..1b2dde3a24 100644 --- a/apps/metadata.c +++ b/apps/metadata.c | |||
@@ -82,6 +82,7 @@ static const struct format_list formats[] = | |||
82 | { AFMT_AIFF, "aif" }, | 82 | { AFMT_AIFF, "aif" }, |
83 | { AFMT_AIFF, "aiff" }, | 83 | { AFMT_AIFF, "aiff" }, |
84 | { AFMT_SID, "sid" }, | 84 | { AFMT_SID, "sid" }, |
85 | { AFMT_ADX, "adx" }, | ||
85 | #endif | 86 | #endif |
86 | }; | 87 | }; |
87 | 88 | ||
@@ -1333,6 +1334,118 @@ static bool get_sid_metadata(int fd, struct mp3entry* id3) | |||
1333 | return true; | 1334 | return true; |
1334 | } | 1335 | } |
1335 | 1336 | ||
1337 | static bool get_adx_metadata(int fd, struct mp3entry* id3) | ||
1338 | { | ||
1339 | /* Use the trackname part of the id3 structure as a temporary buffer */ | ||
1340 | unsigned char * buf = id3->path; | ||
1341 | int chanstart, channels, read_bytes; | ||
1342 | int looping = 0, start_adr = 0, end_adr = 0; | ||
1343 | |||
1344 | /* try to get the basic header */ | ||
1345 | if ((lseek(fd, 0, SEEK_SET) < 0) | ||
1346 | || ((read_bytes = read(fd, buf, 0x38)) < 0x38)) | ||
1347 | { | ||
1348 | DEBUGF("lseek or read failed\n"); | ||
1349 | return false; | ||
1350 | } | ||
1351 | |||
1352 | /* ADX starts with 0x80 */ | ||
1353 | if (buf[0] != 0x80) { | ||
1354 | DEBUGF("get_adx_metadata: wrong first byte %c\n",buf[0]); | ||
1355 | return false; | ||
1356 | } | ||
1357 | |||
1358 | /* check for a reasonable offset */ | ||
1359 | chanstart = ((buf[2] << 8) | buf[3]) + 4; | ||
1360 | if (chanstart > 4096) { | ||
1361 | DEBUGF("get_adx_metadata: bad chanstart %i\n", chanstart); | ||
1362 | return false; | ||
1363 | } | ||
1364 | |||
1365 | /* check for a workable number of channels */ | ||
1366 | channels = buf[7]; | ||
1367 | if (channels != 1 && channels != 2) { | ||
1368 | DEBUGF("get_adx_metadata: bad channel count %i\n",channels); | ||
1369 | return false; | ||
1370 | } | ||
1371 | |||
1372 | id3->frequency = (buf[8] << 24) | (buf[9] << 16) | (buf[10] << 8) | buf[11]; | ||
1373 | /* 32 samples per 18 bytes */ | ||
1374 | id3->bitrate = id3->frequency * channels * 18 * 8 / 32 / 1000; | ||
1375 | id3->length = ((unsigned long) | ||
1376 | (buf[12] << 24) | (buf[13] << 16) | (buf[14] << 8) | buf[15]) / | ||
1377 | id3->frequency * 1000; | ||
1378 | id3->vbr = false; | ||
1379 | id3->filesize = filesize(fd); | ||
1380 | |||
1381 | /* get loop info */ | ||
1382 | if (!memcmp(buf+0x10,"\x01\xF4\x03\x00",4)) { | ||
1383 | /* Soul Calibur 2 style (type 03) */ | ||
1384 | DEBUGF("get_adx_metadata: type 03 found\n"); | ||
1385 | /* check if header is too small for loop data */ | ||
1386 | if (chanstart-6 < 0x2c) looping=0; | ||
1387 | else { | ||
1388 | looping = (buf[0x18]) || | ||
1389 | (buf[0x19]) || | ||
1390 | (buf[0x1a]) || | ||
1391 | (buf[0x1b]); | ||
1392 | end_adr = (buf[0x28]<<24) | | ||
1393 | (buf[0x29]<<16) | | ||
1394 | (buf[0x2a]<<8) | | ||
1395 | (buf[0x2b]); | ||
1396 | |||
1397 | start_adr = ( | ||
1398 | (buf[0x1c]<<24) | | ||
1399 | (buf[0x1d]<<16) | | ||
1400 | (buf[0x1e]<<8) | | ||
1401 | (buf[0x1f]) | ||
1402 | )/32*channels*18+chanstart; | ||
1403 | } | ||
1404 | } else if (!memcmp(buf+0x10,"\x01\xF4\x04\x00",4)) { | ||
1405 | /* Standard (type 04) */ | ||
1406 | DEBUGF("get_adx_metadata: type 04 found\n"); | ||
1407 | /* check if header is too small for loop data */ | ||
1408 | if (chanstart-6 < 0x38) looping=0; | ||
1409 | else { | ||
1410 | looping = (buf[0x24]) || | ||
1411 | (buf[0x25]) || | ||
1412 | (buf[0x26]) || | ||
1413 | (buf[0x27]); | ||
1414 | end_adr = (buf[0x34]<<24) | | ||
1415 | (buf[0x35]<<16) | | ||
1416 | (buf[0x36]<<8) | | ||
1417 | buf[0x37]; | ||
1418 | start_adr = ( | ||
1419 | (buf[0x28]<<24) | | ||
1420 | (buf[0x29]<<16) | | ||
1421 | (buf[0x2a]<<8) | | ||
1422 | (buf[0x2b]) | ||
1423 | )/32*channels*18+chanstart; | ||
1424 | } | ||
1425 | } else { | ||
1426 | DEBUGF("get_adx_metadata: error, couldn't determine ADX type\n"); | ||
1427 | return false; | ||
1428 | } | ||
1429 | |||
1430 | if (looping) { | ||
1431 | /* 2 loops, 10 second fade */ | ||
1432 | id3->length = (start_adr-chanstart + 2*(end_adr-start_adr)) | ||
1433 | *8 / id3->bitrate + 10000; | ||
1434 | } | ||
1435 | |||
1436 | /* try to get the channel header */ | ||
1437 | if ((lseek(fd, chanstart-6, SEEK_SET) < 0) | ||
1438 | || ((read_bytes = read(fd, buf, 6)) < 6)) | ||
1439 | { | ||
1440 | return false; | ||
1441 | } | ||
1442 | |||
1443 | /* check channel header */ | ||
1444 | if (memcmp(buf, "(c)CRI", 6) != 0) return false; | ||
1445 | |||
1446 | return true; | ||
1447 | } | ||
1448 | |||
1336 | #endif /* CONFIG_CODEC == SWCODEC */ | 1449 | #endif /* CONFIG_CODEC == SWCODEC */ |
1337 | 1450 | ||
1338 | static bool get_aiff_metadata(int fd, struct mp3entry* id3) | 1451 | static bool get_aiff_metadata(int fd, struct mp3entry* id3) |
@@ -1629,6 +1742,14 @@ bool get_metadata(struct track_info* track, int fd, const char* trackname, | |||
1629 | } | 1742 | } |
1630 | break; | 1743 | break; |
1631 | 1744 | ||
1745 | case AFMT_ADX: | ||
1746 | if (!get_adx_metadata(fd, &(track->id3))) | ||
1747 | { | ||
1748 | DEBUGF("get_adx_metadata error\n"); | ||
1749 | return false; | ||
1750 | } | ||
1751 | |||
1752 | break; | ||
1632 | #endif /* CONFIG_CODEC == SWCODEC */ | 1753 | #endif /* CONFIG_CODEC == SWCODEC */ |
1633 | 1754 | ||
1634 | case AFMT_AIFF: | 1755 | case AFMT_AIFF: |
diff --git a/apps/tree.c b/apps/tree.c index 8e155a96a0..3ee3061540 100644 --- a/apps/tree.c +++ b/apps/tree.c | |||
@@ -104,6 +104,7 @@ const struct filetype filetypes[] = { | |||
104 | { "aif", TREE_ATTR_MPA, Icon_Audio, VOICE_EXT_MPA }, | 104 | { "aif", TREE_ATTR_MPA, Icon_Audio, VOICE_EXT_MPA }, |
105 | { "aiff",TREE_ATTR_MPA, Icon_Audio, VOICE_EXT_MPA }, | 105 | { "aiff",TREE_ATTR_MPA, Icon_Audio, VOICE_EXT_MPA }, |
106 | { "sid", TREE_ATTR_MPA, Icon_Audio, VOICE_EXT_MPA }, | 106 | { "sid", TREE_ATTR_MPA, Icon_Audio, VOICE_EXT_MPA }, |
107 | { "adx", TREE_ATTR_MPA, Icon_Audio, VOICE_EXT_MPA }, | ||
107 | #endif | 108 | #endif |
108 | { "m3u", TREE_ATTR_M3U, Icon_Playlist, LANG_PLAYLIST }, | 109 | { "m3u", TREE_ATTR_M3U, Icon_Playlist, LANG_PLAYLIST }, |
109 | { "m3u8", TREE_ATTR_M3U, Icon_Playlist, LANG_PLAYLIST }, | 110 | { "m3u8", TREE_ATTR_M3U, Icon_Playlist, LANG_PLAYLIST }, |