diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/main.c | 4 | ||||
-rw-r--r-- | apps/tagcache.c | 211 | ||||
-rw-r--r-- | apps/tagcache.h | 1 |
3 files changed, 119 insertions, 97 deletions
diff --git a/apps/main.c b/apps/main.c index 2ceb24d96f..a2bbe73e65 100644 --- a/apps/main.c +++ b/apps/main.c | |||
@@ -185,10 +185,10 @@ void init_tagcache(void) | |||
185 | { | 185 | { |
186 | #ifdef HAVE_LCD_BITMAP | 186 | #ifdef HAVE_LCD_BITMAP |
187 | gui_syncsplash(0, true, "%s [%d/%d]", | 187 | gui_syncsplash(0, true, "%s [%d/%d]", |
188 | str(LANG_TAGCACHE_INIT), ret, TAG_COUNT); | 188 | str(LANG_TAGCACHE_INIT), ret, 7); |
189 | #else | 189 | #else |
190 | lcd_double_height(false); | 190 | lcd_double_height(false); |
191 | snprintf(buf, sizeof(buf), " TC [%d/%d]", ret, TAG_COUNT); | 191 | snprintf(buf, sizeof(buf), " TC [%d/%d]", ret, 7); |
192 | lcd_puts(0, 1, buf); | 192 | lcd_puts(0, 1, buf); |
193 | #endif | 193 | #endif |
194 | clear = true; | 194 | clear = true; |
diff --git a/apps/tagcache.c b/apps/tagcache.c index dbf58c69fa..042d27cc84 100644 --- a/apps/tagcache.c +++ b/apps/tagcache.c | |||
@@ -171,7 +171,8 @@ static struct ramcache_header *hdr; | |||
171 | struct temp_file_entry { | 171 | struct temp_file_entry { |
172 | long tag_offset[TAG_COUNT]; | 172 | long tag_offset[TAG_COUNT]; |
173 | short tag_length[TAG_COUNT]; | 173 | short tag_length[TAG_COUNT]; |
174 | 174 | long flag; | |
175 | |||
175 | long data_length; | 176 | long data_length; |
176 | }; | 177 | }; |
177 | 178 | ||
@@ -448,9 +449,6 @@ static int find_index(const char *filename) | |||
448 | if (idx_id < 0) | 449 | if (idx_id < 0) |
449 | idx_id = find_entry_disk(filename); | 450 | idx_id = find_entry_disk(filename); |
450 | 451 | ||
451 | if (idx_id < 0) | ||
452 | return false; | ||
453 | |||
454 | return idx_id; | 452 | return idx_id; |
455 | } | 453 | } |
456 | 454 | ||
@@ -1327,18 +1325,37 @@ static inline void write_item(const char *item) | |||
1327 | write(cachefd, item, len); | 1325 | write(cachefd, item, len); |
1328 | } | 1326 | } |
1329 | 1327 | ||
1330 | inline void check_if_empty(char **tag) | 1328 | static int check_if_empty(char **tag) |
1331 | { | 1329 | { |
1332 | if (tag == NULL || *tag == NULL || *tag[0] == '\0') | 1330 | int length; |
1331 | |||
1332 | if (*tag == NULL || *tag[0] == '\0') | ||
1333 | { | ||
1333 | *tag = "<Untagged>"; | 1334 | *tag = "<Untagged>"; |
1335 | return 11; /* Tag length */ | ||
1336 | } | ||
1337 | |||
1338 | length = strlen(*tag); | ||
1339 | if (length >= MAX_PATH-32) | ||
1340 | { | ||
1341 | logf("over length tag: %s", *tag); | ||
1342 | *tag[MAX_PATH-32] = '\0'; | ||
1343 | length = MAX_PATH-32; | ||
1344 | } | ||
1345 | |||
1346 | return length + 1; | ||
1334 | } | 1347 | } |
1335 | 1348 | ||
1336 | #define CRC_BUF_LEN 8 | 1349 | #define ADD_TAG(entry,tag,data) \ |
1337 | 1350 | /* Adding tag */ \ | |
1351 | entry.tag_offset[tag] = offset; \ | ||
1352 | entry.tag_length[tag] = check_if_empty(data); \ | ||
1353 | offset += entry.tag_length[tag] | ||
1354 | |||
1338 | #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) | 1355 | #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) |
1339 | static void add_tagcache(const char *path, const struct dircache_entry *dc) | 1356 | static void add_tagcache(char *path, const struct dircache_entry *dc) |
1340 | #else | 1357 | #else |
1341 | static void add_tagcache(const char *path) | 1358 | static void add_tagcache(char *path) |
1342 | #endif | 1359 | #endif |
1343 | { | 1360 | { |
1344 | struct track_info track; | 1361 | struct track_info track; |
@@ -1347,7 +1364,7 @@ static void add_tagcache(const char *path) | |||
1347 | int fd; | 1364 | int fd; |
1348 | char tracknumfix[3]; | 1365 | char tracknumfix[3]; |
1349 | char *genrestr; | 1366 | char *genrestr; |
1350 | //uint32_t crcbuf[CRC_BUF_LEN]; | 1367 | int offset = 0; |
1351 | 1368 | ||
1352 | if (cachefd < 0) | 1369 | if (cachefd < 0) |
1353 | return ; | 1370 | return ; |
@@ -1391,36 +1408,8 @@ static void add_tagcache(const char *path) | |||
1391 | 1408 | ||
1392 | logf("-> %s", path); | 1409 | logf("-> %s", path); |
1393 | 1410 | ||
1394 | genrestr = id3_get_genre(&track.id3); | 1411 | /* Generate track number if missing. */ |
1395 | 1412 | if (track.id3.tracknum <= 0) | |
1396 | check_if_empty(&track.id3.title); | ||
1397 | check_if_empty(&track.id3.artist); | ||
1398 | check_if_empty(&track.id3.album); | ||
1399 | check_if_empty(&genrestr); | ||
1400 | check_if_empty(&track.id3.composer); | ||
1401 | |||
1402 | entry.tag_length[tag_filename] = strlen(path) + 1; | ||
1403 | entry.tag_length[tag_title] = strlen(track.id3.title) + 1; | ||
1404 | entry.tag_length[tag_artist] = strlen(track.id3.artist) + 1; | ||
1405 | entry.tag_length[tag_album] = strlen(track.id3.album) + 1; | ||
1406 | entry.tag_length[tag_genre] = strlen(genrestr) + 1; | ||
1407 | entry.tag_length[tag_composer] = strlen(track.id3.composer) + 1; | ||
1408 | |||
1409 | entry.tag_offset[tag_filename] = 0; | ||
1410 | entry.tag_offset[tag_title] = entry.tag_offset[tag_filename] + entry.tag_length[tag_filename]; | ||
1411 | entry.tag_offset[tag_artist] = entry.tag_offset[tag_title] + entry.tag_length[tag_title]; | ||
1412 | entry.tag_offset[tag_album] = entry.tag_offset[tag_artist] + entry.tag_length[tag_artist]; | ||
1413 | entry.tag_offset[tag_genre] = entry.tag_offset[tag_album] + entry.tag_length[tag_album]; | ||
1414 | entry.tag_offset[tag_composer] = entry.tag_offset[tag_genre] + entry.tag_length[tag_genre]; | ||
1415 | entry.data_length = entry.tag_offset[tag_composer] + entry.tag_length[tag_composer]; | ||
1416 | |||
1417 | /* Numeric tags */ | ||
1418 | entry.tag_offset[tag_year] = track.id3.year; | ||
1419 | entry.tag_offset[tag_tracknumber] = track.id3.tracknum; | ||
1420 | entry.tag_offset[tag_length] = track.id3.length; | ||
1421 | entry.tag_offset[tag_bitrate] = track.id3.bitrate; | ||
1422 | |||
1423 | if (entry.tag_offset[tag_tracknumber] <= 0) | ||
1424 | { | 1413 | { |
1425 | const char *p = strrchr(path, '.'); | 1414 | const char *p = strrchr(path, '.'); |
1426 | 1415 | ||
@@ -1439,12 +1428,39 @@ static void add_tagcache(const char *path) | |||
1439 | } | 1428 | } |
1440 | 1429 | ||
1441 | if (tracknumfix[0] != '\0') | 1430 | if (tracknumfix[0] != '\0') |
1442 | entry.tag_offset[tag_tracknumber] = atoi(tracknumfix); | 1431 | { |
1432 | track.id3.tracknum = atoi(tracknumfix); | ||
1433 | /* Set a flag to indicate track number has been generated. */ | ||
1434 | entry.flag |= FLAG_TRKNUMGEN; | ||
1435 | } | ||
1443 | else | 1436 | else |
1444 | entry.tag_offset[tag_tracknumber] = -1; | 1437 | { |
1438 | /* Unable to generate track number. */ | ||
1439 | track.id3.tracknum = -1; | ||
1440 | } | ||
1445 | } | 1441 | } |
1446 | 1442 | ||
1443 | genrestr = id3_get_genre(&track.id3); | ||
1444 | |||
1445 | /* Numeric tags */ | ||
1446 | entry.tag_offset[tag_year] = track.id3.year; | ||
1447 | entry.tag_offset[tag_tracknumber] = track.id3.tracknum; | ||
1448 | entry.tag_offset[tag_length] = track.id3.length; | ||
1449 | entry.tag_offset[tag_bitrate] = track.id3.bitrate; | ||
1450 | |||
1451 | /* String tags. */ | ||
1452 | ADD_TAG(entry, tag_filename, &path); | ||
1453 | ADD_TAG(entry, tag_title, &track.id3.title); | ||
1454 | ADD_TAG(entry, tag_artist, &track.id3.artist); | ||
1455 | ADD_TAG(entry, tag_album, &track.id3.album); | ||
1456 | ADD_TAG(entry, tag_genre, &genrestr); | ||
1457 | ADD_TAG(entry, tag_composer, &track.id3.composer); | ||
1458 | entry.data_length = offset; | ||
1459 | |||
1460 | /* Write the header */ | ||
1447 | write(cachefd, &entry, sizeof(struct temp_file_entry)); | 1461 | write(cachefd, &entry, sizeof(struct temp_file_entry)); |
1462 | |||
1463 | /* And tags also... Correct order is critical */ | ||
1448 | write_item(path); | 1464 | write_item(path); |
1449 | write_item(track.id3.title); | 1465 | write_item(track.id3.title); |
1450 | write_item(track.id3.artist); | 1466 | write_item(track.id3.artist); |
@@ -1659,47 +1675,22 @@ inline static int tempbuf_find_location(int id) | |||
1659 | return entry->seek; | 1675 | return entry->seek; |
1660 | } | 1676 | } |
1661 | 1677 | ||
1662 | static bool build_numeric_index(int index_type, struct tagcache_header *h, int tmpfd) | 1678 | static bool build_numeric_indices(struct tagcache_header *h, int tmpfd) |
1663 | { | 1679 | { |
1664 | struct master_header tcmh; | 1680 | struct master_header tcmh; |
1665 | struct index_entry idx; | 1681 | struct index_entry idx; |
1666 | int masterfd; | 1682 | int masterfd; |
1667 | int masterfd_pos; | 1683 | int masterfd_pos; |
1668 | long *databuf = (long *)tempbuf; | 1684 | struct temp_file_entry *entrybuf = (struct temp_file_entry *)tempbuf; |
1669 | int max_entries; | 1685 | int max_entries; |
1670 | int i; | 1686 | int entries_processed = 0; |
1671 | 1687 | int i, j; | |
1672 | max_entries = tempbuf_size / sizeof(long); | ||
1673 | 1688 | ||
1674 | if (h->entry_count >= max_entries) | 1689 | max_entries = tempbuf_size / sizeof(struct temp_file_entry) - 1; |
1675 | { | ||
1676 | logf("not enough space!"); | ||
1677 | return false; | ||
1678 | } | ||
1679 | |||
1680 | logf("Building numeric index: %d", index_type); | ||
1681 | 1690 | ||
1682 | /* Walk through the temporary file. */ | 1691 | logf("Building numeric indices..."); |
1683 | lseek(tmpfd, sizeof(struct tagcache_header), SEEK_SET); | 1692 | lseek(tmpfd, sizeof(struct tagcache_header), SEEK_SET); |
1684 | for (i = 0; i < h->entry_count; i++) | ||
1685 | { | ||
1686 | struct temp_file_entry entry; | ||
1687 | |||
1688 | if (read(tmpfd, &entry, sizeof(struct temp_file_entry)) != | ||
1689 | sizeof(struct temp_file_entry)) | ||
1690 | { | ||
1691 | logf("read fail #1"); | ||
1692 | return false; | ||
1693 | } | ||
1694 | |||
1695 | /* Insert data in buffer. */ | ||
1696 | databuf[i] = (long)entry.tag_offset[index_type]; | ||
1697 | |||
1698 | /* Skip to next. */ | ||
1699 | lseek(tmpfd, entry.data_length, SEEK_CUR); | ||
1700 | } | ||
1701 | 1693 | ||
1702 | /* Update the entries in index. */ | ||
1703 | if ( (masterfd = open_master_fd(&tcmh, true)) < 0) | 1694 | if ( (masterfd = open_master_fd(&tcmh, true)) < 0) |
1704 | return false; | 1695 | return false; |
1705 | 1696 | ||
@@ -1712,29 +1703,61 @@ static bool build_numeric_index(int index_type, struct tagcache_header *h, int t | |||
1712 | return false; | 1703 | return false; |
1713 | } | 1704 | } |
1714 | 1705 | ||
1715 | for (i = 0; i < h->entry_count; i++) | 1706 | while (entries_processed < h->entry_count) |
1716 | { | 1707 | { |
1717 | int loc = lseek(masterfd, 0, SEEK_CUR); | 1708 | int count = MIN(h->entry_count, max_entries); |
1718 | 1709 | ||
1719 | if (read(masterfd, &idx, sizeof(struct index_entry)) != | 1710 | /* Read in as many entries as possible. */ |
1720 | sizeof(struct index_entry)) | 1711 | for (i = 0; i < count; i++) |
1721 | { | 1712 | { |
1722 | logf("read fail #2"); | 1713 | /* Read in numeric data. */ |
1723 | close(masterfd); | 1714 | if (read(tmpfd, &entrybuf[i], sizeof(struct temp_file_entry)) != |
1724 | return false; | 1715 | sizeof(struct temp_file_entry)) |
1716 | { | ||
1717 | logf("read fail #1"); | ||
1718 | close(masterfd); | ||
1719 | return false; | ||
1720 | } | ||
1721 | |||
1722 | /* Skip string data. */ | ||
1723 | lseek(tmpfd, entrybuf[i].data_length, SEEK_CUR); | ||
1725 | } | 1724 | } |
1726 | 1725 | ||
1727 | idx.tag_seek[index_type] = databuf[i]; | 1726 | /* Commit the data to the index. */ |
1728 | 1727 | for (i = 0; i < count; i++) | |
1729 | /* Write back the updated index. */ | ||
1730 | lseek(masterfd, loc, SEEK_SET); | ||
1731 | if (write(masterfd, &idx, sizeof(struct index_entry)) != | ||
1732 | sizeof(struct index_entry)) | ||
1733 | { | 1728 | { |
1734 | logf("write fail"); | 1729 | int loc = lseek(masterfd, 0, SEEK_CUR); |
1735 | close(masterfd); | 1730 | |
1736 | return false; | 1731 | if (read(masterfd, &idx, sizeof(struct index_entry)) != |
1732 | sizeof(struct index_entry)) | ||
1733 | { | ||
1734 | logf("read fail #2"); | ||
1735 | close(masterfd); | ||
1736 | return false; | ||
1737 | } | ||
1738 | |||
1739 | for (j = 0; j < TAG_COUNT; j++) | ||
1740 | { | ||
1741 | if (!tagcache_is_numeric_tag(j)) | ||
1742 | continue; | ||
1743 | |||
1744 | idx.tag_seek[j] = entrybuf[i].tag_offset[j]; | ||
1745 | } | ||
1746 | idx.flag = entrybuf[i].flag; | ||
1747 | |||
1748 | /* Write back the updated index. */ | ||
1749 | lseek(masterfd, loc, SEEK_SET); | ||
1750 | if (write(masterfd, &idx, sizeof(struct index_entry)) != | ||
1751 | sizeof(struct index_entry)) | ||
1752 | { | ||
1753 | logf("write fail"); | ||
1754 | close(masterfd); | ||
1755 | return false; | ||
1756 | } | ||
1737 | } | 1757 | } |
1758 | |||
1759 | entries_processed += count; | ||
1760 | logf("%d/%d entries processed", entries_processed, h->entry_count); | ||
1738 | } | 1761 | } |
1739 | 1762 | ||
1740 | close(masterfd); | 1763 | close(masterfd); |
@@ -2330,13 +2353,10 @@ static bool commit(void) | |||
2330 | { | 2353 | { |
2331 | int ret; | 2354 | int ret; |
2332 | 2355 | ||
2333 | stat.commit_step++; | ||
2334 | if (tagcache_is_numeric_tag(i)) | 2356 | if (tagcache_is_numeric_tag(i)) |
2335 | { | ||
2336 | build_numeric_index(i, &tch, tmpfd); | ||
2337 | continue; | 2357 | continue; |
2338 | } | ||
2339 | 2358 | ||
2359 | stat.commit_step++; | ||
2340 | ret = build_index(i, &tch, tmpfd); | 2360 | ret = build_index(i, &tch, tmpfd); |
2341 | if (ret <= 0) | 2361 | if (ret <= 0) |
2342 | { | 2362 | { |
@@ -2352,6 +2372,7 @@ static bool commit(void) | |||
2352 | } | 2372 | } |
2353 | } | 2373 | } |
2354 | 2374 | ||
2375 | build_numeric_indices(&tch, tmpfd); | ||
2355 | close(tmpfd); | 2376 | close(tmpfd); |
2356 | stat.commit_step = 0; | 2377 | stat.commit_step = 0; |
2357 | 2378 | ||
diff --git a/apps/tagcache.h b/apps/tagcache.h index b639611394..23525f8ea8 100644 --- a/apps/tagcache.h +++ b/apps/tagcache.h | |||
@@ -70,6 +70,7 @@ enum tag_type { tag_artist = 0, tag_album, tag_genre, tag_title, | |||
70 | #define FLAG_DELETED 0x0001 /* Entry has been removed from db */ | 70 | #define FLAG_DELETED 0x0001 /* Entry has been removed from db */ |
71 | #define FLAG_DIRCACHE 0x0002 /* Filename is a dircache pointer */ | 71 | #define FLAG_DIRCACHE 0x0002 /* Filename is a dircache pointer */ |
72 | #define FLAG_DIRTYNUM 0x0004 /* Numeric data has been modified */ | 72 | #define FLAG_DIRTYNUM 0x0004 /* Numeric data has been modified */ |
73 | #define FLAG_TRKNUMGEN 0x0008 /* Track number has been generated */ | ||
73 | #define FLAG_GET_ATTR(flag) ((flag >> 16) & 0x0000ffff) | 74 | #define FLAG_GET_ATTR(flag) ((flag >> 16) & 0x0000ffff) |
74 | #define FLAG_SET_ATTR(flag,attr) flag = (flag & 0x0000ffff) | (attr << 16) | 75 | #define FLAG_SET_ATTR(flag,attr) flag = (flag & 0x0000ffff) | (attr << 16) |
75 | 76 | ||