From 8af5b0e6c3ba755444014d14855879e83070e009 Mon Sep 17 00:00:00 2001 From: Francesco Rubino Date: Fri, 7 Nov 2014 18:14:56 +0000 Subject: [PATCH 1/3] Added backed audiotools to replaygain module and updated documentation --- beetsplug/replaygain.py | 114 ++++++++++++++++++++++++++++++++++++ docs/plugins/replaygain.rst | 8 ++- 2 files changed, 121 insertions(+), 1 deletion(-) diff --git a/beetsplug/replaygain.py b/beetsplug/replaygain.py index 552984ed14..8502ab37d0 100644 --- a/beetsplug/replaygain.py +++ b/beetsplug/replaygain.py @@ -463,6 +463,119 @@ def _on_pad_removed(self, decbin, pad): assert(peer is None) +class AudioToolsBackend(Backend): + def __init__(self, config): + self._import_audiotools() + + def _import_audiotools(self): + try: + import audiotools + import audiotools.replaygain + except ImportError: + raise FatalReplayGainError( + "Failed to load audiotools: audiotools not found" + ) + self._mod_audiotools = audiotools + self._mod_replaygain = audiotools.replaygain + + def open_audio_file(self, item): + try: + audiofile = self._mod_audiotools.open(item.path) + except IOError: + raise ReplayGainError( + "File {} was not found".format(item.path) + ) + except self._mod_audiotools.UnsupportedFile: + raise ReplayGainError( + "Unsupported file type {}".format(item.format) + ) + + return audiofile + + def init_replaygain(self, audiofile, item): + try: + rg = self._mod_replaygain.ReplayGain(audiofile.sample_rate()) + except ValueError: + raise ReplayGainError( + "Unsupported sample rate {}".format(item.samplerate) + ) + return + return rg + + def compute_track_gain(self, items): + return [self._compute_track_gain(item) for item in items] + + def _compute_track_gain(self, item): + + audiofile = self.open_audio_file(item) + + rg = self.init_replaygain(audiofile, item) + + rg_track_gain, rg_track_peak = rg.title_gain(audiofile.to_pcm()) + + log.info( + u'ReplayGain for track {0} - {1}: gain {2:.2f} peak {3:.2f}'.format( + 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): + + log.info( + u'Analysing album {0} - {1}'.format( + album.albumartist, + album.album + ) + ) + + item = list(album.items())[0] + + audiofile = self.open_audio_file(item) + rg = self.init_replaygain(audiofile, item) + + track_gains = [] + + for item in album.items(): + audiofile = self.open_audio_file(item) + rg_track_gain, rg_track_peak = rg.title_gain(audiofile.to_pcm()) + track_gains.append( + Gain(gain=rg_track_gain, peak=rg_track_peak) + ) + log.info( + u'ReplayGain for track {0} - {1}: gain {2:.2f} peak {3:.2f}'.format( + item.artist, + item.title, + rg_track_gain, + rg_track_peak + ) + ) + + rg_album_gain, rg_album_peak = rg.album_gain() + + log.info('-' * 100) + + log.info( + u'ReplayGain for Album {0} - {1}: gain {2:.2f} peak {3:.2f}'.format( + album.albumartist, + album.album, + rg_album_gain, + rg_album_peak + ) + ) + + log.info('=' * 100) + + return AlbumGain( + Gain(gain=rg_album_gain, peak=rg_album_peak), + track_gains=track_gains + ) + + # Main plugin logic. class ReplayGainPlugin(BeetsPlugin): @@ -472,6 +585,7 @@ class ReplayGainPlugin(BeetsPlugin): backends = { "command": CommandBackend, "gstreamer": GStreamerBackend, + "audiotools": AudioToolsBackend } def __init__(self): diff --git a/docs/plugins/replaygain.rst b/docs/plugins/replaygain.rst index 5b5420025f..cab21f2459 100644 --- a/docs/plugins/replaygain.rst +++ b/docs/plugins/replaygain.rst @@ -61,6 +61,12 @@ you can configure the path explicitly like so:: replaygain: command: /Applications/MacMP3Gain.app/Contents/Resources/aacgain +Python Audio Tools +`````````````````` + +This backend uses the `audiotools`_ module to compute ReplayGain, in a range of different file formats. Installation of the module is not available through PyPI. The requirements for most of its dependencies can be installed on Mac OS X via `Homebrew`_: ``brew install mpg123 mp3gain vorbisgain faad2 libvorbis`` + +.. _audiotools: http://audiotools.sourceforge.net Configuration ------------- @@ -70,7 +76,7 @@ configuration file. The available options are: - ``auto``: Enable ReplayGain analysis during import. Default: ``yes``. -- ``backend``: The analysis backend; either ``gstreamer`` or ``command``. +- ``backend``: The analysis backend; either ``gstreamer``, ``command`` or ``audtiotools`. Default: ``command``. - ``overwrite``: Re-analyze files that already have ReplayGain tags. Default: ``no``. From 4bf17486ebb4b45525d796d91b39f2603d259b28 Mon Sep 17 00:00:00 2001 From: Francesco Rubino Date: Sun, 9 Nov 2014 10:29:46 +0000 Subject: [PATCH 2/3] Fixed line lengths, typo in documentation. --- beetsplug/replaygain.py | 6 +++--- docs/plugins/replaygain.rst | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/beetsplug/replaygain.py b/beetsplug/replaygain.py index 8502ab37d0..dbc2f98cc6 100644 --- a/beetsplug/replaygain.py +++ b/beetsplug/replaygain.py @@ -514,7 +514,7 @@ def _compute_track_gain(self, item): rg_track_gain, rg_track_peak = rg.title_gain(audiofile.to_pcm()) log.info( - u'ReplayGain for track {0} - {1}: gain {2:.2f} peak {3:.2f}'.format( + u'ReplayGain for track {0} - {1}: {2:.2f}, {3:.2f}'.format( item.artist, item.title, rg_track_gain, @@ -547,7 +547,7 @@ def compute_album_gain(self, album): Gain(gain=rg_track_gain, peak=rg_track_peak) ) log.info( - u'ReplayGain for track {0} - {1}: gain {2:.2f} peak {3:.2f}'.format( + u'ReplayGain for track {0} - {1}: {2:.2f}, {3:.2f}'.format( item.artist, item.title, rg_track_gain, @@ -560,7 +560,7 @@ def compute_album_gain(self, album): log.info('-' * 100) log.info( - u'ReplayGain for Album {0} - {1}: gain {2:.2f} peak {3:.2f}'.format( + u'ReplayGain for Album {0} - {1}: {2:.2f}, {3:.2f}'.format( album.albumartist, album.album, rg_album_gain, diff --git a/docs/plugins/replaygain.rst b/docs/plugins/replaygain.rst index cab21f2459..1a248b4faf 100644 --- a/docs/plugins/replaygain.rst +++ b/docs/plugins/replaygain.rst @@ -76,7 +76,7 @@ configuration file. The available options are: - ``auto``: Enable ReplayGain analysis during import. Default: ``yes``. -- ``backend``: The analysis backend; either ``gstreamer``, ``command`` or ``audtiotools`. +- ``backend``: The analysis backend; either ``gstreamer``, ``command`` or ``audiotools`. Default: ``command``. - ``overwrite``: Re-analyze files that already have ReplayGain tags. Default: ``no``. From e4dfd23092be9a1565b50eec8051b73661447992 Mon Sep 17 00:00:00 2001 From: Francesco Rubino Date: Sun, 9 Nov 2014 14:50:26 +0000 Subject: [PATCH 3/3] Fix to documentation after merge of upstream repo --- docs/plugins/replaygain.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plugins/replaygain.rst b/docs/plugins/replaygain.rst index da491ba41d..fb6d2369bc 100644 --- a/docs/plugins/replaygain.rst +++ b/docs/plugins/replaygain.rst @@ -76,7 +76,7 @@ configuration file. The available options are: - **auto**: Enable ReplayGain analysis during import. Default: ``yes``. -- ``backend``: The analysis backend; either ``gstreamer``, ``command`` or ``audiotools`. +- **backend**: The analysis backend; either ``gstreamer``, ``command`` or ``audiotools`. Default: ``command``. - **overwrite**: Re-analyze files that already have ReplayGain tags. Default: ``no``.