core: Add mixer controller (fixes: #962)
Deprecate volume and mute methods on playback controller.
This commit is contained in:
parent
cc3e9d5597
commit
42115c56f7
@ -64,6 +64,14 @@ Manages the music library, e.g. searching for tracks to be added to a playlist.
|
||||
:members:
|
||||
|
||||
|
||||
Mixer controller
|
||||
================
|
||||
|
||||
Manages volume and muting.
|
||||
|
||||
.. autoclass:: mopidy.core.MixerController
|
||||
:members:
|
||||
|
||||
Core listener
|
||||
=============
|
||||
|
||||
|
||||
@ -17,6 +17,10 @@ v0.20.0 (UNRELEASED)
|
||||
- Added :class:`mopidy.core.HistoryController` which keeps track of what
|
||||
tracks have been played. (Fixes: :issue:`423`, PR: :issue:`803`)
|
||||
|
||||
- Added :class:`mopidy.core.MixerController` which keeps track of volume and
|
||||
mute. The old methods on :class:`mopidy.core.PlaybackController` for volume
|
||||
and mute management has been deprecated. (Fixes: :issue:`962`)
|
||||
|
||||
- Removed ``clear_current_track`` keyword argument to
|
||||
:meth:`mopidy.core.Playback.stop`. It was a leaky internal abstraction,
|
||||
which was never intended to be used externally.
|
||||
|
||||
@ -5,6 +5,7 @@ from .actor import Core
|
||||
from .history import HistoryController
|
||||
from .library import LibraryController
|
||||
from .listener import CoreListener
|
||||
from .mixer import MixerController
|
||||
from .playback import PlaybackController, PlaybackState
|
||||
from .playlists import PlaylistsController
|
||||
from .tracklist import TracklistController
|
||||
|
||||
@ -11,6 +11,7 @@ from mopidy.audio.utils import convert_tags_to_track
|
||||
from mopidy.core.history import HistoryController
|
||||
from mopidy.core.library import LibraryController
|
||||
from mopidy.core.listener import CoreListener
|
||||
from mopidy.core.mixer import MixerController
|
||||
from mopidy.core.playback import PlaybackController
|
||||
from mopidy.core.playlists import PlaylistsController
|
||||
from mopidy.core.tracklist import TracklistController
|
||||
@ -31,6 +32,10 @@ class Core(
|
||||
"""The playback history controller. An instance of
|
||||
:class:`mopidy.core.HistoryController`."""
|
||||
|
||||
mixer = None
|
||||
"""The mixer controller. An instance of
|
||||
:class:`mopidy.core.MixerController`."""
|
||||
|
||||
playback = None
|
||||
"""The playback controller. An instance of
|
||||
:class:`mopidy.core.PlaybackController`."""
|
||||
@ -49,15 +54,10 @@ class Core(
|
||||
self.backends = Backends(backends)
|
||||
|
||||
self.library = LibraryController(backends=self.backends, core=self)
|
||||
|
||||
self.history = HistoryController()
|
||||
|
||||
self.playback = PlaybackController(
|
||||
mixer=mixer, backends=self.backends, core=self)
|
||||
|
||||
self.playlists = PlaylistsController(
|
||||
backends=self.backends, core=self)
|
||||
|
||||
self.mixer = MixerController(mixer=mixer)
|
||||
self.playback = PlaybackController(backends=self.backends, core=self)
|
||||
self.playlists = PlaylistsController(backends=self.backends, core=self)
|
||||
self.tracklist = TracklistController(core=self)
|
||||
|
||||
self.audio = audio
|
||||
|
||||
64
mopidy/core/mixer.py
Normal file
64
mopidy/core/mixer.py
Normal file
@ -0,0 +1,64 @@
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
import logging
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class MixerController(object):
|
||||
pykka_traversable = True
|
||||
|
||||
def __init__(self, mixer):
|
||||
self._mixer = mixer
|
||||
self._volume = None
|
||||
self._mute = False
|
||||
|
||||
def get_volume(self):
|
||||
"""Get the volume.
|
||||
|
||||
Integer in range [0..100] or :class:`None` if unknown.
|
||||
|
||||
The volume scale is linear.
|
||||
"""
|
||||
if self._mixer:
|
||||
return self._mixer.get_volume().get()
|
||||
else:
|
||||
# For testing
|
||||
return self._volume
|
||||
|
||||
def set_volume(self, volume):
|
||||
"""Set the volume.
|
||||
|
||||
The volume is defined as an integer in range [0..100].
|
||||
|
||||
The volume scale is linear.
|
||||
"""
|
||||
if self._mixer:
|
||||
self._mixer.set_volume(volume)
|
||||
else:
|
||||
# For testing
|
||||
self._volume = volume
|
||||
|
||||
def get_mute(self):
|
||||
"""Get mute state.
|
||||
|
||||
:class:`True` if muted, :class:`False` otherwise.
|
||||
"""
|
||||
if self._mixer:
|
||||
return self._mixer.get_mute().get()
|
||||
else:
|
||||
# For testing
|
||||
return self._mute
|
||||
|
||||
def set_mute(self, mute):
|
||||
"""Set mute state.
|
||||
|
||||
:class:`True` to mute, :class:`False` to unmute.
|
||||
"""
|
||||
mute = bool(mute)
|
||||
if self._mixer:
|
||||
self._mixer.set_mute(mute)
|
||||
else:
|
||||
# For testing
|
||||
self._mute = mute
|
||||
@ -2,6 +2,7 @@ from __future__ import absolute_import, unicode_literals
|
||||
|
||||
import logging
|
||||
import urlparse
|
||||
import warnings
|
||||
|
||||
from mopidy.audio import PlaybackState
|
||||
from mopidy.core import listener
|
||||
@ -11,20 +12,16 @@ from mopidy.utils.deprecation import deprecated_property
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# TODO: split mixing out from playback?
|
||||
class PlaybackController(object):
|
||||
pykka_traversable = True
|
||||
|
||||
def __init__(self, mixer, backends, core):
|
||||
self.mixer = mixer
|
||||
def __init__(self, backends, core):
|
||||
self.backends = backends
|
||||
self.core = core
|
||||
|
||||
self._current_tl_track = None
|
||||
self._current_metadata_track = None
|
||||
self._state = PlaybackState.STOPPED
|
||||
self._volume = None
|
||||
self._mute = False
|
||||
|
||||
def _get_backend(self):
|
||||
# TODO: take in track instead
|
||||
@ -139,64 +136,59 @@ class PlaybackController(object):
|
||||
"""
|
||||
|
||||
def get_volume(self):
|
||||
"""Get the volume.
|
||||
|
||||
Integer in range [0..100] or :class:`None` if unknown.
|
||||
|
||||
The volume scale is linear.
|
||||
"""
|
||||
if self.mixer:
|
||||
return self.mixer.get_volume().get()
|
||||
else:
|
||||
# For testing
|
||||
return self._volume
|
||||
... deprecated:: 0.20
|
||||
Use :meth:`core.mixer.get_volume()
|
||||
<mopidy.core.MixerController.get_volume>` instead.
|
||||
"""
|
||||
warnings.warn(
|
||||
'playback.get_volume() is deprecated', DeprecationWarning)
|
||||
return self.core.mixer.get_volume()
|
||||
|
||||
def set_volume(self, volume):
|
||||
"""Set the volume.
|
||||
|
||||
The volume is defined as an integer in range [0..100].
|
||||
|
||||
The volume scale is linear.
|
||||
"""
|
||||
if self.mixer:
|
||||
self.mixer.set_volume(volume)
|
||||
else:
|
||||
# For testing
|
||||
self._volume = volume
|
||||
... deprecated:: 0.20
|
||||
Use :meth:`core.mixer.set_volume()
|
||||
<mopidy.core.MixerController.set_volume>` instead.
|
||||
"""
|
||||
warnings.warn(
|
||||
'playback.set_volume() is deprecated', DeprecationWarning)
|
||||
return self.core.mixer.set_volume(volume)
|
||||
|
||||
volume = deprecated_property(get_volume, set_volume)
|
||||
"""
|
||||
.. deprecated:: 0.20
|
||||
Use :meth:`get_volume` and :meth:`set_volume` instead.
|
||||
Use :meth:`core.mixer.get_volume()
|
||||
<mopidy.core.MixerController.get_volume>` and
|
||||
:meth:`core.mixer.set_volume()
|
||||
<mopidy.core.MixerController.set_volume>` instead.
|
||||
"""
|
||||
|
||||
def get_mute(self):
|
||||
"""Get mute state.
|
||||
|
||||
:class:`True` if muted, :class:`False` otherwise.
|
||||
"""
|
||||
if self.mixer:
|
||||
return self.mixer.get_mute().get()
|
||||
else:
|
||||
# For testing
|
||||
return self._mute
|
||||
|
||||
def set_mute(self, value):
|
||||
"""Set mute state.
|
||||
|
||||
:class:`True` to mute, :class:`False` to unmute.
|
||||
... deprecated:: 0.20
|
||||
Use :meth:`core.mixer.get_mute()
|
||||
<mopidy.core.MixerController.get_mute>` instead.
|
||||
"""
|
||||
value = bool(value)
|
||||
if self.mixer:
|
||||
self.mixer.set_mute(value)
|
||||
else:
|
||||
# For testing
|
||||
self._mute = value
|
||||
warnings.warn('playback.get_mute() is deprecated', DeprecationWarning)
|
||||
return self.core.mixer.get_mute()
|
||||
|
||||
def set_mute(self, mute):
|
||||
"""
|
||||
... deprecated:: 0.20
|
||||
Use :meth:`core.mixer.set_mute()
|
||||
<mopidy.core.MixerController.set_mute>` instead.
|
||||
"""
|
||||
warnings.warn('playback.set_mute() is deprecated', DeprecationWarning)
|
||||
return self.core.mixer.set_mute(mute)
|
||||
|
||||
mute = deprecated_property(get_mute, set_mute)
|
||||
"""
|
||||
.. deprecated:: 0.20
|
||||
Use :meth:`get_mute` and :meth:`set_mute` instead.
|
||||
Use :meth:`core.mixer.get_mute()
|
||||
<mopidy.core.MixerController.get_mute>` and
|
||||
:meth:`core.mixer.set_mute()
|
||||
<mopidy.core.MixerController.set_mute>` instead.
|
||||
"""
|
||||
|
||||
# Methods
|
||||
|
||||
@ -43,6 +43,7 @@ def make_jsonrpc_wrapper(core_actor):
|
||||
'core.get_version': core.Core.get_version,
|
||||
'core.history': core.HistoryController,
|
||||
'core.library': core.LibraryController,
|
||||
'core.mixer': core.MixerController,
|
||||
'core.playback': core.PlaybackController,
|
||||
'core.playlists': core.PlaylistsController,
|
||||
'core.tracklist': core.TracklistController,
|
||||
@ -54,6 +55,7 @@ def make_jsonrpc_wrapper(core_actor):
|
||||
'core.get_version': core_actor.get_version,
|
||||
'core.history': core_actor.history,
|
||||
'core.library': core_actor.library,
|
||||
'core.mixer': core_actor.mixer,
|
||||
'core.playback': core_actor.playback,
|
||||
'core.playlists': core_actor.playlists,
|
||||
'core.tracklist': core_actor.tracklist,
|
||||
|
||||
28
tests/core/test_mixer.py
Normal file
28
tests/core/test_mixer.py
Normal file
@ -0,0 +1,28 @@
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
import unittest
|
||||
|
||||
from mopidy import core
|
||||
|
||||
|
||||
class CoreMixerTest(unittest.TestCase):
|
||||
def setUp(self): # noqa: N802
|
||||
self.core = core.Core(mixer=None, backends=[])
|
||||
|
||||
def test_volume(self):
|
||||
self.assertEqual(self.core.mixer.get_volume(), None)
|
||||
|
||||
self.core.mixer.set_volume(30)
|
||||
|
||||
self.assertEqual(self.core.mixer.get_volume(), 30)
|
||||
|
||||
self.core.mixer.set_volume(70)
|
||||
|
||||
self.assertEqual(self.core.mixer.get_volume(), 70)
|
||||
|
||||
def test_mute(self):
|
||||
self.assertEqual(self.core.mixer.get_mute(), False)
|
||||
|
||||
self.core.mixer.set_mute(True)
|
||||
|
||||
self.assertEqual(self.core.mixer.get_mute(), True)
|
||||
@ -426,21 +426,3 @@ class CorePlaybackTest(unittest.TestCase):
|
||||
self.assertFalse(self.playback2.get_time_position.called)
|
||||
|
||||
# TODO Test on_tracklist_change
|
||||
|
||||
def test_volume(self):
|
||||
self.assertEqual(self.core.playback.volume, None)
|
||||
|
||||
self.core.playback.volume = 30
|
||||
|
||||
self.assertEqual(self.core.playback.volume, 30)
|
||||
|
||||
self.core.playback.volume = 70
|
||||
|
||||
self.assertEqual(self.core.playback.volume, 70)
|
||||
|
||||
def test_mute(self):
|
||||
self.assertEqual(self.core.playback.mute, False)
|
||||
|
||||
self.core.playback.mute = True
|
||||
|
||||
self.assertEqual(self.core.playback.mute, True)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user