Add volume control support to BaseBackend through alsaaudio.Mixer

This commit is contained in:
Stein Magnus Jodal 2010-02-22 19:47:25 +01:00
parent f9a9a0e82b
commit 0a6545f6d0
5 changed files with 48 additions and 14 deletions

View File

@ -14,6 +14,7 @@ Dependencies
============
* Python >= 2.5
* pyalsaaudio >= 0.2 (Debian/Ubuntu: python-alsaaudio)
* Dependencies for at least one Mopidy backend:
* :ref:`despotify`

View File

@ -3,6 +3,8 @@ import logging
import random
import time
import alsaaudio
from mopidy.models import Playlist
logger = logging.getLogger('backends.base')
@ -242,13 +244,10 @@ class BasePlaybackController(object):
#: The current track is played once.
repeat = False
#: The audio volume as an int in the range [0, 100]. :class:`None` if
#: unknown.
volume = None
def __init__(self, backend):
def __init__(self, backend, mixer=alsaaudio.Mixer):
self.backend = backend
self._state = self.STOPPED
self._mixer = mixer()
@property
def next_track(self):
@ -325,6 +324,19 @@ class BasePlaybackController(object):
def _play_time_resume(self):
self._play_time_started = int(time.time())
@property
def volume(self):
"""
The audio volume as an int in the range [0, 100].
:class:`None` if unknown.
"""
return self._mixer.getvolume()[0]
@volume.setter
def volume(self, volume):
self._mixer.setvolume(volume)
def new_playlist_loaded_callback(self):
"""Tell the playback controller that a new playlist has been loaded."""
self.current_track = None

View File

@ -7,7 +7,7 @@ class DummyBackend(BaseBackend):
def __init__(self):
self.current_playlist = DummyCurrentPlaylistController(backend=self)
self.library = DummyLibraryController(backend=self)
self.playback = DummyPlaybackController(backend=self)
self.playback = DummyPlaybackController(backend=self, mixer=DummyMixer)
self.stored_playlists = DummyStoredPlaylistsController(backend=self)
self.uri_handlers = [u'dummy:']
@ -37,3 +37,12 @@ class DummyPlaybackController(BasePlaybackController):
class DummyStoredPlaylistsController(BaseStoredPlaylistsController):
def search(self, query):
return [Playlist(name=query)]
class DummyMixer(object):
volume = 0
def getvolume(self):
return [self.volume, self.volume]
def setvolume(self, volume):
self.volume = volume

View File

@ -419,14 +419,15 @@ class MpdHandler(object):
def _seekid(self, songid, seconds):
raise MpdNotImplemented # TODO
@register(r'^setvol "(?P<volume>-*\d+)"$')
@register(r'^setvol (?P<volume>[-+]*\d+)$')
@register(r'^setvol "(?P<volume>[-+]*\d+)"$')
def _setvol(self, volume):
volume = int(volume)
if volume < 0:
volume = 0
if volume > 100:
volume = 100
raise MpdNotImplemented # TODO
self.backend.playback.volume = volume
@register(r'^shuffle$')
@register(r'^shuffle "(?P<start>\d+):(?P<end>\d+)*"$')

View File

@ -290,7 +290,8 @@ class StatusHandlerTest(unittest.TestCase):
class PlaybackOptionsHandlerTest(unittest.TestCase):
def setUp(self):
self.h = handler.MpdHandler(backend=DummyBackend())
self.b = DummyBackend()
self.h = handler.MpdHandler(backend=self.b)
def test_consume_off(self):
result = self.h.handle_request(u'consume "0"')
@ -322,23 +323,33 @@ class PlaybackOptionsHandlerTest(unittest.TestCase):
def test_setvol_below_min(self):
result = self.h.handle_request(u'setvol "-10"')
self.assert_(u'ACK Not implemented' in result)
self.assert_(u'OK' in result)
self.assertEqual(0, self.b.playback.volume)
def test_setvol_min(self):
result = self.h.handle_request(u'setvol "0"')
self.assert_(u'ACK Not implemented' in result)
self.assert_(u'OK' in result)
self.assertEqual(0, self.b.playback.volume)
def test_setvol_middle(self):
result = self.h.handle_request(u'setvol "50"')
self.assert_(u'ACK Not implemented' in result)
self.assert_(u'OK' in result)
self.assertEqual(50, self.b.playback.volume)
def test_setvol_max(self):
result = self.h.handle_request(u'setvol "100"')
self.assert_(u'ACK Not implemented' in result)
self.assert_(u'OK' in result)
self.assertEqual(100, self.b.playback.volume)
def test_setvol_above_max(self):
result = self.h.handle_request(u'setvol "110"')
self.assert_(u'ACK Not implemented' in result)
self.assert_(u'OK' in result)
self.assertEqual(100, self.b.playback.volume)
def test_setvol_plus_is_ignored(self):
result = self.h.handle_request(u'setvol "+10"')
self.assert_(u'OK' in result)
self.assertEqual(10, self.b.playback.volume)
def test_single_off(self):
result = self.h.handle_request(u'single "0"')