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

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

  1  # -*- Mode: Python -*- 
  2  # vi:si:et:sw=4:sts=4:ts=4 
  3   
  4  # Flumotion - a streaming media server 
  5  # Copyright (C) 2004,2005,2006,2007,2008,2009 Fluendo, S.L. 
  6  # Copyright (C) 2010,2011 Flumotion Services, S.A. 
  7  # All rights reserved. 
  8  # 
  9  # This file may be distributed and/or modified under the terms of 
 10  # the GNU Lesser General Public License version 2.1 as published by 
 11  # the Free Software Foundation. 
 12  # This file is distributed without any warranty; without even the implied 
 13  # warranty of merchantability or fitness for a particular purpose. 
 14  # See "LICENSE.LGPL" in the source distribution for more information. 
 15  # 
 16  # Headers in this file shall remain intact. 
 17   
 18  import gettext 
 19  import os 
 20   
 21  from zope.interface import implements 
 22   
 23  from flumotion.admin.assistant.interfaces import IProducerPlugin 
 24  from flumotion.admin.assistant.models import AudioProducer 
 25  from flumotion.common.errors import RemoteRunFailure 
 26  from flumotion.common.i18n import N_, gettexter 
 27  from flumotion.common.messages import Info 
 28  from flumotion.admin.gtk.basesteps import AudioProducerStep 
 29   
 30  __version__ = "$Rev$" 
 31  _ = gettext.gettext 
 32  T_ = gettexter() 
 33   
 34  CHANNELS = {1: _('Mono'), 
 35              2: _('Stereo')} 
 36   
 37  SAMPLE_RATES = [48000, 
 38                  44100, 
 39                  32000, 
 40                  22050, 
 41                  16000, 
 42                  11025, 
 43                  8000] 
 44   
 45  # TODO: Add other sources (pulse, jack, ...) 
 46  SOURCE_ELEMENTS = [(_('Alsa'), 'alsasrc'), 
 47                     (_('OSS'), 'osssrc')] 
 48   
 49   
50 -class SoundcardProducer(AudioProducer):
51 componentType = 'soundcard-producer' 52
53 - def __init__(self):
54 super(SoundcardProducer, self).__init__()
55 56
57 -class SoundcardStep(AudioProducerStep):
58 name = 'Soundcard' 59 title = _('Sound Card') 60 icon = 'soundcard.png' 61 gladeFile = os.path.join(os.path.dirname(os.path.abspath(__file__)), 62 'wizard.glade') 63 componentType = 'osssrc' 64 docSection = 'help-configuration-assistant-producer-audio-soundcard' 65 docAnchor = '' 66
67 - def __init__(self, wizard, model):
68 AudioProducerStep.__init__(self, wizard, model)
69 70 # WizardStep 71
72 - def setup(self):
73 self.input_track.data_type = str 74 self.channels.data_type = int 75 self.samplerate.data_type = int 76 self.depth.data_type = int 77 self.device.data_type = str 78 self.source_element.data_type = str 79 80 self.source_element.prefill(SOURCE_ELEMENTS) 81 82 self.add_proxy(self.model.properties, 83 ['input_track', 84 'channels', 85 'samplerate', 86 'depth', 87 'device', 88 'source_element']) 89 90 # Connect the callback after the combo has been filled so the changed 91 # signal is not emited before the page has been set uhas 92 self.source_element.connect('changed', self.on_source_element__changed)
93
94 - def workerChanged(self, worker):
95 self.model.worker = worker 96 self._blockCombos() 97 self._updateDevices()
98
99 - def getNext(self):
100 return None
101 102 # Private 103
104 - def _blockCombos(self, block=True):
105 self.input_track.set_sensitive(not block) 106 self.channels.set_sensitive(not block) 107 self.depth.set_sensitive(not block) 108 self.samplerate.set_sensitive(not block)
109
110 - def _updateDevices(self):
111 self.wizard.waitForTask('soundcard checks') 112 self.wizard.clear_msg('soundcard-check') 113 114 msg = Info(T_( 115 N_("Looking for the sound devices present on the system. " 116 "This can take a while...")), mid='soundcard-check') 117 self.wizard.add_msg(msg) 118 119 def checkFailed(failure): 120 failure.trap(RemoteRunFailure) 121 self.wizard.taskFinished(blockNext=True) 122 self._blockCombos()
123 124 def gotSoundDevices(devices): 125 self.wizard.clear_msg('soundcard-check') 126 self.wizard.taskFinished(False) 127 self.device.set_sensitive(True) 128 self.device.prefill(devices)
129 130 sourceElement = self.source_element.get_selected() 131 132 d = self.runInWorker( 133 'flumotion.worker.checks.audio', 'getAudioDevices', 134 sourceElement, mid='soundcard-check') 135 136 d.addCallback(gotSoundDevices) 137 d.addErrback(checkFailed) 138 139 return d 140
141 - def _updateInputtrack(self):
142 device = self.device.get_selected() 143 sourceElement = self.source_element.get_selected() 144 145 if not device: 146 return 147 148 self.wizard.waitForTask('soundcard checks') 149 msg = Info(T_( 150 N_("Probing the sound card. This can take a while...")), 151 mid='soundcard-check') 152 self.wizard.add_msg(msg) 153 154 def checkFailed(failure): 155 failure.trap(RemoteRunFailure) 156 self._blockCombos() 157 self.wizard.taskFinished(True)
158 159 def soundcardCheckComplete((deviceName, tracks, caps)): 160 self.wizard.clear_msg('soundcard-check') 161 self.wizard.taskFinished(False) 162 self._caps = caps 163 self.input_track.prefill(tracks) 164 self.input_track.set_sensitive(bool(tracks)) 165 166 d = self.runInWorker( 167 'flumotion.worker.checks.audio', 'checkMixerTracks', 168 sourceElement, device, mid='soundcard-check') 169 170 d.addCallback(soundcardCheckComplete) 171 d.addErrback(checkFailed) 172 173 return d 174
175 - def _updateDepth(self):
176 bitdepths = {} 177 for capStruct in self._caps: 178 data = capStruct.copy() 179 bitdepths[data.pop('depth')] = data 180 self._capStructs = bitdepths 181 bitdepths = sorted(bitdepths) 182 self.depth.prefill( 183 [(_('%d-bit') % bitdepth, bitdepth) for bitdepth in bitdepths]) 184 self.depth.set_sensitive(True)
185
186 - def _updateChannels(self):
187 capStruct = self._capStructs.get(self.depth.get_selected()) 188 if capStruct is None: 189 return 190 channels = [] 191 if type(capStruct['channels']) == int: 192 nchannels = capStruct['channels'] 193 channels.append((CHANNELS[nchannels], nchannels)) 194 else: 195 for nchannels in capStruct['channels']: 196 channels.append((CHANNELS[nchannels], nchannels)) 197 198 self.channels.prefill(channels) 199 self.channels.set_sensitive(True)
200
201 - def _updateSamplerate(self):
202 capStruct = self._capStructs.get(self.depth.get_selected()) 203 if capStruct is None: 204 return 205 if type(capStruct['rate']) == int: 206 maxRate = minRate = capStruct['rate'] 207 else: 208 maxRate, minRate = capStruct['rate'] 209 210 self.samplerate.prefill( 211 [(str(rate), rate) for rate in SAMPLE_RATES 212 if minRate <= rate <= maxRate]) 213 self.samplerate.set_sensitive(True)
214 215 # Callbacks 216
217 - def on_source_element__changed(self, combo):
218 self._updateDevices()
219
220 - def on_device__changed(self, combo):
221 self._updateInputtrack()
222
223 - def on_input_track__changed(self, combo):
224 self._updateDepth() 225 self._updateChannels()
226
227 - def on_depth__changed(self, combo):
228 self._updateSamplerate()
229 230
231 -class SoundcardWizardPlugin(object):
232 implements(IProducerPlugin) 233
234 - def __init__(self, wizard):
235 self.wizard = wizard 236 self.model = SoundcardProducer()
237
238 - def getProductionStep(self, type):
239 return SoundcardStep(self.wizard, self.model)
240