def get_gain_for_song(file): exceptions = [] # handlers def on_finished(evsrc, trackdata, albumdata): loop.quit() def on_error(evsrc, exc): exceptions.append(exc) loop.quit() rg = rgcalc.ReplayGain([file], True, ref_level) with util.gobject_signals( rg, ("all-finished", on_finished), ("error", on_error), ): loop = GLib.MainLoop() rg.start() loop.run() if exceptions: raise exceptions[0] return "%0.2f dB" % rg.track_data.popitem()[1].gain
def calculate_gain(files, ref_level): exc_slot = [None] # handlers def on_finished(evsrc, trackdata, albumdata): loop.quit() def on_trk_started(evsrc, filename): print(" %s:" % filename, end='', flush=True) def on_trk_finished(evsrc, filename, gaindata): if gaindata: print("%.2f dB" % (gaindata.gain,)) else: print("done") def on_error(evsrc, exc): exc_slot[0] = exc loop.quit() rg = rgcalc.ReplayGain(files, True, ref_level) with util.gobject_signals(rg, ("all-finished", on_finished), ("track-started", on_trk_started), ("track-finished", on_trk_finished), ("error", on_error),): loop = GLib.MainLoop() rg.start() loop.run() if exc_slot[0] is not None: raise exc_slot[0] return rg.track_data, rg.album_data
def calculate(*args, **kwargs): """Analyze some files. This is only a convenience interface to the ``ReplayGain`` class: it takes the same arguments, but setups its own main loop and returns the results once everything's finished. """ exc_slot = [None] def on_finished(evsrc, trackdata, albumdata): # all done loop.quit() def on_error(evsrc, exc): exc_slot[0] = exc loop.quit() rg = ReplayGain(*args, **kwargs) with util.gobject_signals( rg, ("all-finished", on_finished), ("error", on_error), ): loop = GObject.MainLoop() rg.start() loop.run() if exc_slot[0] is not None: raise exc_slot[0] return (rg.track_data, rg.album_data)
def _replaygain_calc(mp3s: list, target_gain: float) -> Tuple[dict, rgcalc.GainData]: """Calculate replaygain values for all provided files. Args: mp3s: list of mp3s to process target_gain: the target gain to adjust the track to Returns: Replaygain values for all files """ exc_slot = [None] # Handlers # noinspection PyUnusedLocal def on_loop_finished(evsrc, trackdata, albumdata): # pylint: disable=unused-argument loop.quit() # noinspection PyUnusedLocal def on_track_started(evsrc, filename): # pylint: disable=unused-argument LOGGER.debug(" ** replaygain started: %s", filename) # noinspection PyUnusedLocal def on_track_finished(evsrc, filename, gaindata): # pylint: disable=unused-argument LOGGER.debug(" ** replaygain stopped: %s", filename) # noinspection PyUnusedLocal def on_error(evsrc, exc): # pylint: disable=unused-argument exc_slot[0] = exc loop.quit() replaygain_values = rgcalc.ReplayGain(mp3s, True, int(round(target_gain))) with util.gobject_signals( replaygain_values, ("all-finished", on_loop_finished), ("track-started", on_track_started), ("track-finished", on_track_finished), ("error", on_error), ): loop = GLib.MainLoop() replaygain_values.start() loop.run() if exc_slot[0] is not None: raise exc_slot[0] # pylint: disable=raising-bad-type return replaygain_values.track_data, replaygain_values.album_data
def test_track_started_finished_signals(self): tracks = [ os.path.join(DATA_PATH, "no-tags.flac"), os.path.join(DATA_PATH, "no-tags.mp3") ] rg = rgcalc.ReplayGain(tracks) events = [] loop = GObject.MainLoop() def event(*args): """ Collect signals received from analysis. """ events.append(list(args)) def assert_not_called(*args): """ The test must not receive any error signals! """ loop.quit() print(args) assert False with util.gobject_signals(rg, ("error", assert_not_called), ("track-started", event), ("track-finished", event), ("all-finished", lambda *args: loop.quit())): rg.start() loop.run() self.assertEqual(len(events), 4) self.assertEqual(events[0], [rg, tracks[0]]) self.assertEqual(events[1], [rg, tracks[0], rg.track_data[tracks[0]]]) self.assertEqual(events[2], [rg, tracks[1]]) self.assertEqual(events[3], [rg, tracks[1], rg.track_data[tracks[1]]])