There are also other limitations on how the Sonos systems interpret ReplayGain. It is thought that there is a maximum adjustment of 10dB and also that +ve adjustment is at least scaled back or maybe not implemented at all due to the risk of clipping.
To get around this problem I have written this short script which adds a new menu cluster to the Tools Analyze Volume section - "Set Sonos ReplayGain". This has three options - "Set Album ReplayGain" which copies the Album value into the Track field thus fooling the Sonos system, "Reset Track ReplayGain" which restores the Track value and "Clear ReplayGain" which wipes out all the values to switch ReplayGain off. To address the lack of +ve adjustment on the Sonos system there is an optional feature to reduce the Album ReplayGain value as it is copied to the Track field. Looking at my own library I can see Album gains from -11dB (the notorious Oasis albums) up to +5dB (for some classical ones). I have set the adjustment at -3dB which means that I will have to turn up my amplifier by that amount to compensate but I regard that as a small price to pay. I realise that this is controversial, for example by making that adjustment I am pushing the loud albums down to -14dB, far beynod the 10dB limit that Sonos will compensate for, so do experiment and change it to your requirements or comment that line out entirely.
As should be evident, it requires that the albums should already be analysed for volume and that the option "When analyzing Track volume, also analyze Album volume" is switched on in the Options (the script checks).
This script will act on files of any format but only really makes sense (for Sonos users) on Flac files. That is because it is only for Flac files that Sonos reads the ReplayGain values - for other formats it uses different tags e.g. it uses SoundCheck iTunNORM or WMA AverageLevel and ignores ReplayGain and RGAD on mp3 files. I will be working on this next, in the mean time this script addresses about half of my library.
Note: Sonos only honours the ReplayGain when playing on zones with variable output volume. It ignores it if the output volume is fixed.
Beware: The script uses and overwrites field Custom4 to save the previous Track value. If you are using this for anything else then I suggest that you change it to use a different one.
The script needs to be placed in ...\MediaMonkey\Scripts\Auto and MediaMonkey restarted.
Code: Select all
'-------------------------------------------------------------------
' Locate in: ...\MediaMonkey\Scripts\Auto\Menu_SonosReplayGain.vbs
'
' Version: 1.00
' Date: 6 January 2012
' By Rick Parsons (based on UndoAnalyzeVolume by DiddeLeeDoo)
' Tested on Windows XP & 7 using MediaMonkey 3.2.5 and Sonos 3.6.
'
' This script requires "Analyze Volume" to have been run first.
'
' It is only really useful for Flac files because those are the only
' ones that the Sonos reads the ReplayGain tags for.
'
' NOTE 1: This script uses Custom4 as a holding location. If this is
' used for anything else it will be corrupted. Change this to an
' unused custom field in 3 places below.
' NOTE 2: An adjustment to the gain set is made to allow Sonos to
' use the headroom available. This can be customised below.
'-------------------------------------------------------------------
Sub OnStartup
Set UI = SDB.UI
Set Mnu = UI.AddMenuItemSub(UI.Menu_Tools, 4, 2)
Mnu.Caption = SDB.Localize("Set Sonos ReplayGain")
Mnu.IconIndex = 39
' Set Album ReplayGain
Set Mn1 = UI.AddMenuItem(Mnu, 0, 0)
Mn1.Caption = "Set Album ReplayGain"
Mn1.UseScript = Script.ScriptPath
Mn1.OnClickFunc = "Album"
Mn1.IconIndex = 39
' Reset Track ReplayGain
Set Mn2 = UI.AddMenuItem(Mnu, 0, 0)
Mn2.Caption = "Reset Track ReplayGain"
Mn2.UseScript = Script.ScriptPath
Mn2.OnClickFunc = "Track"
Mn2.IconIndex = 39
' Clear ReplayGains
Set Mn3 = UI.AddMenuItem(Mnu, 0, 0)
Mn3.Caption = "Clear ReplayGains"
Mn3.UseScript = Script.ScriptPath
Mn3.OnClickFunc = "Clear"
Mn3.IconIndex = 39
End Sub
Sub Album(o)
If SDB.SelectedSongList.Count > 0 Then
Set dbT = SDB.SelectedSongList
Set Prg = SDB.Progress
Prg.MaxValue = dbT.Count - 1
Prg.Text = SDB.Localize("Seting Album ReplayGain...")
For i = 0 To dbT.Count - 1
Set Sng = dbT.Item(i)
' We must have the Album volume to do anything at all
If Sng.LevelingAlbum = -999999 Then
SDB.MessageBox SDB.Localize("The Album ReplayGain is not available. Please set the Option 'When analyzing Track volume, also analyze Album volume' and re-analyse these tracks"), mtError, Array(mbOk)
Exit Sub
End If
' If Track = Album then don't do it again
If Sng.Leveling <> Sng.LevelingAlbum Then
' Use an available Custom field in the line below. The default is Custom4
Sng.Custom4 = Sng.Leveling
Sng.Leveling = Sng.LevelingAlbum
' Optional gain adjustment - change or comment out the next line to suit your requirements
Sng.Leveling = Sng.Leveling - 3.0
Sng.UpdateDB
Sng.WriteTags
End If
Prg.Value = i
If Prg.Terminate Then Exit For
Next
Set Prg = Nothing
Set dbT = Nothing
Else
SDB.MessageBox SDB.Localize("Please select the tracks to be processed"), mtError, Array(mbOk)
End If
End Sub
Sub Track(o)
If SDB.SelectedSongList.Count > 0 Then
Set dbT = SDB.SelectedSongList
Set Prg = SDB.Progress
Prg.MaxValue = dbT.Count - 1
Prg.Text=SDB.Localize("Setting Track ReplayGain...")
For i = 0 To dbT.Count - 1
Set Sng = dbT.Item(i)
' Only do it if there is a value to restore
' Use an available Custom field in the 3 lines below. The default is Custom4
If Sng.Custom4 <> "" Then
Sng.Leveling = Sng.Custom4
Sng.Custom4 = ""
Sng.UpdateDB
Sng.WriteTags
End If
Prg.Value = i
If Prg.Terminate Then Exit For
Next
Set Prg = Nothing
Set dbT = Nothing
Else
SDB.MessageBox SDB.Localize("Please select the tracks to be processed"), mtError, Array(mbOk)
End If
End Sub
Sub Clear(o)
If SDB.SelectedSongList.Count > 0 Then
Set dbT = SDB.SelectedSongList
Set Prg = SDB.Progress
Prg.MaxValue = dbT.Count-1
Prg.Text = SDB.Localize("Clearing ReplayGains...")
For i = 0 To dbT.Count - 1
Set Sng = dbT.Item(i)
' Just wipe it all out, no questions asked
Sng.Leveling = -999999
Sng.LevelingAlbum = -999999
' Use an available Custom field in the line below. The default is Custom4
Sng.Custom4 = ""
Sng.UpdateDB
Sng.WriteTags
Prg.Value = i
If Prg.Terminate Then Exit For
Next
Set Prg = Nothing
Set dbT = Nothing
Else
SDB.MessageBox SDB.Localize("Please select the tracks to be processed"), mtError, Array(mbOk)
End If
End Sub