Use a third-party MP3 volume normalization tool in iTunes

Jan 07, '10 07:30:00AM

Contributed by: midget2000x

There are a couple of options for "normalizing" MP3 volume in iTunes in OS X. The first, of course, is iTunes' own Sound Check. If you use this feature and like it, then you may not need this hint. I disabled it because, with iTunes 9, I had a lot of problems importing large MP3 files -- it would often hang when determing the MP3's volume. Also, I was never able to tell the difference one way or the other -- playlists with songs from different albums still sounded uneven when Sound Check was enabled. If you love Sound Check and don't have any problems with it, this tip is not for you.

Another solution 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 adjustments -- 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, however.

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 AppleScript, which can be run right from the iTunes script menu:

(* 

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
(For possible code updates, as well as a number of screenshots and more detail on the entire process, please see my original blog post.)

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 it's done (so you can see exactly what changes were made to each file).

Prerequisites: Now, copy and paste the AppleScript to Script Editor, and save it as normalize_playlist.scpt in your user's iTunes scripts directory (/Users » your_user » Library » iTunes » Scripts). This will allow you to run the script from the iTunes script menu within iTunes.

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!

Comments (11)


Mac OS X Hints
http://hints.macworld.com/article.php?story=20091231081928881