Script: SonosReplayGain v1.0 [MM3]

Download and get help for different MediaMonkey Addons.

Moderators: Peke, Gurus

renowden
Posts: 37
Joined: Wed Dec 12, 2007 3:55 pm
Location: Bristol, England
Contact:

Script: SonosReplayGain v1.0 [MM3]

Post by renowden » Fri Jan 06, 2012 6:50 am

When replaying Flac files, Sonos systems use the Track ReplayGain value to set the volume. https://sonos.custhelp.com/cgi-bin/sono ... _faqid=330 This is fine if you are playing a mixture of tracks from different sources but I prefer to play music by the Album. In that case, with ReplayGain switched on, the music comes out a bit flat with no variation in volume between tracks. This is particularly noticeable in Classical works where the loud movements will have the same overall volume as the quiet ones.

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
Cheers,

Rick Parsons

renowden
Posts: 37
Joined: Wed Dec 12, 2007 3:55 pm
Location: Bristol, England
Contact:

Re: Script: SonosReplayGain v1.0 [MM3]

Post by renowden » Mon Mar 10, 2014 11:38 am

I have now written a bit of binary code which can achieve the same thing for MP3 files. See http://west-penwith.org.uk/misc/sonosreplaygain.htm and my blog article at http://west-penwith.org.uk/blog/archives/1323 for a full description and the required downloads.
Cheers,

Rick Parsons

Post Reply