mirror of
https://github.com/beetbox/beets.git
synced 2026-01-03 06:22:48 +01:00
Added per disc album_gain support
This commit is contained in:
parent
7438cd50f6
commit
3d842db8d8
1 changed files with 61 additions and 31 deletions
|
|
@ -83,7 +83,7 @@ class Backend(object):
|
|||
def compute_track_gain(self, items):
|
||||
raise NotImplementedError()
|
||||
|
||||
def compute_album_gain(self, album):
|
||||
def compute_album_gain(self, items):
|
||||
# TODO: implement album gain in terms of track gain of the
|
||||
# individual tracks which can be used for any backend.
|
||||
raise NotImplementedError()
|
||||
|
|
@ -125,15 +125,14 @@ class Bs1770gainBackend(Backend):
|
|||
output = self.compute_gain(items, False)
|
||||
return output
|
||||
|
||||
def compute_album_gain(self, album):
|
||||
def compute_album_gain(self, items):
|
||||
"""Computes the album gain of the given album, returns an
|
||||
AlbumGain object.
|
||||
"""
|
||||
# TODO: What should be done when not all tracks in the album are
|
||||
# supported?
|
||||
|
||||
supported_items = album.items()
|
||||
output = self.compute_gain(supported_items, True)
|
||||
output = self.compute_gain(items, True)
|
||||
|
||||
if not output:
|
||||
raise ReplayGainError(u'no output from bs1770gain')
|
||||
|
|
@ -316,15 +315,15 @@ class CommandBackend(Backend):
|
|||
output = self.compute_gain(supported_items, False)
|
||||
return output
|
||||
|
||||
def compute_album_gain(self, album):
|
||||
def compute_album_gain(self, items):
|
||||
"""Computes the album gain of the given album, returns an
|
||||
AlbumGain object.
|
||||
"""
|
||||
# TODO: What should be done when not all tracks in the album are
|
||||
# supported?
|
||||
|
||||
supported_items = list(filter(self.format_supported, album.items()))
|
||||
if len(supported_items) != len(album.items()):
|
||||
supported_items = list(filter(self.format_supported, items))
|
||||
if len(supported_items) != len(items):
|
||||
self._log.debug(u'tracks are of unsupported format')
|
||||
return AlbumGain(None, [])
|
||||
|
||||
|
|
@ -521,8 +520,8 @@ class GStreamerBackend(Backend):
|
|||
|
||||
return ret
|
||||
|
||||
def compute_album_gain(self, album):
|
||||
items = list(album.items())
|
||||
def compute_album_gain(self, items):
|
||||
items = list(items)
|
||||
self.compute(items, True)
|
||||
if len(self._file_tags) != len(items):
|
||||
raise ReplayGainError(u"Some items in album did not receive tags")
|
||||
|
|
@ -777,22 +776,20 @@ class AudioToolsBackend(Backend):
|
|||
item.artist, item.title, rg_track_gain, rg_track_peak)
|
||||
return Gain(gain=rg_track_gain, peak=rg_track_peak)
|
||||
|
||||
def compute_album_gain(self, album):
|
||||
def compute_album_gain(self, items):
|
||||
"""Compute ReplayGain values for the requested album and its items.
|
||||
|
||||
:rtype: :class:`AlbumGain`
|
||||
"""
|
||||
self._log.debug(u'Analysing album {0}', album)
|
||||
|
||||
# The first item is taken and opened to get the sample rate to
|
||||
# initialize the replaygain object. The object is used for all the
|
||||
# tracks in the album to get the album values.
|
||||
item = list(album.items())[0]
|
||||
item = list(items)[0]
|
||||
audiofile = self.open_audio_file(item)
|
||||
rg = self.init_replaygain(audiofile, item)
|
||||
|
||||
track_gains = []
|
||||
for item in album.items():
|
||||
for item in items:
|
||||
audiofile = self.open_audio_file(item)
|
||||
rg_track_gain, rg_track_peak = self._title_gain(rg, audiofile)
|
||||
track_gains.append(
|
||||
|
|
@ -836,9 +833,11 @@ class ReplayGainPlugin(BeetsPlugin):
|
|||
'backend': u'command',
|
||||
'targetlevel': 89,
|
||||
'r128': ['Opus'],
|
||||
'per_disc': False
|
||||
})
|
||||
|
||||
self.overwrite = self.config['overwrite'].get(bool)
|
||||
self.per_disc = self.config['per_disc'].get(bool)
|
||||
backend_name = self.config['backend'].as_str()
|
||||
if backend_name not in self.backends:
|
||||
raise ui.UserError(
|
||||
|
|
@ -919,6 +918,21 @@ class ReplayGainPlugin(BeetsPlugin):
|
|||
|
||||
self._log.debug(u'applied r128 album gain {0}', album.r128_album_gain)
|
||||
|
||||
def store_album_gain_item_level(self, items, album_gain):
|
||||
for item in items:
|
||||
item.rg_album_gain = album_gain.gain
|
||||
item.rg_album_peak = album_gain.peak
|
||||
item.store()
|
||||
self._log.debug(u'applied album gain {0}, peak {1}',
|
||||
item.rg_album_gain, item.rg_album_peak)
|
||||
|
||||
def store_album_r128_gain_item_level(self, items, album_gain):
|
||||
for item in items:
|
||||
item.r128_album_gain = album_gain.gain
|
||||
item.store()
|
||||
self._log.debug(u'applied r128 album gain {0}',
|
||||
item.r128_album_gain)
|
||||
|
||||
def handle_album(self, album, write, force=False):
|
||||
"""Compute album and track replay gain store it in all of the
|
||||
album's items.
|
||||
|
|
@ -946,29 +960,45 @@ class ReplayGainPlugin(BeetsPlugin):
|
|||
backend_instance = self.r128_backend_instance
|
||||
store_track_gain = self.store_track_r128_gain
|
||||
store_album_gain = self.store_album_r128_gain
|
||||
store_album_gain_item_level = self.store_album_r128_gain_item_level
|
||||
else:
|
||||
backend_instance = self.backend_instance
|
||||
store_track_gain = self.store_track_gain
|
||||
store_album_gain = self.store_album_gain
|
||||
store_album_gain_item_level = self.store_album_gain_item_level
|
||||
|
||||
try:
|
||||
album_gain = backend_instance.compute_album_gain(album)
|
||||
if len(album_gain.track_gains) != len(album.items()):
|
||||
raise ReplayGainError(
|
||||
u"ReplayGain backend failed "
|
||||
u"for some tracks in album {0}".format(album)
|
||||
)
|
||||
discs = dict()
|
||||
if self.per_disc:
|
||||
for item in album.items():
|
||||
if discs.get(item.disc) is None:
|
||||
discs[item.disc] = []
|
||||
discs[item.disc].append(item)
|
||||
else:
|
||||
discs[1] = album.items()
|
||||
|
||||
store_album_gain(album, album_gain.album_gain)
|
||||
for item, track_gain in zip(album.items(), album_gain.track_gains):
|
||||
store_track_gain(item, track_gain)
|
||||
if write:
|
||||
item.try_write()
|
||||
except ReplayGainError as e:
|
||||
self._log.info(u"ReplayGain error: {0}", e)
|
||||
except FatalReplayGainError as e:
|
||||
raise ui.UserError(
|
||||
u"Fatal replay gain error: {0}".format(e))
|
||||
for discnumber in discs:
|
||||
try:
|
||||
items = discs[discnumber]
|
||||
album_gain = backend_instance.compute_album_gain(items)
|
||||
if len(album_gain.track_gains) != len(items):
|
||||
raise ReplayGainError(
|
||||
u"ReplayGain backend failed "
|
||||
u"for some tracks in album {0}".format(album)
|
||||
)
|
||||
|
||||
if len(items) == len(album.items()):
|
||||
store_album_gain(album, album_gain.album_gain)
|
||||
else:
|
||||
store_album_gain_item_level(items, album_gain.album_gain)
|
||||
for item, track_gain in zip(items, album_gain.track_gains):
|
||||
store_track_gain(item, track_gain)
|
||||
if write:
|
||||
item.try_write()
|
||||
except ReplayGainError as e:
|
||||
self._log.info(u"ReplayGain error: {0}", e)
|
||||
except FatalReplayGainError as e:
|
||||
raise ui.UserError(
|
||||
u"Fatal replay gain error: {0}".format(e))
|
||||
|
||||
def handle_track(self, item, write, force=False):
|
||||
"""Compute track replay gain and store it in the item.
|
||||
|
|
|
|||
Loading…
Reference in a new issue