#!/usr/bin/perl my $sum1 = 0; # That I declare my variables at the top of the script my $sum2 = 0; # demonstrates that I spend more time writing C code. my $tracknum = 1; # these days. my %discinfo; if ($ARGV[0]) { # If an alternate file is specified on the command line, use it. open(DISCINFO, $ARGV[0]) or die "error opening $ARGV[0]: $!"; } else { # Otherwise, use the default file location. open(DISCINFO, "/CDROM/info.disc") or die "error opening /CDROM/info.disc: $!"; } while () # Damn I love parsing text files in Perl. { # Amazing how three lines of Perl can turn these files into an easily # accessed set of variables, isn't it? ($key, $value) = split(/: /, $_); chomp($value); $discinfo{$key} = $value; } close(DISCINFO); # This section generates the checksum (though I'm not sure it can really be called # a checksum) that is the first element of the ID string. I don't know why they # do it this way, I suppose they figure this is the best way. But, whatever works. while ($tracknum <= $discinfo{"album.tracks"}) { $sum1 += &calculate_sum(&to_seconds($discinfo{"track$tracknum.start"})); ++$tracknum; } $sum2 = &to_seconds($discinfo{"album.duration"}) - &to_seconds($discinfo{"track1.start"}); printf("%08x ", $sum1 % 255 << 24 | $sum2 << 8 | $discinfo{"album.tracks"}); # Next comes the number of tracks on the CD. print $discinfo{"album.tracks"}, " "; # Reset this variable back to 1 so I can re-use it. Hey, I believe in recycling. $tracknum = 1; while ($tracknum <= $discinfo{"album.tracks"}) { # This converts each track offset to frames and then prints it out. print &to_frames($discinfo{"track$tracknum.start"}), " "; ++$tracknum; } # Last element of the ID string, the album duration in seconds. For some reason # the info.disc files always list the albums as 2 seconds longer than the discid.c # source did, so I just subtract 2 from this to make them conform to what CDDB wants. print (&to_seconds($discinfo{"album.duration"}) - 2); print "\n"; exit(0); # Subroutine to generate the checksums for the first ID element. sub calculate_sum { my $seconds = shift(@_); my $retval = 0; while ($seconds > 0) { $retval += $seconds % 10; $seconds /= 10; } return($retval); } # Subroutine to convert the minutes:seconds:frames strings to just frames. sub to_frames { my $dirty = shift @_; my $minutes = 0; my $seconds = 0; my $frames = 0; ($minutes, $seconds, $frames) = split(/:/, $dirty); $frames += (($minutes * 60) + $seconds) * 75; return($frames); } # Subroutine to convert the minutes:seconds:frames strings to just seconds. # Note that the extra frames are truncated by this; it's supposed to be # like that in order to return values like what CDDB wants. sub to_seconds { my $dirty = shift @_; my $minutes = 0; my $seconds = 0; ($minutes, $seconds) = split(/:/, $dirty); $seconds += $minutes * 60; return($seconds); }