summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/main.c4
-rw-r--r--apps/tagcache.c211
-rw-r--r--apps/tagcache.h1
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;
171struct temp_file_entry { 171struct 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
1330inline void check_if_empty(char **tag) 1328static 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)
1339static void add_tagcache(const char *path, const struct dircache_entry *dc) 1356static void add_tagcache(char *path, const struct dircache_entry *dc)
1340#else 1357#else
1341static void add_tagcache(const char *path) 1358static 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
1662static bool build_numeric_index(int index_type, struct tagcache_header *h, int tmpfd) 1678static 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