Skip to content

Commit

Permalink
Added support for retaining existing album gain via CLI argument
Browse files Browse the repository at this point in the history
  • Loading branch information
maszaa committed May 21, 2020
1 parent 9b0b235 commit 529556c
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 11 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ tags are already present in the files. If you have files which had loudness
levels calculated using the old ReplayGain algorithm, you can use this option
to recalculate using the EBU R128 algorithm.

`-i`/`--ignore-album-gain` causes regainer to ignore existing album gain.
This is useful if you for example have multi-disc albums that have discs mastered
at different loudness levels. NOTE: Using `-f` overrides this argument.

`-j N` specifies the number of parallel jobs to run. By default it will
use all CPUs available on the system. You can use this to reduce the amount
of CPU that regainer will use.
Expand Down
40 changes: 29 additions & 11 deletions regainer.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ def format_opus_gain(self, value):
if value < -32768 or value > 32767:
raise ValueError('Opus gain value out of range')
return "{:d}".format(value)


def read_gain_id3(self):
need_update = False
Expand Down Expand Up @@ -730,13 +730,18 @@ async def scan_album_gain(self):
gain_scanner = GainScanner()
self.gain = await gain_scanner.scan_album(included)

async def scan_gain(self):
album_task = asyncio.ensure_future(self.scan_album_gain())
track_tasks = [track.scan_gain() for track in self.tracks]
async def scan_gain(self, ignore_album_scan=False):
tasks = [track.scan_gain() for track in self.tracks]

if not ignore_album_scan:
album_task = asyncio.ensure_future(self.scan_album_gain())
tasks.append(album_task)

await asyncio.gather(album_task, *track_tasks)
await asyncio.gather(*tasks)

if not ignore_album_scan:
self.gain.album_peak = max([t.gain.peak for t in self.tracks])

self.gain.album_peak = max([t.gain.peak for t in self.tracks])
for track in self.tracks:
track.gain.album_loudness = self.gain.album_loudness
track.gain.album_peak = self.gain.album_peak
Expand All @@ -745,30 +750,35 @@ async def write_tags(self):
track_tasks = [track.write_tags() for track in self.tracks]
await asyncio.gather(*track_tasks)

async def scan(self, force=False, skip_save=False):
async def scan(self, force=False, skip_save=False, ignore=False):
await self.read_tags()

need_scan = False
ignore_album_scan = False
for track in self.tracks:
if track.gain.loudness is None or track.gain.peak is None:
need_scan = True
if self.gain.album_loudness is None:
self.gain.album_loudness = track.gain.album_loudness
if self.gain.album_loudness != track.gain.album_loudness:
need_scan = True
need_scan = need_scan or not ignore
ignore_album_scan = ignore
if self.gain.album_peak is None:
self.gain.album_peak = track.gain.album_peak
if self.gain.album_peak != track.gain.album_peak:
need_scan = True
need_scan = need_scan or not ignore
ignore_album_scan = ignore
if self.gain.album_loudness is None or self.gain.album_peak is None:
need_scan = True
ignore_album_scan = False
if force:
need_scan = True
ignore_album_scan = False

need_save = any([track.tagger.need_album_update for track in self.tracks])

if need_scan:
await self.scan_gain()
await self.scan_gain(ignore_album_scan)
need_save = True

if need_save:
Expand All @@ -781,6 +791,8 @@ async def scan(self, force=False, skip_save=False):
print(track.gain)
if need_scan:
print("Rescanned loudness")
if ignore_album_scan:
print("Ignored missmatching album gains")
if need_save:
if not skip_save:
print("Updated tags")
Expand Down Expand Up @@ -808,6 +820,12 @@ def main(argv=None):
Recalculate the ReplayGain values even if valid tags are already
present in the files.
''')
parser.add_argument('-i', '--ignore-album-gain', default=False, action='store_true',
help='''
Don't recalculate the album ReplayGain values even if missmatching gains are already
present in the files. Using this option will preserve different album gain values for
given files. Using -f/--force overrides this arguments.
''')
parser.add_argument('-j', '--jobs', type=int,
default=multiprocessing.cpu_count(),
help='''
Expand Down Expand Up @@ -855,7 +873,7 @@ def main(argv=None):

tasks = []
albums = [Album(album, job_sem) for album in args.album]
tasks += [album.scan(force=args.force, skip_save=args.dry_run)
tasks += [album.scan(force=args.force, skip_save=args.dry_run, ignore=args.ignore_album_gain)
for album in albums]
tracks = [Track(track, job_sem) for track in args.track]
tasks += [track.scan(force=args.force, skip_save=args.dry_run)
Expand Down

0 comments on commit 529556c

Please sign in to comment.