summaryrefslogtreecommitdiffstats
path: root/tools/songdb.pl
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2004-10-20 21:40:04 +0000
committerDaniel Stenberg <daniel@haxx.se>2004-10-20 21:40:04 +0000
commit8c58eee1e6e11514ba1c712bfb6ff7249e503954 (patch)
tree8b7451ffb8dcc864df865f5ffe581afbf145141c /tools/songdb.pl
parentc100a42ac01271dffee0cb18e8fb22df1e735b28 (diff)
downloadrockbox-8c58eee1e6e11514ba1c712bfb6ff7249e503954.tar.gz
rockbox-8c58eee1e6e11514ba1c712bfb6ff7249e503954.tar.bz2
rockbox-8c58eee1e6e11514ba1c712bfb6ff7249e503954.zip
Closing in on the TagDatabase 1.7 spec
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@5314 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'tools/songdb.pl')
-rwxr-xr-xtools/songdb.pl178
1 files changed, 174 insertions, 4 deletions
diff --git a/tools/songdb.pl b/tools/songdb.pl
index 73c8e94c09..7d0d203e3e 100755
--- a/tools/songdb.pl
+++ b/tools/songdb.pl
@@ -5,16 +5,45 @@
# MP3::Info is installed on debian using package 'libmp3-info-perl'
+# Rockbox song database docs:
+# http://www.rockbox.org/twiki/bin/view/Main/TagDatabase
+
use MP3::Info;
-my $dir = $ARGV[0];
+my $db;
+my $dir;
+my $strip;
+while($ARGV[0]) {
+ if($ARGV[0] eq "--db") {
+ $db = $ARGV[1];
+ shift @ARGV;
+ shift @ARGV;
+ }
+ elsif($ARGV[0] eq "--path") {
+ $dir = $ARGV[1];
+ shift @ARGV;
+ shift @ARGV;
+ }
+ elsif($ARGV[0] eq "--strip") {
+ $strip = $ARGV[1];
+ shift @ARGV;
+ shift @ARGV;
+ }
+ else {
+ shift @ARGV;
+ }
+}
my %entries;
my %genres;
my %albums;
my %years;
+my %filename;
+
+my $dbver = 1;
if(! -d $dir) {
+ print "songdb [--db <file>] --path <dir> [--strip <path>]\n";
print "given argument is not a directory!\n";
exit;
}
@@ -66,6 +95,8 @@ sub singlefile {
return $hash; # a hash reference
}
+my $maxsongperalbum;
+
sub dodir {
my ($dir)=@_;
@@ -91,15 +122,21 @@ sub dodir {
#printf "Artist: %s\n", $id3->{'ARTIST'};
$entries{"$dir/$f"}= $id3;
-
+ $filename{$id3}="$dir/$f";
$artists{$id3->{'ARTIST'}}++ if($id3->{'ARTIST'});
$genres{$id3->{'GENRE'}}++ if($id3->{'GENRE'});
$years{$id3->{'YEAR'}}++ if($id3->{'YEAR'});
+ $id3->{'FILE'}="$dir/$f"; # store file name
+
# prepend Artist name to handle duplicate album names from other
# artists
- $albums{$id3->{'ARTIST'}."___".$id3->{'ALBUM'}}++ if($id3->{'ALBUM'});
-
+ if($id3->{'ALBUM'}) {
+ my $num = $albums{$id3->{'ARTIST'}."___".$id3->{'ALBUM'}}++;
+ if($num > $maxsongperalbum) {
+ $maxsongperalbum = $num;
+ }
+ }
}
# extractdirs filters out only subdirectories from all given entries
@@ -115,19 +152,40 @@ sub dodir {
dodir($dir);
print "File name table\n";
+my $fc;
for(sort keys %entries) {
printf(" %s\n", $_);
+ $fc += length($_)+1;
}
+my $maxsonglen;
print "\nSong title table\n";
#for(sort {$entries{$a}->{'TITLE'} cmp $entries{$b}->{'TITLE'}} %entries) {
for(sort {$entries{$a}->{'TITLE'} cmp $entries{$b}->{'TITLE'}} keys %entries) {
printf(" %s\n", $entries{$_}->{'TITLE'} );
+ my $l = length($entries{$_}->{'TITLE'});
+ if($l > $maxsonglen) {
+ $maxsonglen = $l;
+ }
+}
+while($maxsonglen&3) {
+ $maxsonglen++;
}
+my $maxaristlen;
print "\nArtist table\n";
+my $i=0;
+my %artistcount;
for(sort keys %artists) {
printf(" %s\n", $_);
+ $artistcount{$_}=$i++;
+ my $l = length($_);
+ if($l > $maxaristlen) {
+ $maxaristlen = $l;
+ }
+}
+while($maxaristlen&3) {
+ $maxaristlen++;
}
print "\nGenre table\n";
@@ -141,7 +199,119 @@ for(sort keys %years) {
}
print "\nAlbum table\n";
+my $maxalbumlen;
+my %albumcount;
+$i=0;
for(sort keys %albums) {
my @moo=split(/___/, $_);
printf(" %s\n", $moo[1]);
+ $albumcount{$moo[1]} = $i++;
+ my $l = length($moo[1]);
+ if($l > $maxalbumlen) {
+ $maxalbumlen = $l;
+ }
+}
+while($maxalbumlen&3) {
+ $maxalbumlen++;
+}
+
+
+sub dumpint {
+ my ($num)=@_;
+
+# print STDERR "int: $num\n";
+
+ printf DB ("%c%c%c%c",
+ $num>>24,
+ ($num&0xff0000)>>16,
+ ($num&0xff00)>>8,
+ ($num&0xff));
+}
+
+if($db) {
+ print STDERR "\nCreating db $db\n";
+
+ print STDERR "Max song length: $maxsonglen\n";
+ print STDERR "Max album length: $maxalbumlen\n";
+ print STDERR "Database version: $dbver\n";
+
+ open(DB, ">$db") || die "couldn't make $db";
+ printf DB "RDB%c", $dbver;
+
+ dumpint(48); # file position index of song table
+ dumpint(scalar(keys %entries)); # number of songs
+ dumpint($maxsonglen); # length of song name field
+
+ dumpint(48 + $fc); # file position index of album table
+ dumpint(scalar(keys %albums)); # number of albums
+ dumpint($maxalbumlen); # length of album name field
+ dumpint($maxsongperalbum); # number of entries in songs-per-album array
+
+ my $ac = ($maxalbumlen + 8 ) * scalar(keys %albums);
+
+ dumpint(48 + $fc + $ac); # file position index of artist table
+ dumpint(scalar(keys %artists)); # number of artists
+ dumpint($maxaristlen); # length of artist name field
+ dumpint($maxalbumsperartist); # number of entries in albums-per-artist array
+
+ # 12 x 4 = 48 bytes written before this point
+ my $l=48;
+
+ #### TABLE of file names ###
+ # path1
+
+ my %filenamepos;
+ for $f (sort keys %entries) {
+ printf DB ("%s\x00", $f);
+ $filenamepos{$f}= $l;
+ $l += length($f)+1;
+ }
+
+ #### TABLE of songs ###
+ # title of song1
+ # pointer to artist of song1
+ # pointer to album of song1
+ # pointer to filename of song1
+
+ for(sort {$entries{$a}->{'TITLE'} cmp $entries{$b}->{'TITLE'}} keys %entries) {
+ my $f = $_;
+ my $id3 = $entries{$f};
+ my $t = $id3->{'TITLE'};
+ my $str = $t."\x00" x ($maxsonglen- length($t));
+ printf DB ("%s\x00", $str); # title
+
+ my $a = $artistcount{$id3->{'ARTIST'}} * $maxaristlen;
+ dumpint($a); # pointer to artist of this song
+
+ $a = $albumcount{$id3->{'ALBUM'}} * $maxalbumlen;
+ dumpint($a); # pointer to album of this song
+
+ # pointer to filename of this song
+ dumpint($filenamepos{$id3->{'FILE'}});
+ }
+
+ #### TABLE of albums ###
+ # name of album1
+ # pointers to artists of album1
+ # pointers to songs on album1
+
+ for(sort keys %albums) {
+ my @moo=split(/___/, $_);
+ my $t = $moo[1];
+ my $str = $t."\x00" x ($maxalbumlen - length($t));
+ printf DB ("%s\x00", $str);
+
+ dumpint(14); # pointers to artists of album1
+ dumpint(15); # pointers to songs on album1
+ }
+
+ #### TABLE of artists ###
+ # name of artist1
+ # pointers to albums of artist1
+
+ for(sort keys %artists) {
+ printf DB ("%s\x00", $_);
+ }
+
+ close(DB);
}