Package flumotion :: Package component :: Package producers :: Package soundcard :: Module soundcard
[hide private]

Source Code for Module flumotion.component.producers.soundcard.soundcard

  1  # -*- Mode: Python; test-case-name:flumotion.test.test_soundcard -*- 
  2  # vi:si:et:sw=4:sts=4:ts=4 
  3  # 
  4  # Flumotion - a streaming media server 
  5  # Copyright (C) 2004,2005,2006,2007 Fluendo, S.L. (www.fluendo.com). 
  6  # All rights reserved. 
  7   
  8  # This file may be distributed and/or modified under the terms of 
  9  # the GNU General Public License version 2 as published by 
 10  # the Free Software Foundation. 
 11  # This file is distributed without any warranty; without even the implied 
 12  # warranty of merchantability or fitness for a particular purpose. 
 13  # See "LICENSE.GPL" in the source distribution for more information. 
 14   
 15  # Licensees having purchased or holding a valid Flumotion Advanced 
 16  # Streaming Server license may use this file in accordance with the 
 17  # Flumotion Advanced Streaming Server Commercial License Agreement. 
 18  # See "LICENSE.Flumotion" in the source distribution for more information. 
 19   
 20  # Headers in this file shall remain intact. 
 21   
 22  import gst 
 23  import gst.interfaces 
 24   
 25  from twisted.internet import defer 
 26   
 27  from flumotion.component import feedcomponent 
 28  from flumotion.component.effects.volume import volume 
 29  from flumotion.common import messages 
 30  from flumotion.common.messages import N_ 
 31  T_ = messages.gettexter('flumotion') 
 32   
33 -class Soundcard(feedcomponent.ParseLaunchComponent):
34 - def do_check(self):
35 self.debug('running PyGTK/PyGST checks') 36 from flumotion.component.producers import checks 37 d1 = checks.checkTicket347() 38 d2 = checks.checkTicket348() 39 dl = defer.DeferredList([d1, d2]) 40 dl.addCallback(self._checkCallback) 41 return dl
42
43 - def _checkCallback(self, results):
44 for (state, result) in results: 45 for m in result.messages: 46 self.addMessage(m)
47
48 - def get_pipeline_string(self, properties):
49 element = properties.get('source-element', 'alsasrc') 50 device = properties.get('device', 'hw:0') 51 rate = properties.get('rate', 44100) 52 depth = properties.get('depth', 16) 53 channels = properties.get('channels', 2) 54 self.inputTrackLabel = properties.get('input-track', None) 55 d = self._change_monitor.add(gst.STATE_CHANGE_NULL_TO_READY) 56 d.addCallback(self._set_input_track, self.inputTrackLabel) 57 # FIXME: we should find a way to figure out what the card supports, 58 # so we can add in correct elements on the fly 59 # just adding audioscale and audioconvert always makes the soundcard 60 # open in 1000 Hz, mono 61 caps = 'audio/x-raw-int,rate=(int)%d,depth=%d,channels=%d' % ( 62 rate, depth, channels) 63 pipeline = "%s device=%s name=src ! %s ! " \ 64 "level name=volumelevel message=true" % ( 65 element, device, caps) 66 self._srcelement = None 67 return pipeline
68
69 - def configure_pipeline(self, pipeline, properties):
70 # add volume effect 71 comp_level = pipeline.get_by_name('volumelevel') 72 allowVolumeSet = True 73 if gst.pygst_version < (0, 10, 7): 74 allowVolumeSet = False 75 m = messages.Info(T_( 76 N_("The soundcard volume cannot be changed with this version of the 'gst-python' library.\n")), id = 'mixer-track-setting') 77 m.add(T_(N_("Please upgrade '%s' to version %s or later if you desire this functionality."), 78 'gst-python', '0.10.7')) 79 self.addMessage(m) 80 81 vol = volume.Volume('inputVolume', comp_level, pipeline, 82 allowIncrease=False, allowVolumeSet=allowVolumeSet) 83 self.addEffect(vol) 84 self._srcelement = pipeline.get_by_name("src")
85
86 - def _set_input_track(self, result, trackLabel=None):
87 element = self._srcelement 88 for track in element.list_tracks(): 89 if trackLabel != None: 90 self.debug("Setting track %s to record", trackLabel) 91 # some low-end sound cards require the Capture track to be 92 # set to recording to get any sound, so set that track and 93 # the input track we selected 94 element.set_record(track, 95 (track.get_property("label") == trackLabel or 96 track.get_property("label") == "Capture"))
97
98 - def setVolume(self, value):
99 if gst.pygst_version < (0, 10, 7): 100 self.warning( 101 "Cannot set volume on soundcards with gst-python < 0.10.7") 102 return 103 self.debug("Volume set to: %f", value) 104 if self.inputTrackLabel and self._srcelement: 105 element = self._srcelement 106 volumeSet = False 107 for track in element.list_tracks(): 108 if track.get_property("label") == self.inputTrackLabel: 109 volumeVals = tuple(int(value/1.0 * 110 track.get_property("max-volume")) 111 for _ in xrange(0, track.get_property("num-channels"))) 112 element.set_volume(track, volumeVals) 113 volumeSet = True 114 break 115 if not volumeSet: 116 self.warning("could not find track %s", self.inputTrackLabel) 117 else: 118 self.warning("no input track selected, cannot set volume")
119
120 - def getVolume(self):
121 if gst.pygst_version < (0, 10, 7): 122 self.warning( 123 "Cannot query volume on soundcards with gst-python < 0.10.7") 124 return 1.0 125 if self.inputTrackLabel and self._srcelement: 126 element = self._srcelement 127 for track in element.list_tracks(): 128 if track.get_property("label") == self.inputTrackLabel: 129 volumeVals = element.get_volume(track) 130 vol = 0 131 nchannels = track.get_property("num-channels") 132 for k in range(0, track.get_property("num-channels")): 133 vol = vol + (volumeVals[k] / nchannels) 134 self.debug("vol: %f max vol: %d", vol, track.get_property("max-volume")) 135 v = vol / float(track.get_property("max-volume")) 136 self.debug("v: %f", v) 137 return v 138 self.warning("could not find track %s", self.inputTrackLabel) 139 else: 140 self.warning("no input track selected, cannot set volume") 141 return 1.0
142