Merge branch 'gstreamer' of git://github.com/jodal/mopidy into gstreamer-local-backend

This commit is contained in:
Thomas Adamcik 2010-08-14 18:20:36 +02:00
commit 48dc3137d5
9 changed files with 72 additions and 30 deletions

View File

@ -34,6 +34,7 @@ greatly improved MPD client support.
``SPOTIFY_LIB_APPKEY`` setting is thus removed.
- Added new :mod:`mopidy.mixers.GStreamerSoftwareMixer` which now is the
default mixer on all platforms.
- New setting ``MIXER_MAX_VOLUME`` for capping the maximum output volume.
- MPD frontend:
- Relocate from :mod:`mopidy.mpd` to :mod:`mopidy.frontends.mpd`.

View File

@ -1,3 +1,5 @@
from mopidy import settings
class BaseMixer(object):
"""
:param backend: a backend instance
@ -6,6 +8,7 @@ class BaseMixer(object):
def __init__(self, backend, *args, **kwargs):
self.backend = backend
self.amplification_factor = settings.MIXER_MAX_VOLUME / 100.0
@property
def volume(self):
@ -15,11 +18,13 @@ class BaseMixer(object):
Integer in range [0, 100]. :class:`None` if unknown. Values below 0 is
equal to 0. Values above 100 is equal to 100.
"""
return self._get_volume()
if self._get_volume() is None:
return None
return int(self._get_volume() / self.amplification_factor)
@volume.setter
def volume(self, volume):
volume = int(volume)
volume = int(int(volume) * self.amplification_factor)
if volume < 0:
volume = 0
elif volume > 100:

View File

@ -22,10 +22,7 @@ class NadMixer(BaseMixer):
currently used by this mixer.
Sadly, this means that if you use the remote control to change the volume
on the amplifier, Mopidy will no longer report the correct volume. To
recalibrate the mixer, set the volume to 0 through Mopidy. This will reset
the amplifier to a known state, including powering on the device, selecting
the configured speakers and input sources.
on the amplifier, Mopidy will no longer report the correct volume.
**Dependencies**
@ -51,8 +48,6 @@ class NadMixer(BaseMixer):
def _set_volume(self, volume):
self._volume = volume
if volume == 0:
self._pipe.send({'command': 'reset_device'})
self._pipe.send({'command': 'set_volume', 'volume': volume})

View File

@ -167,15 +167,14 @@ class GStreamerProcess(BaseProcess):
:type state_name: string
:rtype: :class:`True` or :class:`False`
"""
state = getattr(gst, 'STATE_' + state_name)
self.gst_pipeline.set_state(state)
new_state = self.gst_pipeline.get_state()[1]
if new_state == state:
logger.debug('Setting GStreamer state to %s: OK', state_name)
return True
else:
result = self.gst_pipeline.set_state(
getattr(gst, 'STATE_' + state_name))
if result == gst.STATE_CHANGE_FAILURE:
logger.warning('Setting GStreamer state to %s: failed', state_name)
return False
else:
logger.debug('Setting GStreamer state to %s: OK', state_name)
return True
def get_volume(self):
"""Get volume in range [0..100]"""

View File

@ -115,6 +115,16 @@ MIXER_EXT_SPEAKERS_A = None
#: Default: :class:`None`.
MIXER_EXT_SPEAKERS_B = None
#: The maximum volume. Integer in the range 0 to 100.
#:
#: If this settings is set to 80, the mixer will set the actual volume to 80
#: when asked to set it to 100.
#:
#: Default::
#:
#: MIXER_MAX_VOLUME = 100
MIXER_MAX_VOLUME = 100
#: Audio output handler to use.
#:
#: Default::

View File

@ -271,18 +271,32 @@ class PlaybackControlHandlerTest(unittest.TestCase):
self.assert_(u'OK' in result)
def test_seek(self):
self.b.current_playlist.load([Track()])
self.b.current_playlist.load([Track(length=40000)])
self.h.handle_request(u'seek "0"')
result = self.h.handle_request(u'seek "0" "30"')
self.assert_(u'OK' in result)
self.assert_(self.b.playback.time_position > 30000)
self.assert_(self.b.playback.time_position >= 30000)
def test_seek_with_songpos(self):
seek_track = Track(uri='2', length=40000)
self.b.current_playlist.load(
[Track(uri='1', length=40000), seek_track])
result = self.h.handle_request(u'seek "1" "30"')
self.assertEqual(self.b.playback.current_track, seek_track)
def test_seekid(self):
self.b.current_playlist.load([Track()])
result = self.h.handle_request(u'seekid "0" "30"')
self.b.current_playlist.load([Track(length=40000)])
result = self.h.handle_request(u'seekid "1" "30"')
self.assert_(u'OK' in result)
self.assert_(self.b.playback.time_position > 30000)
self.assert_(self.b.playback.time_position >= 30000)
def test_seekid_with_cpid(self):
seek_track = Track(uri='2', length=40000)
self.b.current_playlist.load(
[Track(length=40000), seek_track])
result = self.h.handle_request(u'seekid "2" "30"')
self.assertEqual(self.b.playback.current_cpid, 2)
self.assertEqual(self.b.playback.current_track, seek_track)
def test_stop(self):
result = self.h.handle_request(u'stop')

View File

@ -1,18 +1,16 @@
import unittest
from mopidy.mixers.dummy import DummyMixer
class BaseMixerTest(unittest.TestCase):
class BaseMixerTest(object):
MIN = 0
MAX = 100
ACTUAL_MIN = MIN
ACTUAL_MAX = MAX
INITIAL = None
mixer_class = None
def setUp(self):
self.mixer = DummyMixer(None)
assert self.mixer_class is not None, \
"mixer_class must be set in subclass"
self.mixer = self.mixer_class(None)
def test_initial_volume(self):
self.assertEqual(self.mixer.volume, self.INITIAL)

View File

@ -1,3 +1,5 @@
import unittest
from mopidy.mixers.denon import DenonMixer
from tests.mixers.base_test import BaseMixerTest
@ -22,11 +24,12 @@ class DenonMixerDeviceMock(object):
def open(self):
self._open = True
class DenonMixerTest(BaseMixerTest):
class DenonMixerTest(BaseMixerTest, unittest.TestCase):
ACTUAL_MAX = 99
INITIAL = 1
mixer_class = DenonMixer
def setUp(self):
self.device = DenonMixerDeviceMock()
self.mixer = DenonMixer(None, device=self.device)

View File

@ -0,0 +1,17 @@
import unittest
from mopidy.mixers.dummy import DummyMixer
from tests.mixers.base_test import BaseMixerTest
class DenonMixerTest(BaseMixerTest, unittest.TestCase):
mixer_class = DummyMixer
def test_set_volume_is_capped(self):
self.mixer.amplification_factor = 0.5
self.mixer.volume = 100
self.assertEquals(self.mixer._volume, 50)
def test_get_volume_does_not_show_that_the_volume_is_capped(self):
self.mixer.amplification_factor = 0.5
self.mixer._volume = 50
self.assertEquals(self.mixer.volume, 100)