From 1511e313f7958a989e56dfb0bae14f4b4fe8e6f3 Mon Sep 17 00:00:00 2001 From: Carl Suster Date: Sat, 30 Mar 2019 20:18:08 +1100 Subject: [PATCH] bpd: add mixramp commands These are a more sophisticated version of crossfade so we're free to ignore them, at least for now. We now track the values of the two settings, and show them in the status output. Like MPD, we suppress the mixrampdb value if it's set to nan, which is how it signals that the feature should be turned off. --- beetsplug/bpd/__init__.py | 22 ++++++++++++++++++++++ test/test_player.py | 22 +++++++++++++++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/beetsplug/bpd/__init__.py b/beetsplug/bpd/__init__.py index 4f04d01fc..5c394212c 100644 --- a/beetsplug/bpd/__init__.py +++ b/beetsplug/bpd/__init__.py @@ -25,6 +25,7 @@ from string import Template import traceback import random import time +import math import beets from beets.plugins import BeetsPlugin @@ -174,6 +175,8 @@ class BaseServer(object): self.repeat = False self.volume = VOLUME_MAX self.crossfade = 0 + self.mixrampdb = 0.0 + self.mixrampdelay = float('nan') self.playlist = [] self.playlist_version = 0 self.current_index = -1 @@ -307,8 +310,11 @@ class BaseServer(object): u'random: ' + six.text_type(int(self.random)), u'playlist: ' + six.text_type(self.playlist_version), u'playlistlength: ' + six.text_type(len(self.playlist)), + u'mixrampdb: ' + six.text_type(self.mixrampdb), ) + if not math.isnan(self.mixrampdelay): + yield u'mixrampdelay: ' + six.text_type(self.mixrampdelay) if self.crossfade > 0: yield u'xfade: ' + six.text_type(self.crossfade) @@ -358,6 +364,22 @@ class BaseServer(object): self._log.warning(u'crossfade is not implemented in bpd') self.crossfade = crossfade + def cmd_mixrampdb(self, conn, db): + """Set the mixramp normalised max volume in dB.""" + db = cast_arg(float, db) + if db > 0: + raise BPDError(ERROR_ARG, u'mixrampdb time must be negative') + self._log.warning('mixramp is not implemented in bpd') + self.mixrampdb = db + + def cmd_mixrampdelay(self, conn, delay): + """Set the mixramp delay in seconds.""" + delay = cast_arg(float, delay) + if delay < 0: + raise BPDError(ERROR_ARG, u'mixrampdelay time must be nonnegative') + self._log.warning('mixramp is not implemented in bpd') + self.mixrampdelay = delay + def cmd_clear(self, conn): """Clear the playlist.""" self.playlist = [] diff --git a/test/test_player.py b/test/test_player.py index d2ea496c4..5589b4d6c 100644 --- a/test/test_player.py +++ b/test/test_player.py @@ -361,7 +361,7 @@ class BPDQueryTest(BPDTestHelper): class BPDPlaybackTest(BPDTestHelper): test_implements_playback = implements({ - 'consume', 'mixrampd', 'mixrampdelay', 'random', + 'consume', 'random', 'repeat', 'setvol', 'single', 'replay_gain_mode', 'replay_gain_status', 'volume', }, expectedFailure=True) @@ -379,6 +379,26 @@ class BPDPlaybackTest(BPDTestHelper): self.assertNotIn('xfade', responses[0].data) self.assertAlmostEqual(123, int(responses[2].data['xfade'])) + def test_cmd_mixrampdb(self): + with self.run_bpd() as client: + responses = client.send_commands( + ('mixrampdb', '-17'), + ('status',)) + self._assert_ok(*responses) + self.assertAlmostEqual(-17, float(responses[1].data['mixrampdb'])) + + def test_cmd_mixrampdelay(self): + with self.run_bpd() as client: + responses = client.send_commands( + ('mixrampdelay', '2'), + ('status',), + ('mixrampdelay', 'nan'), + ('status',), + ('mixrampdelay', '-2')) + self._assert_failed(responses, bpd.ERROR_ARG, pos=4) + self.assertAlmostEqual(2, float(responses[1].data['mixrampdelay'])) + self.assertNotIn('mixrampdelay', responses[3].data) + class BPDControlTest(BPDTestHelper): test_implements_control = implements({