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