summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/dbtree.c99
-rwxr-xr-xtools/songdb.pl354
2 files changed, 302 insertions, 151 deletions
diff --git a/apps/dbtree.c b/apps/dbtree.c
index 1b2cabf783..359419cbd6 100644
--- a/apps/dbtree.c
+++ b/apps/dbtree.c
@@ -57,16 +57,21 @@
#define BE32(_x_) _x_
#endif
-#define ID3DB_VERSION 1
+#define SONGENTRY_SIZE (songlen+12+genrelen+4)
+#define FILEENTRY_SIZE (filelen+12)
+#define ALBUMENTRY_SIZE (albumlen+4+songarraylen*4)
+#define ARTISTENTRY_SIZE (artistlen+albumarraylen*4)
+
+#define ID3DB_VERSION 2
static int fd;
static int
- songstart, albumstart, artiststart,
- songcount, albumcount, artistcount,
- songlen, songarraylen,
+ songstart, albumstart, artiststart, filestart,
+ songcount, albumcount, artistcount, filecount,
+ songlen, songarraylen, genrelen, filelen,
albumlen, albumarraylen,
- artistlen, initialized = 0;
+ artistlen, rundbdirty,initialized = 0;
static int db_play_folder(struct tree_context* c);
static int db_search(struct tree_context* c, char* string);
@@ -76,7 +81,7 @@ static char searchstring[32];
int db_init(void)
{
unsigned int version;
- unsigned int buf[12];
+ unsigned int buf[17];
unsigned char* ptr = (char*)buf;
fd = open(ROCKBOX_DIR "/rockbox.id3db", O_RDONLY);
@@ -84,7 +89,7 @@ int db_init(void)
DEBUGF("Failed opening database\n");
return -1;
}
- read(fd, buf, 48);
+ read(fd, buf, 68);
if (ptr[0] != 'R' ||
ptr[1] != 'D' ||
@@ -94,29 +99,35 @@ int db_init(void)
return -1;
}
- version = BE32(buf[0]) & 0xff;
+ version = BE32(buf[0])&0xFF;
if (version != ID3DB_VERSION)
{
splash(HZ,true,"Unsupported database version %d!", version);
return -1;
}
- songstart = BE32(buf[1]);
- songcount = BE32(buf[2]);
- songlen = BE32(buf[3]);
-
- albumstart = BE32(buf[4]);
- albumcount = BE32(buf[5]);
- albumlen = BE32(buf[6]);
- songarraylen = BE32(buf[7]);
-
- artiststart = BE32(buf[8]);
- artistcount = BE32(buf[9]);
- artistlen = BE32(buf[10]);
- albumarraylen = BE32(buf[11]);
-
- if (songstart > albumstart ||
- albumstart > artiststart)
+ artiststart = BE32(buf[1]);
+ albumstart = BE32(buf[2]);
+ songstart = BE32(buf[3]);
+ filestart = BE32(buf[4]);
+
+ artistcount = BE32(buf[5]);
+ albumcount = BE32(buf[6]);
+ songcount = BE32(buf[7]);
+ filecount = BE32(buf[8]);
+
+ artistlen = BE32(buf[9]);
+ albumlen = BE32(buf[10]);
+ songlen = BE32(buf[11]);
+ genrelen = BE32(buf[12]);
+ filelen = BE32(buf[13]);
+ songarraylen = BE32(buf[14]);
+ albumarraylen = BE32(buf[15]);
+ rundbdirty = BE32(buf[16]);
+
+ if (songstart > filestart ||
+ albumstart > songstart ||
+ artiststart > albumstart)
{
splash(HZ,true,"Corrupt ID3 database!");
return -1;
@@ -150,7 +161,7 @@ int db_load(struct tree_context* c)
c->dentry_size = 2;
c->dirfull = false;
- DEBUGF("db_load(%d, %x, %d)\n", table, extra, c->firstpos);
+ DEBUGF("db_load() table: %d extra: 0x%x firstpos: %d\n", table, extra, c->firstpos);
if (!table) {
table = root;
@@ -166,7 +177,7 @@ int db_load(struct tree_context* c)
str(LANG_ID3DB_ALBUMS),
str(LANG_ID3DB_SONGS),
str(LANG_ID3DB_SEARCH)};
-
+ DEBUGF("dbload table root\n");
for (i=0; i < 4; i++) {
strcpy(nbuf, labels[i]);
dptr[0] = (unsigned long)nbuf;
@@ -186,7 +197,7 @@ int db_load(struct tree_context* c)
char* labels[] = { str(LANG_ID3DB_SEARCH_ARTISTS),
str(LANG_ID3DB_SEARCH_ALBUMS),
str(LANG_ID3DB_SEARCH_SONGS)};
-
+ DEBUGF("dbload table search\n");
for (i=0; i < 3; i++) {
strcpy(nbuf, labels[i]);
dptr[0] = (unsigned long)nbuf;
@@ -201,6 +212,7 @@ int db_load(struct tree_context* c)
case searchartists:
case searchalbums:
case searchsongs:
+ DEBUGF("dbload table searchsongs/searchartists/searchalbums\n");
i = db_search(c, searchstring);
c->dirlength = c->filesindir = i;
if (c->dirfull) {
@@ -214,26 +226,28 @@ int db_load(struct tree_context* c)
return i;
case allsongs:
- offset = songstart + c->firstpos * (songlen + 12);
+ DEBUGF("dbload table allsongs\n");
+ offset = songstart + c->firstpos * SONGENTRY_SIZE;
itemcount = songcount;
stringlen = songlen;
break;
case allalbums:
- offset = albumstart +
- c->firstpos * (albumlen + 4 + songarraylen * 4);
+ DEBUGF("dbload table allalbums\n");
+ offset = albumstart + c->firstpos * ALBUMENTRY_SIZE;
itemcount = albumcount;
stringlen = albumlen;
break;
case allartists:
- offset = artiststart +
- c->firstpos * (artistlen + albumarraylen * 4);
+ DEBUGF("dbload table allartists\n");
+ offset = artiststart + c->firstpos * ARTISTENTRY_SIZE;
itemcount = artistcount;
stringlen = artistlen;
break;
case albums4artist:
+ DEBUGF("dbload table albums4artist\n");
/* 'extra' is offset to the artist */
safeplacelen = albumarraylen * 4;
safeplace = (void*)(end_of_nbuf - safeplacelen);
@@ -252,6 +266,7 @@ int db_load(struct tree_context* c)
break;
case songs4album:
+ DEBUGF("dbload table songs4album\n");
/* 'extra' is offset to the album */
safeplacelen = songarraylen * 4;
safeplace = (void*)(end_of_nbuf - safeplacelen);
@@ -261,8 +276,10 @@ int db_load(struct tree_context* c)
return -1;
#ifdef LITTLE_ENDIAN
- for (i=0; i<songarraylen; i++)
+ for (i=0; i<songarraylen; i++) {
safeplace[i] = BE32(safeplace[i]);
+ DEBUGF("db_load songs4album song %d: 0x%x\n",i,safeplace[i]);
+ }
#endif
offset = safeplace[0];
itemcount = songarraylen;
@@ -270,8 +287,9 @@ int db_load(struct tree_context* c)
break;
case songs4artist:
+ DEBUGF("dbload table songs4artist\n");
/* 'extra' is offset to the artist, used as filter */
- offset = songstart + c->firstpos * (songlen + 12);
+ offset = songstart + c->firstpos * SONGENTRY_SIZE;
itemcount = songcount;
stringlen = songlen;
break;
@@ -318,13 +336,16 @@ int db_load(struct tree_context* c)
case songs4album:
case songs4artist:
rc = read(fd, intbuf, 12);
+ skip = SONGENTRY_SIZE-stringlen-12; /* skip the rest of the song info */
if (rc < 12) {
DEBUGF("%d read(%d) returned %d\n", i, 12, rc);
return -1;
}
/* continue to next song if wrong artist */
- if (table == songs4artist && (int)BE32(intbuf[0]) != extra)
+ if (table == songs4artist && (int)BE32(intbuf[0]) != extra) {
+ lseek(fd, skip, SEEK_CUR);
continue;
+ }
/* save offset of filename */
dptr[1] = BE32(intbuf[2]);
@@ -400,19 +421,19 @@ static int db_search(struct tree_context* c, char* string)
case searchartists:
start = artiststart;
count = artistcount;
- size = artistlen + albumarraylen * 4;
+ size = ARTISTENTRY_SIZE;
break;
case searchalbums:
start = albumstart;
count = albumcount;
- size = albumlen + 4 + songarraylen * 4;
+ size = ALBUMENTRY_SIZE;
break;
case searchsongs:
start = songstart;
count = songcount;
- size = songlen + 12;
+ size = SONGENTRY_SIZE;
break;
default:
@@ -497,7 +518,7 @@ int db_enter(struct tree_context* c)
case searchalbums:
/* virtual <all albums> entry points to the artist,
all normal entries point to the album */
- if (newextra >= artiststart)
+ if (newextra < albumstart)
c->currtable = songs4artist;
else
c->currtable = songs4album;
diff --git a/tools/songdb.pl b/tools/songdb.pl
index 19ca1cb634..a9fc78ee4a 100755
--- a/tools/songdb.pl
+++ b/tools/songdb.pl
@@ -12,6 +12,8 @@ my $dir;
my $strip;
my $verbose;
my $help;
+my $dirisalbum;
+my $dirisalbumname;
while($ARGV[0]) {
if($ARGV[0] eq "--db") {
@@ -33,6 +35,14 @@ while($ARGV[0]) {
$verbose = 1;
shift @ARGV;
}
+ elsif($ARGV[0] eq "--dirisalbum") {
+ $dirisalbum = 1;
+ shift @ARGV;
+ }
+ elsif($ARGV[0] eq "--dirisalbumname") {
+ $dirisalbumname = 1;
+ shift @ARGV;
+ }
elsif($ARGV[0] eq "--help" or ($ARGV[0] eq "-h")) {
$help = 1;
shift @ARGV;
@@ -50,11 +60,13 @@ my %filename;
my %lcartists;
my %lcalbums;
-my $dbver = 1;
+my %dir2albumname;
+
+my $dbver = 2;
if(! -d $dir or $help) {
print "'$dir' is not a directory\n" if ($dir ne "" and ! -d $dir);
- print "songdb --path <dir> [--db <file>] [--strip <path>] [--verbose] [--help]\n";
+ print "songdb --path <dir> [--dirisalbum] [--dirisalbumname] [--db <file>] [--strip <path>] [--verbose] [--help]\n";
exit;
}
@@ -140,6 +152,7 @@ sub dodir {
# YEAR
# don't index songs without tags
+ # um. yes we do.
if (not defined $$id3{'ARTIST'} and
not defined $$id3{'ALBUM'} and
not defined $$id3{'TITLE'})
@@ -178,29 +191,56 @@ sub dodir {
# fallback names
$$id3{'ARTIST'} = "<no artist tag>" if ($$id3{'ARTIST'} eq "");
- # Fall back on the directory name (not full path dirname),
- # if no album tag
- $$id3{'ALBUM'} = (split m[/], $dir)[-1] if ($$id3{'ALBUM'} eq "");
- #if that doesn't work, fall back.
+ # Fall back on the directory name (not full path dirname),
+ # if no album tag
+ if ($dirisalbum) {
+ if($dir2albumname{$dir} eq "") {
+ $dir2albumname{$dir} = $$id3{'ALBUM'};
+ }
+ elsif($dir2albumname{$dir} ne $$id3{'ALBUM'}) {
+ $dir2albumname{$dir} = (split m[/], $dir)[-1];
+ }
+ }
+ # if no directory
+ if ($dirisalbumname) {
+ $$id3{'ALBUM'} = (split m[/], $dir)[-1] if ($$id3{'ALBUM'} eq "");
+ }
$$id3{'ALBUM'} = "<no album tag>" if ($$id3{'ALBUM'} eq "");
- # fall back on basename of the file if no title tag.
- my $base;
- ($base = $f) =~ s/\.\w+$//;
+ # fall back on basename of the file if no title tag.
+ my $base;
+ ($base = $f) =~ s/\.\w+$//;
$$id3{'TITLE'} = $base if ($$id3{'TITLE'} eq "");
# Append dirname, to handle multi-artist albums
$$id3{'DIR'} = $dir;
- my $albumid = $id3->{'ALBUM'}."___".$$id3{'DIR'};
-
- if($id3->{'ALBUM'}."___".$id3->{'DIR'} ne "<no album tag>___<no artist tag>") {
+ my $albumid;
+ if ($dirisalbum) {
+ $albumid=$$id3{'DIR'};
+ }
+ else {
+ $albumid= $id3->{'ALBUM'}."___".$$id3{'DIR'};
+ }
+ #printf "album id: %s\n", $albumid;
+
+# if($id3->{'ALBUM'}."___".$id3->{'DIR'} ne "<no album tag>___<no artist tag>") {
my $num = ++$albums{$albumid};
if($num > $maxsongperalbum) {
$maxsongperalbum = $num;
$longestalbum = $albumid;
}
$album2songs{$albumid}{$$id3{TITLE}} = $id3;
- $artist2albums{$$id3{ARTIST}}{$$id3{ALBUM}} = $id3;
- }
+ if($dirisalbum) {
+ $artist2albums{$$id3{ARTIST}}{$$id3{DIR}} = $id3;
+ }
+ else {
+ $artist2albums{$$id3{ARTIST}}{$$id3{ALBUM}} = $id3;
+ }
+# }
+ }
+
+ if($dirisalbum and $dir2albumname{$dir} eq "") {
+ $dir2albumname{$dir} = (split m[/], $dir)[-1];
+ printf "%s\n", $dir2albumname{$dir};
}
# extractdirs filters out only subdirectories from all given entries
@@ -217,17 +257,24 @@ dodir($dir);
print "\n";
print "File name table\n" if ($verbose);
-my $fc;
for(sort keys %entries) {
printf(" %s\n", $_) if ($verbose);
- $fc += length($_)+1;
+ my $l = length($_);
+ if($l > $maxfilelen) {
+ $maxfilelen = $l;
+ $longestfilename = $_;
+ }
}
+$maxfilelen++; # include zero termination byte
+while($maxfilelen&3) {
+ $maxfilelen++;
+}
my $maxsonglen = 0;
my $sc;
print "\nSong title table\n" if ($verbose);
-for(sort {$entries{$a}->{'TITLE'} cmp $entries{$b}->{'TITLE'}} keys %entries) {
+for(sort {uc($entries{$a}->{'TITLE'}) cmp uc($entries{$b}->{'TITLE'})} keys %entries) {
printf(" %s\n", $entries{$_}->{'TITLE'} ) if ($verbose);
my $l = length($entries{$_}->{'TITLE'});
if($l > $maxsonglen) {
@@ -244,8 +291,8 @@ my $maxartistlen = 0;
print "\nArtist table\n" if ($verbose);
my $i=0;
my %artistcount;
-for(sort keys %artists) {
- printf(" %s\n", $_) if ($verbose);
+for(sort {uc($a) cmp uc($b)} keys %artists) {
+ printf(" %s: %d\n", $_, $i) if ($verbose);
$artistcount{$_}=$i++;
my $l = length($_);
if($l > $maxartistlen) {
@@ -256,6 +303,7 @@ for(sort keys %artists) {
$l = scalar keys %{$artist2albums{$_}};
if ($l > $maxalbumsperartist) {
$maxalbumsperartist = $l;
+ $longestartistalbum = $_;
}
}
$maxartistlen++; # include zero termination byte
@@ -263,12 +311,22 @@ while($maxartistlen&3) {
$maxartistlen++;
}
-if ($verbose) {
- print "\nGenre table\n";
- for(sort keys %genres) {
- printf(" %s\n", $_);
- }
+print "\nGenre table\n" if ($verbose);
+for(sort keys %genres) {
+ my $l = length($_);
+ if($l > $maxgenrelen) {
+ $maxgenrelen = $l;
+ $longestgenrename = $_;
+ }
+}
+$maxgenrelen++; #include zero termination byte
+while($maxgenrelen&3) {
+ $maxgenrelen++;
+}
+
+
+if ($verbose) {
print "\nYear table\n";
for(sort keys %years) {
printf(" %s\n", $_);
@@ -279,14 +337,32 @@ print "\nAlbum table\n" if ($verbose);
my $maxalbumlen = 0;
my %albumcount;
$i=0;
-for(sort keys %albums) {
+my @albumssort;
+if($dirisalbum) {
+ @albumssort = sort {uc($dir2albumname{$a}) cmp uc($dir2albumname{$b})} keys %albums;
+}
+else {
+ @albumssort = sort {uc($a) cmp uc($b)} keys %albums;
+}
+for(@albumssort) {
my @moo=split(/___/, $_);
printf(" %s\n", $moo[0]) if ($verbose);
$albumcount{$_} = $i++;
- my $l = length($moo[0]);
+ my $l;
+ if($dirisalbum) {
+ $l = length($dir2albumname{$_});
+ }
+ else {
+ $l = length($moo[0]);
+ }
if($l > $maxalbumlen) {
$maxalbumlen = $l;
- $longestalbumname = $moo[0];
+ if($dirisalbum) {
+ $longestalbumname = $dir2albumname{$_};
+ }
+ else {
+ $longestalbumname = $moo[0];
+ }
}
}
$maxalbumlen++; # include zero termination byte
@@ -296,6 +372,14 @@ while($maxalbumlen&3) {
+sub dumpshort {
+ my ($num)=@_;
+
+ # print "int: $num\n";
+
+ print DB pack "n", $num;
+}
+
sub dumpint {
my ($num)=@_;
@@ -311,111 +395,124 @@ if (!scalar keys %entries) {
}
if ($db) {
- my $songentrysize = $maxsonglen + 12;
+ my $songentrysize = $maxsonglen + 12 + $maxgenrelen+ 4;
my $albumentrysize = $maxalbumlen + 4 + $maxsongperalbum*4;
my $artistentrysize = $maxartistlen + $maxalbumsperartist*4;
-
- printf "Number of artists : %d\n", scalar keys %artists;
- printf "Number of albums : %d\n", scalar keys %albums;
- printf "Number of songs : %d\n", scalar keys %entries;
- print "Max artist length : $maxartistlen ($longestartist)\n";
- print "Max album length : $maxalbumlen ($longestalbumname)\n";
- print "Max song length : $maxsonglen ($longestsong)\n";
- print "Max songs per album: $maxsongperalbum ($longestalbum)\n";
+ my $fileentrysize = $maxfilelen + 12;
+
+ printf "Number of artists : %d\n", scalar keys %artists;
+ printf "Number of albums : %d\n", scalar keys %albums;
+ printf "Number of songs / files : %d\n", scalar keys %entries;
+ print "Max artist length : $maxartistlen ($longestartist)\n";
+ print "Max album length : $maxalbumlen ($longestalbumname)\n";
+ print "Max song length : $maxsonglen ($longestsong)\n";
+ print "Max songs per album : $maxsongperalbum ($longestalbum)\n";
+ print "Max albums per artist: $maxalbumsperartist ($longestartistalbum)\n";
+ print "Max genre length : $maxgenrelen ($longestgenrename)\n";
+ print "Max file length : $maxfilelen ($longestfilename)\n";
print "Database version: $dbver\n" if ($verbose);
+ print "Song Entry Size : $songentrysize ($maxsonglen + 12 + $maxgenrelen + 4)\n" if ($verbose);
+ print "Album Entry Size: $albumentrysize ($maxalbumlen + 4 + $maxsongperalbum * 4)\n" if ($verbose);
+ print "Artist Entry Size: $artistentrysize ($maxartistlen + $maxalbumsperartist * 4)\n" if ($verbose);
+ print "File Entry Size: $fileentrysize ($maxfilelen + 12)\n" if ($verbose);
+
open(DB, ">$db") || die "couldn't make $db";
binmode(DB);
printf DB "RDB%c", $dbver;
- $pathindex = 48; # paths always start at index 48
+ $pathindex = 68; # paths always start at index 68
- $songindex = $pathindex + $fc; # fc is size of all paths
- $songindex++ while ($songindex & 3); # align to 32 bits
-
- dumpint($songindex); # file position index of song table
- dumpint(scalar(keys %entries)); # number of songs
- dumpint($maxsonglen); # length of song name field
+ $artistindex = $pathindex;
# set total size of song title table
$sc = scalar(keys %entries) * $songentrysize;
+ my $ac = scalar(keys %albums) * $albumentrysize;
+ my $arc = scalar(keys %artists) * $artistentrysize;
+ $albumindex = $artistindex + $arc; # arc is size of all artists
+ $songindex = $albumindex + $ac; # ac is size of all albums
+ my $fileindex = $songindex + $sc; # sc is size of all songs
- $albumindex = $songindex + $sc; # sc is size of all songs
+ dumpint($artistindex); # file position index of artist table
dumpint($albumindex); # file position index of album table
+ dumpint($songindex); # file position index of song table
+ dumpint($fileindex); # file position index of file table
+ dumpint(scalar(keys %artists)); # number of artists
dumpint(scalar(keys %albums)); # number of albums
+ dumpint(scalar(keys %entries)); # number of songs
+ dumpint(scalar(keys %entries)); # number of files
+ dumpint($maxartistlen); # length of artist name field
dumpint($maxalbumlen); # length of album name field
+ dumpint($maxsonglen); # length of song name field
+ dumpint($maxgenrelen); #length of genre field
+ dumpint($maxfilelen); # length of file field
dumpint($maxsongperalbum); # number of entries in songs-per-album array
-
- my $ac = scalar(keys %albums) * $albumentrysize;
-
- $artistindex = $albumindex + $ac; # ac is size of all albums
- dumpint($artistindex); # file position index of artist table
- dumpint(scalar(keys %artists)); # number of artists
- dumpint($maxartistlen); # length of artist name field
dumpint($maxalbumsperartist); # number of entries in albums-per-artist array
+ dumpint(-1); # rundb dirty
- my $l=0;
-
- #### TABLE of file names ###
- # path1
-
- my %filenamepos;
- for $f (sort keys %entries) {
- printf DB ("%s\x00", $f);
- $filenamepos{$f}= $l;
- $l += length($f)+1;
- }
- while ($l & 3) {
- print DB "\x00";
- $l++;
- }
-
- #### TABLE of songs ###
- # title of song1
- # pointer to artist of song1
- # pointer to album of song1
- # pointer to filename of song1
-
- my $offset = $songindex;
- for(sort {uc($entries{$a}->{'TITLE'}) cmp uc($entries{$b}->{'TITLE'})} keys %entries) {
- my $f = $_;
- my $id3 = $entries{$f};
- my $t = $id3->{'TITLE'};
- my $str = $t."\x00" x ($maxsonglen- length($t));
-
- print DB $str; # title
+ #### TABLE of artists ###
+ # name of artist1
+ # pointers to albums of artist1
- my $a = $artistcount{$id3->{'ARTIST'}} * $artistentrysize;
- dumpint($a + $artistindex); # pointer to artist of this song
+ for (sort {uc($a) cmp uc($b)} keys %artists) {
+ my $artist = $_;
+ my $str = $_."\x00" x ($maxartistlen - length($_));
+ print DB $str;
- $a = $albumcount{"$$id3{ALBUM}___$$id3{DIR}"} * $albumentrysize;
- dumpint($a + $albumindex); # pointer to album of this song
+ for (sort keys %{$artist2albums{$artist}}) {
+ my $id3 = $artist2albums{$artist}{$_};
+ my $a;
+ if($dirisalbum) {
+ $a = $albumcount{"$$id3{'DIR'}"} * $albumentrysize;
+ }
+ else {
+ $a = $albumcount{"$$id3{'ALBUM'}___$$id3{'DIR'}"} * $albumentrysize;
+ }
+ dumpint($a + $albumindex);
+ }
- # pointer to filename of this song
- dumpint($filenamepos{$f} + $pathindex);
+ for (scalar keys %{$artist2albums{$artist}} .. $maxalbumsperartist-1) {
+ print DB "\x00\x00\x00\x00";
+ }
- $$id3{'songoffset'} = $offset;
- $offset += $songentrysize;
}
+ ### Build song offset info.
+ my $offset = $songindex;
+ for(sort {uc($entries{$a}->{'TITLE'}) cmp uc($entries{$b}->{'TITLE'})} keys %entries) {
+ my $id3 = $entries{$_};
+ $$id3{'songoffset'} = $offset;
+ $offset += $songentrysize;
+ }
+
+
#### TABLE of albums ###
# name of album1
# pointers to artists of album1
# pointers to songs on album1
- for(sort {uc($a) cmp uc($b)} keys %albums) {
+ for(@albumssort) {
my $albumid = $_;
- my @moo=split(/___/, $_);
- my $t = $moo[0];
- my $str = $t."\x00" x ($maxalbumlen - length($t));
- print DB $str;
+ my @moo=split(/___/, $_);
+ my $t;
+ my $str;
+ if($dirisalbum) {
+ $t = $dir2albumname{$albumid};
+ }
+ else {
+ $t = $moo[0];
+ }
+ $str = $t."\x00" x ($maxalbumlen - length($t));
+ print DB $str;
my @songlist = keys %{$album2songs{$albumid}};
my $id3 = $album2songs{$albumid}{$songlist[0]};
+ #printf "(d) albumid: %s artist: %s\n",$albumid, $id3->{'ARTIST'};
+
my $aoffset = $artistcount{$id3->{'ARTIST'}} * $artistentrysize;
- dumpint($aoffset + $artistindex); # pointer to artist of this album
-
+ dumpint($aoffset + $artistindex); # pointer to artist of this album
+
if (defined $id3->{'TRACKNUM'}) {
@songlist = sort {
$album2songs{$albumid}{$a}->{'TRACKNUM'} <=>
@@ -435,26 +532,59 @@ if ($db) {
print DB "\x00\x00\x00\x00";
}
}
-
- #### TABLE of artists ###
- # name of artist1
- # pointers to albums of artist1
- for (sort {uc($a) cmp uc($b)} keys %artists) {
- my $artist = $_;
- my $str = $_."\x00" x ($maxartistlen - length($_));
- print DB $str;
+ #### Build filename offset info
+ my $l=$fileindex;
+ my %filenamepos;
+ for $f (sort keys %entries) {
+ $filenamepos{$f}= $l;
+ $l += $fileentrysize;
+ }
+
+ #### TABLE of songs ###
+ # title of song1
+ # pointer to artist of song1
+ # pointer to album of song1
+ # pointer to filename of song1
- for (sort keys %{$artist2albums{$artist}}) {
- my $id3 = $artist2albums{$artist}{$_};
- my $a = $albumcount{"$$id3{'ALBUM'}___$$id3{'DIR'}"} * $albumentrysize;
- dumpint($a + $albumindex);
- }
+ for(sort {uc($entries{$a}->{'TITLE'}) cmp uc($entries{$b}->{'TITLE'})} keys %entries) {
+ my $f = $_;
+ my $id3 = $entries{$f};
+ my $t = $id3->{'TITLE'};
+ my $g = $id3->{'GENRE'};
+ my $str = $t."\x00" x ($maxsonglen- length($t));
- for (scalar keys %{$artist2albums{$artist}} .. $maxalbumsperartist-1) {
- print DB "\x00\x00\x00\x00";
- }
+ print DB $str; # title
+ $str = $g."\x00" x ($maxgenrelen - length($g));
+
+ my $a = $artistcount{$id3->{'ARTIST'}} * $artistentrysize;
+ dumpint($a + $artistindex); # pointer to artist of this song
+
+ if($dirisalbum) {
+ $a = $albumcount{"$$id3{DIR}"} * $albumentrysize;
+ }
+ else {
+ $a = $albumcount{"$$id3{ALBUM}___$$id3{DIR}"} * $albumentrysize;
+ }
+ dumpint($a + $albumindex); # pointer to album of this song
+ # pointer to filename of this song
+ dumpint($filenamepos{$f});
+ print DB $str; #genre
+ dumpshort(-1);
+ dumpshort($id3->{'YEAR'});
+ }
+
+ #### TABLE of file names ###
+ # path1
+
+ for $f (sort keys %entries) {
+ my $str = $f."\x00" x ($maxfilelen- length($f));
+ my $id3 = $entries{$f};
+ print DB $str;
+ dumpint(0);
+ dumpint($id3->{'songoffset'});
+ dumpint(-1);
}
close(DB);