mixer: Add MixerListener
This commit is contained in:
parent
4d0fa17c85
commit
b8de7fa75c
@ -10,6 +10,9 @@ Audio mixer API
|
|||||||
.. autoclass:: mopidy.mixer.Mixer
|
.. autoclass:: mopidy.mixer.Mixer
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: mopidy.mixer.MixerListener
|
||||||
|
:members:
|
||||||
|
|
||||||
|
|
||||||
Mixer implementations
|
Mixer implementations
|
||||||
=====================
|
=====================
|
||||||
|
|||||||
@ -1,8 +1,16 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from mopidy import listener
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class Mixer(object):
|
class Mixer(object):
|
||||||
"""Audio mixer API
|
"""
|
||||||
|
Audio mixer API
|
||||||
|
|
||||||
If the mixer has problems during initialization it should raise
|
If the mixer has problems during initialization it should raise
|
||||||
:exc:`~mopidy.exceptions.MixerError` with a descriptive error message. This
|
:exc:`~mopidy.exceptions.MixerError` with a descriptive error message. This
|
||||||
@ -16,7 +24,8 @@ class Mixer(object):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
name = None
|
name = None
|
||||||
"""Name of the mixer.
|
"""
|
||||||
|
Name of the mixer.
|
||||||
|
|
||||||
Used when configuring what mixer to use. Should match the
|
Used when configuring what mixer to use. Should match the
|
||||||
:attr:`~mopidy.ext.Extension.ext_name` of the extension providing the
|
:attr:`~mopidy.ext.Extension.ext_name` of the extension providing the
|
||||||
@ -54,9 +63,20 @@ class Mixer(object):
|
|||||||
"""
|
"""
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def trigger_volume_changed(self, volume):
|
||||||
|
"""
|
||||||
|
Send ``volume_changed`` event to all mixer listeners.
|
||||||
|
|
||||||
|
This method should be called by subclasses when the volume is changed,
|
||||||
|
either because of a call to :meth:`set_volume` or because or any
|
||||||
|
external entity changing the volume.
|
||||||
|
"""
|
||||||
|
logger.debug('Mixer event: volume_changed(volume=%d)', volume)
|
||||||
|
MixerListener.send('volume_changed', volume=volume)
|
||||||
|
|
||||||
def get_mute(self):
|
def get_mute(self):
|
||||||
"""
|
"""
|
||||||
Get mute status of the mixer.
|
Get mute state of the mixer.
|
||||||
|
|
||||||
*MAY be implemented by subclass.*
|
*MAY be implemented by subclass.*
|
||||||
|
|
||||||
@ -76,3 +96,53 @@ class Mixer(object):
|
|||||||
:rtype: :class:`True` if success, :class:`False` if failure
|
:rtype: :class:`True` if success, :class:`False` if failure
|
||||||
"""
|
"""
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def trigger_mute_changed(self, muted):
|
||||||
|
"""
|
||||||
|
Send ``mute_changed`` event to all mixer listeners.
|
||||||
|
|
||||||
|
This method should be called by subclasses when the mute state is
|
||||||
|
changed, either because of a call to :meth:`set_mute` or because or
|
||||||
|
any external entity changing the mute state.
|
||||||
|
"""
|
||||||
|
logger.debug('Mixer event: mute_changed(muted=%s)', muted)
|
||||||
|
MixerListener.send('mute_changed', muted=muted)
|
||||||
|
|
||||||
|
|
||||||
|
class MixerListener(listener.Listener):
|
||||||
|
"""
|
||||||
|
Marker interface for recipients of events sent by the mixer actor.
|
||||||
|
|
||||||
|
Any Pykka actor that mixes in this class will receive calls to the methods
|
||||||
|
defined here when the corresponding events happen in the mixer actor. This
|
||||||
|
interface is used both for looking up what actors to notify of the events,
|
||||||
|
and for providing default implementations for those listeners that are not
|
||||||
|
interested in all events.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def send(event, **kwargs):
|
||||||
|
"""Helper to allow calling of audio listener events"""
|
||||||
|
listener.send_async(MixerListener, event, **kwargs)
|
||||||
|
|
||||||
|
def volume_changed(self, volume):
|
||||||
|
"""
|
||||||
|
Called after the volume has changed.
|
||||||
|
|
||||||
|
*MAY* be implemented by actor.
|
||||||
|
|
||||||
|
:param volume: the new volume
|
||||||
|
:type volume: int in range [0..100]
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def mute_changed(self, muted):
|
||||||
|
"""
|
||||||
|
Called after the mute state has changed.
|
||||||
|
|
||||||
|
*MAY* be implemented by actor.
|
||||||
|
|
||||||
|
:param muted: :class:`True` if muted, :class:`False` if not muted
|
||||||
|
:type muted: bool
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|||||||
26
tests/test_mixer.py
Normal file
26
tests/test_mixer.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
import mock
|
||||||
|
|
||||||
|
from mopidy import mixer
|
||||||
|
|
||||||
|
|
||||||
|
class MixerListenerTest(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.listener = mixer.MixerListener()
|
||||||
|
|
||||||
|
def test_on_event_forwards_to_specific_handler(self):
|
||||||
|
self.listener.volume_changed = mock.Mock()
|
||||||
|
|
||||||
|
self.listener.on_event(
|
||||||
|
'volume_changed', volume=60)
|
||||||
|
|
||||||
|
self.listener.volume_changed.assert_called_with(volume=60)
|
||||||
|
|
||||||
|
def test_listener_has_default_impl_for_volume_changed(self):
|
||||||
|
self.listener.volume_changed(volume=60)
|
||||||
|
|
||||||
|
def test_listener_has_default_impl_for_mute_changed(self):
|
||||||
|
self.listener.mute_changed(muted=True)
|
||||||
Loading…
Reference in New Issue
Block a user