Per-album volume leveling

Download and get help for different MediaMonkey Addons.

Moderators: Peke, Gurus

Sarkos
Posts: 4
Joined: Fri Aug 19, 2005 4:07 am

Per-album volume leveling

Post by Sarkos » Fri Aug 19, 2005 5:42 am

I'd like an option to calculate volume leveling on a per-album basis, rather than a per-track basis. Since most albums are professionally mixed, the volume shouldn't really be changing from track to track.

Adamo
Posts: 11
Joined: Mon Aug 08, 2005 10:54 am
Location: Massachusetts

Re: Per-album volume leveling

Post by Adamo » Fri Aug 19, 2005 7:25 am

I agree. This is a great idea for us aurally obsessed users.

onkel_enno
Posts: 2146
Joined: Fri Jan 14, 2005 1:45 am
Location: Germany
Contact:

Post by onkel_enno » Fri Aug 19, 2005 8:47 am

Album Leveling means that the whole Album is leveled by the loudest track of that album, right?

I made a short script which makes that. Please try it and give me your feedback. Please make a Backup of your My Music\MediaMonkey\MediaMonkey.mdb before testing. Thanks

Code: Select all

...
I hope it will help you.
Last edited by onkel_enno on Mon Aug 22, 2005 5:56 am, edited 1 time in total.
SansaMonkey - for SanDisk Sansa and Rockbox Users

Please no PMs for Questions which should be asked in the Forum. Thx

Adamo
Posts: 11
Joined: Mon Aug 08, 2005 10:54 am
Location: Massachusetts

Post by Adamo » Fri Aug 19, 2005 11:10 am

This is very useful. Thanks. But doesn't this level everything to the quietest track (i.e. thae track whose volume has been decreased by the least amount)?

I think replacing the first For-Next with this one will fix it.

Code: Select all

# see onkel's below
Please correct me if I'm wrong.
Last edited by Adamo on Mon Aug 22, 2005 7:53 am, edited 2 times in total.

onkel_enno
Posts: 2146
Joined: Fri Jan 14, 2005 1:45 am
Location: Germany
Contact:

Post by onkel_enno » Mon Aug 22, 2005 1:43 am

Adamo wrote:But doesn't this level everything to the quietest track (i.e. thae track whose volume has been decreased by the least amount)?
I think you are right. I don't really understand why the amount is stored by which the volume of the track should be increased/decreases and not the real Volume Level but that's not my part.

The Code should then be so:

Code: Select all

Option Explicit
'This Script will set the Volume Level of all selected Songs
'to the Volume Level of the loudest Song

'1. Create a file AlbumVolumeLevel.vbs in MediaMonkey\Scripts and paste these lines
'2. Add these Section to Scripts.ini

'[AlbumVolumeLevel]
'FileName=AlbumVolumeLevel.vbs
'ProcName=AlbumLevel
'Order=12
'DisplayName=Analyze Album Volume
'Description=Analyze Album Volume
'Language=VBScript
'ScriptType=0

'3. restart MediMonkey
'4. you'll find "Analyze Album Volume" in Tools\Scripts

Sub AlbumLevel
Dim List
Dim Song
Dim strTemp
Dim Result
Dim i
Dim maxVolume

maxVolume = 999999

	Set List = SDB.SelectedSongList
	strTemp = "selected"
	If List.Count=0 Then 
		Set List = SDB.AllVisibleSongList
		strTemp = "visible"
	end if
	
	Result = SDB.MessageBox("Realy level all " & strTemp & " Tracks?", 0, Array(0, 2))
	if Result = 6 then 'YES
		For i=0 To List.Count-1
			Set Song = List.Item(i)
			if Song.Leveling = -999999 then
				SDB.MessageBox """" & Song.Title & """ isn't analyzed yet!", 1, Array(4)
				exit sub
			else
				if Song.Leveling < maxVolume then maxVolume = Song.Leveling
			end if
		next
		
		For i=0 To List.Count-1
			Set Song = List.Item(i)
			Song.Leveling = maxVolume
			Song.UpdateDB
		next
	end if

End Sub
Feedback?
Last edited by onkel_enno on Mon Aug 22, 2005 5:55 am, edited 1 time in total.
SansaMonkey - for SanDisk Sansa and Rockbox Users

Please no PMs for Questions which should be asked in the Forum. Thx

Sarkos
Posts: 4
Joined: Fri Aug 19, 2005 4:07 am

Post by Sarkos » Mon Aug 22, 2005 5:52 am

Very cool thanks! (except you left out an = between strTemp and "visible" :))

Just wondering: is this the technique MediaMonkey uses to analyze track volume? Just find the loudest bit and reduce the whole song to that level? It seems a bit simplistic... oh well, as long as it works...

onkel_enno
Posts: 2146
Joined: Fri Jan 14, 2005 1:45 am
Location: Germany
Contact:

Post by onkel_enno » Mon Aug 22, 2005 5:55 am

Sarkos wrote:Very cool thanks! (except you left out an = between strTemp and "visible" :))
Ups :oops: :D
Sarkos wrote:Just wondering: is this the technique MediaMonkey uses to analyze track volume? Just find the loudest bit and reduce the whole song to that level? It seems a bit simplistic... oh well, as long as it works...


Maybe Jiri can say s.th. to this.
SansaMonkey - for SanDisk Sansa and Rockbox Users

Please no PMs for Questions which should be asked in the Forum. Thx

Sjettepet
Posts: 7
Joined: Fri Aug 19, 2005 6:17 am
Location: The Netherlands

Post by Sjettepet » Mon Aug 22, 2005 6:36 am

This IS the kind of volume leveling that I have been waiting for... if it works. But I have my doubts:

a) As far as I understand this script, I will have to run it per album - i.e. open each album, select the tracks and run the script. This would be a tremendous job since I have around 750 albums in my library. Is there a way to select all tracks, have the script sort out to which album the track belongs, group tracks per album and then level the volume?

b) Then again, does this script REALLY do what we want? I understand from Sarkos that he wants to prevent albums that were recorded/mastered louder than others to "stick out". At least this is what I would welcome!. So a script should seek for the highest (or average) volume bit for every album, than compare these levels AMONG ALBUMS and volume level all albums to the volume level of the album with the highest (or average, or lowest) volume level. There would be no difference in amount of volume levelling between tracks on one album.

I don't see how the proposed script could have the required result. It seems to be aimed at controlling volume levelling per album, which is nice but not what the topicstarter requested I.M.H.O.

Sjettepet

Sjettepet
Posts: 7
Joined: Fri Aug 19, 2005 6:17 am
Location: The Netherlands

Post by Sjettepet » Mon Aug 22, 2005 6:50 am

onkel_enno wrote:Album Leveling means that the whole Album is leveled by the loudest track of that album, right?
Err, I don't think so Onkel. I would describe it as levelling albums rather than tracks.

For example, the result of corrent volume leveling implementation may look like this:

Album A:
track 1: -4.3
track 2: +0.9
track 3: -0.6

Album B:
track 1: +2.1
track 2: +1.3
track 3: - 5.4

This means that the difference in volume level between tracks on a given album is affected. And, as the topic starter rightly points out, this should not be desired since most albums have been professionally mastered.

In the above result, Album A may, after volume leveling, still "sound" at a higher or lower volume than Album B, simply because the original was mastered at a different overall volume.

Album Leveling such as Sarkos proposes would be very sensible and very welcome. It's result would look more like something like this:

Album A:
track 1: -2.1
track 2: -2.1
track 3: -2.1

Average bit volume on Album A: 60dB (or highest: 87dB)

Album B:
track 1: +0.3
track 2: +0.3
track 3: +0.3

Average bit volume on Album A: 60dB (or highest: 87dB)

The numbers given have no mathematical meaning but just serve as an example to indicate the difference between the two sorts of volume leveling.

With Album Leveling all albums would sound as if they had been recorded/mastered at the same level, while the dynamics between the tracks would be preserved. Current volume leveling kills dynamic range of an album.

Sjettepet

onkel_enno
Posts: 2146
Joined: Fri Jan 14, 2005 1:45 am
Location: Germany
Contact:

Post by onkel_enno » Mon Aug 22, 2005 7:14 am

Sjettepet wrote:With Album Leveling all albums would sound as if they had been recorded/mastered at the same level, while the dynamics between the tracks would be preserved.
I still believe that the Script does exactly what you're describing.

I copied s.th. from the Audiograbber-Help:
Normalizing means how loud a track is recorded. Different CD's, just like LP's from the old days, are usually recorded at different volumes. All tracks on the same CD are individually, recorded at about the same level and as long as one listens to only one CD at a time there is usually no problem with the loudness of the CD.

The problem starts when you mix tracks from different CD's because they occasionally have an output level that differs from one CD to another. One CD can play quite loud and another noticeably quieter. The normalize function comes in handy in these cases and you can select the same level for all your CD's.

Most of the CD's are properly recorded and the normal level is usually between 95-99 %. By choosing to normalize only the tracks normalized to less than about 91 %, your result will be that all the songs will have approximately the same volume and most tracks will be left in their original condition. These percentage values detect when the sound is loudest on the track. Normalize to 0% means absolute silence.
Audiograbber uses percentage, not dB.

IMHO if for track volume the loudest sound is important, than for album volume it should be the loudest track.

@Sjettepet
Surely it is possible to write a script that does it for all albums, but let's wait and see if it's correct this way or not.
SansaMonkey - for SanDisk Sansa and Rockbox Users

Please no PMs for Questions which should be asked in the Forum. Thx

Adamo
Posts: 11
Joined: Mon Aug 08, 2005 10:54 am
Location: Massachusetts

Post by Adamo » Mon Aug 22, 2005 8:00 am

onkel_enno wrote:I don't really understand why the amount is stored by which the volume of the track should be increased/decreases and not the real Volume Level.
Thanks writing a much more elegent fix than mine. As for why the actual (corrected) volume is not used as the stored value, this is probably because all of the values would end up being the same. MM is levelling each and every track to one target dB value (zero?). So, the only meaningful value would be the difference between original and corrected.

Of course, the ORIGINAL volume of the track would be useful to know, but might prove to be even more confusing to the average user.

Sarkos
Posts: 4
Joined: Fri Aug 19, 2005 4:07 am

script

Post by Sarkos » Mon Aug 22, 2005 12:02 pm

I rewrote onkel_enno's script to do all your albums at once. It works ok on my pc. Use it at your own risk :o

I'm starting to think this conversation should be moved to the Scripts forum... I apologise for the long post but I don't have a website to put the script on :(

If you want to debug, uncomment the SDB.MessageBox line near the bottom, and comment out the next 2 lines.

Code: Select all

Option Explicit
'This Script will set the Volume Level of all selected Songs
'to the Volume Level of the loudest Song

'1. Create a file AlbumVolumeLevel.vbs in MediaMonkey\Scripts and paste these lines
'2. Add this Section to Scripts.ini

'[AlbumVolumeLevel]
'FileName=AlbumVolumeLevel.vbs
'ProcName=AlbumLevel
'Order=12
'DisplayName=Analyze Album Volume
'Description=Analyze Album Volume
'Language=VBScript
'ScriptType=0

'3. restart MediaMonkey
'4. you'll find "Analyze Album Volume" in Tools\Scripts

sub AlbumLevel

	dim list
	dim song
	dim result
	dim i
	dim albumMap
	dim albumId
	dim level
	
	set albumMap = CreateObject( "Scripting.Dictionary" )
	set list = SDB.CurrentSongList
	
	if list.Count = 0 then
		set list = SDB.AllVisibleSongList
		if list.Count = 0 then
			SDB.MessageBox "No tracks selected", mtError, Array(mbOK)
			exit sub
		end if
	end if
	
	result = SDB.MessageBox( "Are you sure you want to level " & list.Count & " track(s)?", mtConfirmation, Array( mbOK, mbCancel ) )
	if result = mrOk then
		for i = 0 to list.Count - 1
			set song = list.Item(i)
			albumId = song.Album.ID
			level = song.Leveling
			if level <> -999999 and albumId > 0 then ' if the song has been levelled and is part of an album
				if albumMap.exists( albumId ) then ' if there is a min level for this album
					if level < albumMap.Item( albumId ) then ' check this song level against the min level
						albumMap.Item( albumId ) = level ' assign if lower
					end if
				else
					albumMap.add albumId, level
				end if
			end if
		next
		
		for i = 0 to list.Count - 1
			set song = list.Item(i)
			albumId = song.Album.ID
			if albumId > 0 and albumMap.exists( albumId ) then
'				SDB.MessageBox """" & song.Title & """ from " & song.Leveling & " to " & albumMap.Item( albumId ), mtInformation, Array(mbOK)
				song.Leveling = albumMap.Item(albumId)
				song.UpdateDB
			end if
		next
	end if

end sub

Adamo
Posts: 11
Joined: Mon Aug 08, 2005 10:54 am
Location: Massachusetts

Re: script

Post by Adamo » Mon Aug 22, 2005 12:43 pm

Sarkos wrote:Use it at your own risk :o
Throwing caution to the wind, ran on entire library. Works great. Great work.

Sjettepet
Posts: 7
Joined: Fri Aug 19, 2005 6:17 am
Location: The Netherlands

Post by Sjettepet » Mon Aug 22, 2005 12:51 pm

O.k. I can't wait to try it myself. It would make me an even happier monkey! I'll report back.

Sjettepet

Sjettepet
Posts: 7
Joined: Fri Aug 19, 2005 6:17 am
Location: The Netherlands

Post by Sjettepet » Mon Aug 22, 2005 1:05 pm

Tried it on 7 albums, but I after the confirmation I got no progress indicator or any sign that the script had finished. Also the "leveling" column remains blank. What is normal behaviour? Did I do something wrong?

Sjettepet

Post Reply