There are a couple other options for "normalizing" MP3 volume on OS X. One is iVolume which I've never tried. I read good things about it...but it costs money. Another is what I am going to focus on here: MacMP3Gain which is a port of the open source command-line program mp3gain for OS X (they also added a GUI).
mp3gain does more than just normalization, it does analysis to determine how quiet or loud an mp3 will sound to the human ear. If you really want to get technical, mp3gain does its analysis based on the Replay Gain algorithm. mp3gain applies lossless adjustment - it does not re-encode the mp3. However, MacMP3Gain offers this caveat about mp3gain, "MacMP3Gain modifies MP3 and unprotected AAC files with no provision provided to undo the changes." I haven't had any trouble after using extensively.
The MacMP3Gain application does have a GUI, which allows you to process by folder or by iTunes playlist. However, in the spirit of efficiency, I wanted a way to be able to normalize playlists right from iTunes. So I wrote this script which can be run right from the iTunes script menu. The other advantages of this script vs. the MacMP3Gain GUI is that it gives you a proper progress bar (important because it can take a long time to process), and it shows you the output when its done (so you can see exactly what changes were made to each file).
Prerequisites
MacMP3Gain - Install MacMP3Gain on your Mac. To use this applescript, you'll need to create a symlink from the command-line binary to somewhere in your path. This can be done with this command:
sudo ln -s /Applications/MacMP3Gain.app/Contents/Resources/aacgain /usr/bin/mp3gainYou can now use mp3gain on the command line. For a complete list of switches, open up Terminal and type:
mp3gain -?mp3gain is also available via MacPorts, if you use that. Though at the time of writing, the newest version was 1.7.0 while the version rolled into the Intel MacMP3Gain is 1.8.0. To install via ports do this:
sudo port install aacgain sudo ln -s /opt/local/bin/aacgain /usr/bin/mp3gainNote: if you don't want to use any symlinks then just update the "mp3gain" reference in the applescript to point to the full path of your installed aacgain program.
BP Progress Bar - mp3gain takes roughly 30 seconds to process each mp3. Therefore, it can take a while to process an entire playlist. So, I've configured this script with a handy progress indicator. Applescript has no "native" progress indicator method, but you can access an external app to do this for you. Download BP Progress Bar (download link), unzip it and mount the disk image. Then, copy the app "BP Progress Bar" to your "Applications" folder, and the "BP Progress Bar Controller.scpt" to your Scripts folder /Users/YOU/Library/Scripts/ (create if it doesn't exist) and you're all good to go!
Please Note: The first time you run this script, you might get the rainbow wheel for 10-20 seconds, and you'll probably get the "BP Progress Bar was downloaded from the internet" security warning. Both of these things happen only the first time.
Now, copy the script below to Script Editor, and save it as "normalize_playlist.scpt" in your iTunes scripts directory /Users/YOU/Library/iTunes/Scripts/ (create if it doesn't exist). This will allow you to run it from the iTunes script menu like below:

Upon launch, you're prompted to enter a playlist to normalize.

As long as you enter a good one, you should see a progress bar come up.

Upon completion you can view the log, which is written to /tmp/mp3gain_output.log.

Enjoy!
(*
Normalize Playlist
Accepts an itunes playlist as text input,
and normalizes all mp3 files on the playlist
with mp3gain -r (mp3gain itself decides how
best to normalize).
Prerequisities:
* mp3gain on command-line
* http://homepage.mac.com/beryrinaldo/AudioTron/MacMP3Gain/
* BP Progress Bar
* http://scriptbuilders.net/files/bpprogressbar1.0.html
*)
--Ask the use for the playlist
set myList to the text returned of (display dialog "Enter playlist to normalize " default answer "")
--exit if they didn't enter anyting
if the myList is "" then
display dialog "No playlist entered" giving up after 2
return
end if
--make sure itunes is running
--SHOULD BE if it's run from the itunes script menu
--but it could be executed directly
set itunesOK to my itunes_is_running()
if itunesOK is false then
tell application "iTunes"
activate
end tell
end if
tell application "iTunes"
set oldfi to fixed indexing
set fixed indexing to true
--see if the playlist exists
if exists user playlist myList then
--do nothing for now
else
--show error if the playlist doesn't exist
display dialog "Playlist does not exist" giving up after 2
return
end if
set currentList to playlist myList
--initialize progress bar
set ProgressBar to load script alias (((path to scripts folder) as text) & "BP Progress Bar Controller.scpt")
set myTitle to "Normalizing " & myList & " - may take several minutes"
tell ProgressBar to initialize(myTitle) -- title of progress bar
-- Start of Script to use ProgressBar Controller
tell ProgressBar
barberPole(true)
setStatusTop to "Initializing Volume Adjustment"
setStatusBottom to ""
end tell
--get the number of items on the playlist
set eop to index of last track of currentList
-- Stop the barber pole, set up for the progress bar
tell ProgressBar
barberPole(false)
setMax to eop -- to match the items to be processed below
setStatusTop to "Examining playlist"
end tell
--add a little progress so it doesn't start at 0
tell ProgressBar to increase by 1
with timeout of 10800 seconds --avoid "event timed out" error
--delete the logfile if it already exists
do shell script "if [ -e /tmp/mp3gain_output.log ]; then rm -f /tmp/mp3gain_output.log; fi;"
repeat with i from 1 to eop
--write current track to log
do shell script "echo \"------------ Track " & i & " of " & eop & " ------------\" >> /tmp/mp3gain_output.log"
--get the mac path to the mp3 file, name of the track, and extension
set i_location to (get location of track i of currentList)
set i_name to (get name of track i of currentList)
set theFileInfo to info for i_location
set ext to name extension of theFileInfo as string
--only do this if it's an mp3
if ext is "mp3" then
--convert mac path to POSIX path, quote it so we
--can use it on the cmd line
set mypath to POSIX path of i_location
set posixpath to quoted form of mypath
--create our command
--mp3gain is CPU-intensive, so pass thru nice
--write output of mp3gain to log
--this will allow us to report on what changes were made
set myCmd to "nice mp3gain -r -k -c -q " & posixpath & " >> /tmp/mp3gain_output.log"
--update progress window with status
tell ProgressBar
setStatusTop to "Processing file " & i & " of " & eop & " : " & i_name
setStatusBottom to "Full path: " & mypath
end tell
--execute the shell command
do shell script myCmd
else
--if track is not an mp3, don't process it
do shell script "echo \"Track " & posixpath & "is not an mp3...not processing\" >> /tmp/mp3gain_output.log"
end if --end if for is an mp3
tell ProgressBar to increase by 1
end repeat
end timeout
set fixed indexing to oldfi
end tell
tell ProgressBar to quit
--tell them we're done and ask if they want to see log
set seeLog to (display dialog ¬
"Done. Would you like to see the log? " with title ¬
"Normalization Complete" buttons {"Yes", "No"} ¬
default button "Yes")
set button_name to button returned of seeLog
if button_name is "Yes" then
--open log in textedit
tell application "TextEdit"
activate
open "/tmp/mp3gain_output.log"
end tell
end if
--be nice and clean up
do shell script "if [ -e /tmp/mp3gain_output.log ]; then rm -f /tmp/mp3gain_output.log; fi;"
return
--subroutine checks if itunes is running
on itunes_is_running()
tell application "System Events" to return (exists process "iTunes")
end itunes_is_running


I am tackling this problem right now and was glad when I came across your script and explanation. I created the symlink and installed the two software apps including your scripts to their respective places but I get this error after the progress bar appears: "The variable posixpath is not defined". I am running Snow Leopard perhaps it is an Applescript issue with the new OS. I would appreciate your help.
ReplyDeleteThanks - Loren