From 8281128a2eff054a14229e4b1471ff1278bbe3b1 Mon Sep 17 00:00:00 2001 From: Thomas Adamcik Date: Tue, 4 Sep 2012 01:04:59 +0200 Subject: [PATCH] Move mixers out of gstreamer module. Mixers now live in mopidy.mixers.. Futhermore mopidy.mixers should now import each of the mixers so that doing import mopidy.mixers is enough to install the gstreamer elements. --- mopidy/gstreamer.py | 143 +------------------------------------- mopidy/mixers/__init__.py | 2 + mopidy/mixers/auto.py | 72 +++++++++++++++++++ mopidy/mixers/fake.py | 80 +++++++++++++++++++++ 4 files changed, 155 insertions(+), 142 deletions(-) create mode 100644 mopidy/mixers/__init__.py create mode 100644 mopidy/mixers/auto.py create mode 100644 mopidy/mixers/fake.py diff --git a/mopidy/gstreamer.py b/mopidy/gstreamer.py index de5f988e..7bf5f370 100644 --- a/mopidy/gstreamer.py +++ b/mopidy/gstreamer.py @@ -1,6 +1,5 @@ import pygst pygst.require('0.10') -import gobject import gst import logging @@ -10,151 +9,11 @@ from pykka.registry import ActorRegistry from mopidy import settings, utils from mopidy.backends.base import Backend +from mopidy import mixers # Trigger install of gst mixer plugins. logger = logging.getLogger('mopidy.gstreamer') -# TODO: we might want to add some ranking to the mixers we know about? -# TODO: move to mixers module and do from mopidy.mixers import * to install -# elements. -class AutoAudioMixer(gst.Bin): - __gstdetails__ = ('AutoAudioMixer', - 'Mixer', - 'Element automatically selects a mixer.', - 'Thomas Adamcik') - - def __init__(self): - gst.Bin.__init__(self) - mixer = self._find_mixer() - if mixer: - self.add(mixer) - logger.debug('AutoAudioMixer chose: %s', mixer.get_name()) - else: - logger.debug('AutoAudioMixer did not find any usable mixers') - - def _find_mixer(self): - registry = gst.registry_get_default() - - factories = registry.get_feature_list(gst.TYPE_ELEMENT_FACTORY) - factories.sort(key=lambda f: (-f.get_rank(), f.get_name())) - - for factory in factories: - # Avoid sink/srcs that implment mixing. - if factory.get_klass() != 'Generic/Audio': - continue - # Avoid anything that doesn't implment mixing. - elif not factory.has_interface('GstMixer'): - continue - - if self._test_mixer(factory): - return factory.create() - - return None - - def _test_mixer(self, factory): - element = factory.create() - if not element: - return False - - try: - result = element.set_state(gst.STATE_READY) - if result != gst.STATE_CHANGE_SUCCESS: - return False - - # Trust that the default device is sane and just check tracks. - return self._test_tracks(element) - finally: - element.set_state(gst.STATE_NULL) - - def _test_tracks(self, element): - # Only allow elements that have a least one output track. - flags = gst.interfaces.MIXER_TRACK_OUTPUT - - for track in element.list_tracks(): - if track.flags & flags: - return True - return False - - -gobject.type_register(AutoAudioMixer) -gst.element_register (AutoAudioMixer, 'autoaudiomixer', gst.RANK_MARGINAL) - - -def create_fake_track(label, intial_volume, min_volume, max_volume, - num_channels, flags): - class Track(gst.interfaces.MixerTrack): - def __init__(self): - super(Track, self).__init__() - self.volumes = (intial_volume,) * self.num_channels - - @gobject.property - def label(self): - return label - - @gobject.property - def min_volume(self): - return min_volume - - @gobject.property - def max_volume(self): - return max_volume - - @gobject.property - def num_channels(self): - return num_channels - - @gobject.property - def flags(self): - return flags - - return Track() - - -class FakeMixer(gst.Element, gst.ImplementsInterface, gst.interfaces.Mixer): - __gstdetails__ = ('FakeMixer', - 'Mixer', - 'Fake mixer for use in tests.', - 'Thomas Adamcik') - - track_label = gobject.property(type=str, default='Master') - - track_initial_volume = gobject.property(type=int, default=0) - - track_min_volume = gobject.property(type=int, default=0) - - track_max_volume = gobject.property(type=int, default=100) - - track_num_channels = gobject.property(type=int, default=2) - - track_flags = gobject.property(type=int, - default=(gst.interfaces.MIXER_TRACK_MASTER | - gst.interfaces.MIXER_TRACK_OUTPUT)) - - def __init__(self): - gst.Element.__init__(self) - - def list_tracks(self): - track = create_fake_track(self.track_label, - self.track_initial_volume, - self.track_min_volume, - self.track_max_volume, - self.track_num_channels, - self.track_flags) - return [track] - - def get_volume(self, track): - return track.volumes - - def set_volume(self, track, volumes): - track.volumes = volumes - - def set_record(self, track, record): - pass - -gobject.type_register(FakeMixer) -gst.element_register (FakeMixer, 'fakemixer', gst.RANK_MARGINAL) - - class GStreamer(ThreadingActor): """ Audio output through `GStreamer `_. diff --git a/mopidy/mixers/__init__.py b/mopidy/mixers/__init__.py new file mode 100644 index 00000000..cf282a03 --- /dev/null +++ b/mopidy/mixers/__init__.py @@ -0,0 +1,2 @@ +from mopidy.mixers.auto import AutoAudioMixer +from mopidy.mixers.fake import FakeMixer diff --git a/mopidy/mixers/auto.py b/mopidy/mixers/auto.py new file mode 100644 index 00000000..4b4ce543 --- /dev/null +++ b/mopidy/mixers/auto.py @@ -0,0 +1,72 @@ +import pygst +pygst.require('0.10') +import gobject +import gst + +import logging + +logger = logging.getLogger('mopidy.mixers.auto') + + +# TODO: we might want to add some ranking to the mixers we know about? +class AutoAudioMixer(gst.Bin): + __gstdetails__ = ('AutoAudioMixer', + 'Mixer', + 'Element automatically selects a mixer.', + 'Thomas Adamcik') + + def __init__(self): + gst.Bin.__init__(self) + mixer = self._find_mixer() + if mixer: + self.add(mixer) + logger.debug('AutoAudioMixer chose: %s', mixer.get_name()) + else: + logger.debug('AutoAudioMixer did not find any usable mixers') + + def _find_mixer(self): + registry = gst.registry_get_default() + + factories = registry.get_feature_list(gst.TYPE_ELEMENT_FACTORY) + factories.sort(key=lambda f: (-f.get_rank(), f.get_name())) + + for factory in factories: + # Avoid sink/srcs that implment mixing. + if factory.get_klass() != 'Generic/Audio': + continue + # Avoid anything that doesn't implment mixing. + elif not factory.has_interface('GstMixer'): + continue + + if self._test_mixer(factory): + return factory.create() + + return None + + def _test_mixer(self, factory): + element = factory.create() + if not element: + return False + + try: + result = element.set_state(gst.STATE_READY) + if result != gst.STATE_CHANGE_SUCCESS: + return False + + # Trust that the default device is sane and just check tracks. + return self._test_tracks(element) + finally: + element.set_state(gst.STATE_NULL) + + def _test_tracks(self, element): + # Only allow elements that have a least one output track. + flags = gst.interfaces.MIXER_TRACK_OUTPUT + + for track in element.list_tracks(): + if track.flags & flags: + return True + return False + + +gobject.type_register(AutoAudioMixer) +gst.element_register (AutoAudioMixer, 'autoaudiomixer', gst.RANK_MARGINAL) diff --git a/mopidy/mixers/fake.py b/mopidy/mixers/fake.py new file mode 100644 index 00000000..de0f6a50 --- /dev/null +++ b/mopidy/mixers/fake.py @@ -0,0 +1,80 @@ +import pygst +pygst.require('0.10') +import gobject +import gst + + +def create_fake_track(label, intial_volume, min_volume, max_volume, + num_channels, flags): + class Track(gst.interfaces.MixerTrack): + def __init__(self): + super(Track, self).__init__() + self.volumes = (intial_volume,) * self.num_channels + + @gobject.property + def label(self): + return label + + @gobject.property + def min_volume(self): + return min_volume + + @gobject.property + def max_volume(self): + return max_volume + + @gobject.property + def num_channels(self): + return num_channels + + @gobject.property + def flags(self): + return flags + + return Track() + + +class FakeMixer(gst.Element, gst.ImplementsInterface, gst.interfaces.Mixer): + __gstdetails__ = ('FakeMixer', + 'Mixer', + 'Fake mixer for use in tests.', + 'Thomas Adamcik') + + track_label = gobject.property(type=str, default='Master') + + track_initial_volume = gobject.property(type=int, default=0) + + track_min_volume = gobject.property(type=int, default=0) + + track_max_volume = gobject.property(type=int, default=100) + + track_num_channels = gobject.property(type=int, default=2) + + track_flags = gobject.property(type=int, + default=(gst.interfaces.MIXER_TRACK_MASTER | + gst.interfaces.MIXER_TRACK_OUTPUT)) + + def __init__(self): + gst.Element.__init__(self) + + def list_tracks(self): + track = create_fake_track(self.track_label, + self.track_initial_volume, + self.track_min_volume, + self.track_max_volume, + self.track_num_channels, + self.track_flags) + return [track] + + def get_volume(self, track): + return track.volumes + + def set_volume(self, track, volumes): + track.volumes = volumes + + def set_record(self, track, record): + pass + + +gobject.type_register(FakeMixer) +gst.element_register (FakeMixer, 'fakemixer', gst.RANK_MARGINAL)