mirror of
https://github.com/beetbox/beets.git
synced 2026-02-22 15:22:42 +01:00
Handle bs1770gain v0.6.0 XML output
* Remove `0%\x08\x08` from output (backspace code doesn't resolve; progress percentages get spliced in)
* Handle changed attributes/fields:
* `sample-peak` attribute `factor` is called `amplitude` instead
* Album summary is not included in a `summary` tag now, but in two separate `integrated` and `sample-peak` tags
* Handle `lu` attribute
* Get bs1770gain version
* If v0.6.0 or later, add `--unit=ebu` flag to convert `db` attributes to LUFS
* May be useful later on
### Output examples
Track:
```
<!-- analyzing ... -->
<bs1770gain norm="-18.00">
<track total="1" number="1" file="02 tïtle 0.mp3">
<integrated lufs="-70.00" lu="52.00"/>
<sample-peak spfs="-72.28" amplitude="0.00"/>
</track>
<integrated lufs="-70.00" lu="52.00"/>
<sample-peak spfs="-72.28" amplitude="0.00"/>
</bs1770gain>
<!-- done. -->
```
Album:
```
<!-- analyzing ... -->
<bs1770gain norm="-18.00">
<track total="2" number="1" file="02 tïtle 0.mp3">
<integrated dbfs="-70.00" db="52.00"/>
<sample-peak dbfs="-72.28" amplitude="0.00"/>
</track>
<track total="2" number="2" file="02 tïtle 1.mp3">
<integrated dbfs="-70.00" db="52.00"/>
<sample-peak dbfs="-72.28" amplitude="0.00"/>
</track>
<integrated dbfs="-70.00" db="52.00"/>
<sample-peak dbfs="-72.28" amplitude="0.00"/>
</bs1770gain>
<!-- done. -->
```
This commit is contained in:
parent
ca3142b1d9
commit
53820c0a98
2 changed files with 31 additions and 4 deletions
|
|
@ -22,6 +22,7 @@ import math
|
|||
import sys
|
||||
import warnings
|
||||
import enum
|
||||
import re
|
||||
import xml.parsers.expat
|
||||
from six.moves import zip
|
||||
|
||||
|
|
@ -135,6 +136,11 @@ class Bs1770gainBackend(Backend):
|
|||
-18: "replaygain",
|
||||
}
|
||||
|
||||
version = re.search(
|
||||
'bs1770gain ([0-9]+.[0-9]+.[0-9]+), ',
|
||||
call(['bs1770gain', '--version']).stdout.decode('utf-8')
|
||||
).group(1)
|
||||
|
||||
def __init__(self, config, log):
|
||||
super(Bs1770gainBackend, self).__init__(config, log)
|
||||
config.add({
|
||||
|
|
@ -252,6 +258,8 @@ class Bs1770gainBackend(Backend):
|
|||
cmd = [self.command]
|
||||
cmd += ["--" + method]
|
||||
cmd += ['--xml', '-p']
|
||||
if self.version >= '0.6.0':
|
||||
cmd += ['--unit=ebu'] # set units to LU
|
||||
|
||||
# Workaround for Windows: the underlying tool fails on paths
|
||||
# with the \\?\ prefix, so we don't use it here. This
|
||||
|
|
@ -286,6 +294,7 @@ class Bs1770gainBackend(Backend):
|
|||
album_gain = {} # mutable variable so it can be set from handlers
|
||||
parser = xml.parsers.expat.ParserCreate(encoding='utf-8')
|
||||
state = {'file': None, 'gain': None, 'peak': None}
|
||||
album_state = {'gain': None, 'peak': None}
|
||||
|
||||
def start_element_handler(name, attrs):
|
||||
if name == u'track':
|
||||
|
|
@ -294,9 +303,13 @@ class Bs1770gainBackend(Backend):
|
|||
raise ReplayGainError(
|
||||
u'duplicate filename in bs1770gain output')
|
||||
elif name == u'integrated':
|
||||
state['gain'] = float(attrs[u'lu'])
|
||||
if 'lu' in attrs:
|
||||
state['gain'] = float(attrs[u'lu'])
|
||||
elif name == u'sample-peak':
|
||||
state['peak'] = float(attrs[u'factor'])
|
||||
if 'factor' in attrs:
|
||||
state['peak'] = float(attrs[u'factor'])
|
||||
elif 'amplitude' in attrs:
|
||||
state['peak'] = float(attrs[u'amplitude'])
|
||||
|
||||
def end_element_handler(name):
|
||||
if name == u'track':
|
||||
|
|
@ -312,10 +325,25 @@ class Bs1770gainBackend(Backend):
|
|||
'the output of bs1770gain')
|
||||
album_gain["album"] = Gain(state['gain'], state['peak'])
|
||||
state['gain'] = state['peak'] = None
|
||||
elif len(per_file_gain) == len(path_list):
|
||||
if state['gain'] is not None:
|
||||
album_state['gain'] = state['gain']
|
||||
if state['peak'] is not None:
|
||||
album_state['peak'] = state['peak']
|
||||
if album_state['gain'] is not None \
|
||||
and album_state['peak'] is not None:
|
||||
album_gain["album"] = Gain(
|
||||
album_state['gain'], album_state['peak'])
|
||||
state['gain'] = state['peak'] = None
|
||||
|
||||
parser.StartElementHandler = start_element_handler
|
||||
parser.EndElementHandler = end_element_handler
|
||||
|
||||
try:
|
||||
if type(text) == bytes:
|
||||
text = text.decode('utf-8')
|
||||
while '\x08' in text:
|
||||
text = re.sub('[^\x08]\x08', '', text)
|
||||
parser.Parse(text, True)
|
||||
except xml.parsers.expat.ExpatError:
|
||||
raise ReplayGainError(
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ if any(has_program(cmd, ['-v']) for cmd in ['mp3gain', 'aacgain']):
|
|||
else:
|
||||
GAIN_PROG_AVAILABLE = False
|
||||
|
||||
if has_program('bs1770gain', ['--replaygain']):
|
||||
if has_program('bs1770gain'):
|
||||
LOUDNESS_PROG_AVAILABLE = True
|
||||
else:
|
||||
LOUDNESS_PROG_AVAILABLE = False
|
||||
|
|
@ -58,7 +58,6 @@ def reset_replaygain(item):
|
|||
|
||||
|
||||
class ReplayGainCliTestBase(TestHelper):
|
||||
|
||||
def setUp(self):
|
||||
self.setup_beets()
|
||||
self.config['replaygain']['backend'] = self.backend
|
||||
|
|
|
|||
Loading…
Reference in a new issue