#!/usr/bin/perl # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Library General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #Modified version of the original mp32dao distributed with cdrdao. #Now with cdtext, mp3 and ogg support #Support for cdrecord: builds .inf files #Giuseppe Corbelli #Original code by Joe Steward use FindBin; use lib $FindBin::Bin; use Cwd; use strict; use MediaHandler; use Audio::Wav; use Audio::Tools::Time; my $wav = new Audio::Wav; my ($count, $totalsamples, $divided, $rounded, $remainder, $artist, $album, $total, $song, $fh); my $cdtext = 1; my $samplestart = 0; my (@tracklist, @filelist); print "-------- MP3-to-DAO Helper Script ---------\n"; print "Usage: mp32dao.pl [tocfile]\n"; my $tocfile = $ARGV[0]; unless ($tocfile) { $tocfile = "cd.toc"; warn "No toc file specified, using default \"cd.toc\"\n"; } my ($list) = MediaHandler->new (getcwd()); die "No supported media files found!\n" if ($list->total == 0); #Creates array of mediahandlers, sets artist and album. foreach my $file (@{$list->list}) { if (!$file->artist || !$file->title || !$file->album) {$cdtext = 0}; #Sets artist and album name if ($cdtext) { #If artist is still not defined define as in first song tag if (!$artist) { $artist=$file->artist; } #If different artists mark as VVAA if ( ! $artist =~ /\s*\Q$file->artist\E\s*/i) { $artist = "Various Artists"; } #Same for album name if (!$album) { $album = $file->album } if (! $album =~ m/\Q$file->album\E/i) {$album = "Compilation"}; } } open ($fh, ">$tocfile") or die "Couldn't open $tocfile for write!\n"; tocfile_header($fh, $cdtext, $album, $artist); #Set outputfiles and decode to wav. print "\nDecoding compressed files to wav\n"; foreach my $file (@{$list->list}) { if ( $_=($file->to_wav) != 0 ) { printf ("\n\tWARNING: decoder for file %s exited with code %d\n", $file->Filename, $_); } } $count=0; print "\nAnalyzing wav files and creating toc\n\n"; while ($count <= ($list->total-1)) { my $file = ${$list->list}[$count]; my $read = $wav->read($file->Outfile); my $audio_bytes = $read->length; my $time = Audio::Tools::Time->new (44100, 16, 2); my $sample = $time->bytes_to_samples($audio_bytes); tocfile_entry ($fh, $cdtext, $file, $samplestart, $count+1); #if ($cdtext) {build_inf ($file, $count)}; if ($cdtext) {$file->write_inf ($count+1)}; $totalsamples = $sample - $samplestart; $divided = $totalsamples / 588; $rounded = int($divided) * 588; $remainder = $totalsamples - $rounded; printf ("\tNeed to pad up %d samples for track %d\n", $remainder, $count+1); if (($remainder != 0) && ($count ne ($list->total-1))) { my $nextfile = ${$list->list}[$count+1]; print $fh "FILE \"".$nextfile->Outfile."\" "; print $fh "0 $remainder\n\n"; $samplestart = $remainder; } $count++; } print "\nFinished writing TOC/inf files. You may now burn the CD using\n\ \tcdrdao write $tocfile\ \tcdrecord dev=X,Y,Z -useinfo -dao -text -audio *.wav\n\n"; print "You may want to normalize wav files right now.\n"; close ($fh); exit; sub seconds_to_cd_time { my $seconds = shift; my ($minutes, $frames); my $minute_increment = int($seconds / 60); if ($minute_increment) { $seconds = $seconds - ($minute_increment * 60); $minutes = $minutes + $minute_increment; } my $decimal = $seconds - int($seconds); if ($decimal) { $frames = int($decimal * 75); } return sprintf ("%02d:%02d:%02d", $minutes, $seconds, $frames); } #Arguments: # fh: filehandle opened for writing # cdtext: if != 0 cdtext info wanted # title: only if cdtext wanted, is the album title # performer: only if cdtext wanted, is the album performer sub tocfile_header { my ($fh, $cdtext, $title, $performer) = @_; print $fh "CD_DA\n"; if ($cdtext) { print $fh "CD_TEXT \{\n"; print $fh "\tLANGUAGE_MAP \{\n"; print $fh "\t\t0 : EN\n"; print $fh "\t\}\n\n"; print $fh "\tLANGUAGE 0 \{\n"; print $fh "\t\tTITLE \"$title\"\n"; print $fh "\t\tPERFORMER \"$performer\"\n"; #print $fh "\t\tDISC_ID \"XY12345\"\n"; #print $fh "\t\tUPC_EAN \"\"\n"; print $fh "\t\}\n"; print $fh "\}\n"; } } #Arguments: # fh: Filehandle opened for writing # cdtext: scalar != 0 if cdtext ON # song: reference to song structure # samplestart: scalar containing sample offset # count: track number sub tocfile_entry { my ($fh, $cdtext, $song, $samplestart, $count) = @_; print $fh "// Track $count\n"; print $fh "TRACK AUDIO\n"; print $fh "TWO_CHANNEL_AUDIO\n"; if ($cdtext) { print $fh "CD_TEXT {\n"; print $fh "\tLANGUAGE 0 {\n"; print $fh "\t\tTITLE \"".$song->title."\"\n"; print $fh "\t\tPERFORMER \"".$song->artist."\"\n"; #print $fh "\t\tISRC \"US-XX1-98-01234\"\n"; print $fh "\t}\n}\n"; } print $fh "FILE \"".$song->Outfile."\" "; print $fh "$samplestart"; print $fh "\n"; }