Linux
Apache
MySQL
PHP

CSS
XHTML1.1
XML/RSS

Creative Commons

2007-11-28 11:29:26

WAV conversion with Perl

Most linux users know that if they want to make an audio cd from their mp3 collection it can be somewhat troublesome. Due to the licensing cost involved with the mp3 codec, it's not included by default in most distros of linux. Therefore, your cd burning programs can't convert the MP3s to WAVs so they can be burned to a cd and be playable in cd players. For those of you who don't know, those magic audio cds you buy in the store are just a bunch of WAV files on a cd. And if you're smart, you've realized that if you were to take WAV files and burn them directly to a cd, it would work. But when you choose "Audio CD" in your burning software, it goes through the extra step of hiding the actual WAV data and creating a CDA pointer that is visible. If you've ever put an audio cd in your computer and browsed it, you've seen these CDA files that are only 1K in size. Those are the pointers to the real data.
Woah, back on topic. In linux you need to have WAV files in order to make an audio cd. Some programs have plugins that you have to scour the internet to find, and I got sick of scouring. So I wrote a Perl script that uses mpg123 to convert MP3s to WAVs. It has some basic error checking to make sure you actually gave it an MP3 and not some other type of file.
#!/usr/bin/perl ######## # Help # ######## # Define our "bool" variable to see if we have a real argument $haveArg = 0; # See if the user forgot to supply arguments, or did something where we # want to show them the help page if (@ARGV[0] =~ /(^$|^-[^f])/) { HELP: @path = split(/\//, $0); $file = @path[@path - 1]; print "Usage: $file [-hf] file...\n\n"; print "\t$file MySong.mp3\n"; print "\t$file -f MyBrokenSong.mp3\n"; print "\t$file MySong.mp3 /music/* /var/*mp3\n"; exit(1); } elsif (@ARGV[0] =~ /^-f$/) { if (@ARGV[1] =~ /^$/) { goto HELP; } else { $haveArg = 1; } } #################### # Check for mpg123 # #################### # Take each directory in the PATH and put it into our array @sysPath = split(/:/, $ENV{'PATH'}); # Find out how many directories we have to look in $sysPathCount = @sysPath; # Create a tracker we'll set if mpg123 was found $exist = 0; for ($z = 0; $z < $sysPathCount; $z++) { # Create a full path to where mpg123 might be $searchString = "@sysPath[$z]/mpg123"; # If the file exists, set our tracker so we know if (-e $searchString) { $exist = 1; } } if (!$exist) { print "\nError: mpg123 not found in PATH\n\n"; print "mpg123 can be found at http://www.mpg123.de/\n"; exit(1); } ################ # Main Program # ################ # Find out how many files we have to convert $argCount = @ARGV; # Create a counter for the number of files we successfully convert $success = 0; # If we got the -f argument, the list of mp3s starts at index 1, not 0 if ($haveArg) { $y = 1; } else { $y = 0; } for ($y; $y < $argCount; $y++) { # Store each item into a variable, one at a time $mp3 = @ARGV[$y]; # Remove the newline character at the end of the filename $mp3 =~ s/\n//; # Determine what type of file we are working with by # redirecting the output of the `file` command to a stream. # We do this because using exec() or system() would throw # the output to the screen and we don't want that. open (FILETYPE, "file -b \"$mp3\" |"); # This loop should only run once, as `file` only gives 1 # line of output while (<FILETYPE>) { # If the current line of the stream contains "MP3" that # means that `file` determined it was MPEG-1 Layer 3 audio. # If it contains "MPEG ADTS" it's MPEG-2 Layer 3 audio. # Why can't there just be one?!?!?!?! if (uc($_) =~ /(MP3|MPEG ADTS)/ || $haveArg) { # Tell the user what we're about to do print "\n\nCreating " . $mp3 . ".wav\n"; # Create the command to convert the file $command = "mpg123 -w \"" . $mp3 . ".wav\" \""; $command .= $mp3 . "\""; # Execute the command system($command); # Increase our success counter $success++; } # If the file isn't a real MP3, tell the user he f'd up else { if (uc($mp3) =~ /MP3$/) { print "\n\nError: Not an MP3 (possible "; print "header corruption): " . $mp3 . "\n\n"; print "Try -f if you're sure this is an mp3."; } else { print "\n\nError: Not an MP3: " . $mp3; } } } # Close the stream since we're done with it this time around close FILETYPE; } print "\n\n\n******************************"; if ($haveArg) { print "\nForced $success of " . ($argCount - 1) . " files"; } else { print "\nConverted $success of $argCount files"; } print "\n******************************\n"; exit(1);


Back

6 comments


2007-12-03 15:15:28


Friedly Advisor says...
See mp3cd at http://outflux.net/software/pkgs/mp3cd/
This perl script implements the suggested conversion/sanitizing methods outlined in the Linux MP3 CD Burning HOWTO for converting a set of MP3s into a regular audio CD.

2007-12-03 15:59:51


slonkak says...
Hi Friedly Advisor. It's nice to see that you can spell. It's also nice to know that you're browsing my site from work (Raytheon)... shame shame. Anyway, mp3cd, though more feature-smashed than what I needed, looks like a pretty good script. I'll definitely give it a try.

2007-12-04 02:37:15


bat'Serjo says...
A looser is a looser till the end. If you had some more brain you would have realised what a useless lame dumb ass script you have written. And then you would have simply erased it and ashamed go kill your self. But no you so dum you proud of it and post on the net. You suck. You could have done the same shit in shell script and it would have been equaly lame and useless but no you l33t and c0d3 in P3r1. Wasting memory and forking/execing every loop cycle. Simply lame. You do not even qualify as a script kiddie.

P.S. This is your first P333rl script isn't it?

2007-12-04 08:41:16


slonkak says...
No, this isn't my first perl script. Perl is much easier than shell script to write. And you're either 13 or Bulgaria has a worthless educational system. Thanks for the words of wisdom, though!

2007-12-08 13:08:55


Iain says...
Who cares about RAM use? What's it using, a few extra kilobytes? A whole extra megabyte? It does the job, and it's fun to write scripts, even if there's practically no need since every program under the sun has been written by now. Good job.

2007-12-08 13:23:40


slonkak says...
Thanks Iain. Most things anyone needs to do _have_ already been done, but I like to figure it out for myself. It's the only way to learn ;)

Post a comment!

Name:
Comment: