Add new option to restart audio after standby. Made for users having
[enigma2-plugins.git] / audiosync / src / AC3main.py
1 from AC3delay import AC3delay
2 from AC3utils import AC3, PCM, AC3GLOB, PCMGLOB, AC3PCM, SKIN
3 from Components.Label import Label, MultiColorLabel
4 from Components.Pixmap import MultiPixmap
5 from Components.ProgressBar import ProgressBar
6 from Components.SystemInfo import SystemInfo
7 from Components.config import config, config
8 from HelpableNumberActionMap import HelpableNumberActionMap
9 from MovableScreen import MovableScreen
10 from Screens import Standby
11 from Screens.ChoiceBox import ChoiceBox
12 from Screens.HelpMenu import HelpableScreen
13 from Screens.MessageBox import MessageBox
14 from Screens.Screen import Screen
15 from __init__ import _
16 from enigma import ePoint, eTimer
17
18 class AC3LipSync(Screen, HelpableScreen, MovableScreen):
19
20     def __init__(self, session, plugin_path):
21         Screen.__init__(self, session)
22         self.onShow.append(self.__onShow)
23         self.skin = SKIN
24         self.skin_path = plugin_path
25
26         # Configuration values
27         self.upperBound = int(config.plugins.AC3LipSync.outerBounds.getValue())
28         self.lowerBound = -1 * self.upperBound
29         self.arrowStepSize = int(config.plugins.AC3LipSync.arrowStepSize.getValue())
30         self.stepSize = {}
31         self.stepSize["3"] = int(config.plugins.AC3LipSync.stepSize13.getValue())
32         self.stepSize["1"] = -1 * self.stepSize["3"]
33         self.stepSize["6"] = int(config.plugins.AC3LipSync.stepSize46.getValue())
34         self.stepSize["4"] = -1 * self.stepSize["6"]
35         self.stepSize["9"] = int(config.plugins.AC3LipSync.stepSize79.getValue())
36         self.stepSize["7"] = -1 * self.stepSize["9"]
37         self.keyStep = {}
38         self.keyStep["0"] = 0
39         self.keyStep["2"] = int(config.plugins.AC3LipSync.absoluteStep2.getValue()) 
40         self.keyStep["5"] = int(config.plugins.AC3LipSync.absoluteStep5.getValue()) 
41         self.keyStep["8"] = int(config.plugins.AC3LipSync.absoluteStep8.getValue()) 
42
43         # AC3delay instance
44         self.AC3delay = AC3delay()
45
46         # Last saved values
47         self.savedValue = {}
48         # Current Values
49         self.currentValue = {}
50         
51         #OptionFields
52         self["ChannelImg"] = MultiPixmap()
53         self["GlobalImg"] = MultiPixmap()
54         
55         self["ChannelLabel"] = MultiColorLabel( _("Service delay"))
56         self["GlobalLabel"] = MultiColorLabel( _("Global delay"))
57
58         # Slider
59         self["AudioSliderBar"] = ProgressBar()
60         self["AudioSlider"] = Label(_("%i ms")%self.AC3delay.systemDelay[self.AC3delay.whichAudio])
61         
62         #Service Information
63         self["ServiceInfoLabel"] = Label(_("Channel audio:"))
64         self["ServiceInfo"] = Label()
65         self.setChannelInfoText()
66
67         # Buttons
68         self["key_red"] = Label(_("Cancel"))
69         self["key_green"] = Label(_("OK"))
70         self["key_blue"] = Label(_("Save to key"))
71
72         # Actions
73         self["actions"] = HelpableNumberActionMap(self, "PluginAudioSyncActions",
74         {
75             "menu":     (self.keyMenu,              _("Open plugin menu")),
76             "ok":       (self.keyOk,                _("Save values and close plugin")),
77             "cancel":   (self.keyCancel,            _("Discard changes and close plugin")),
78             "left":     (self.keyLeft,              _("Change active delay")),
79             "right":    (self.keyRight,             _("Change active delay")),
80             "up":       (self.keyUp,                _("Increase delay")),
81             "down":     (self.keyDown,              _("Decrease delay")),
82             "red":      (self.keyCancel,            _("Discard changes and close plugin")),
83             "green":    (self.keyOk,                _("Save values and close plugin")),
84             "blue":     (self.menuSaveDelayToKey,    _("Save current delay to key")),
85             "1":        (self.keyNumberRelative,    _("Decrease delay by %i ms (can be set)")%self.stepSize["1"]),
86             "3":        (self.keyNumberRelative,    _("Increase delay by %i ms (can be set)")%self.stepSize["3"]),
87             "4":        (self.keyNumberRelative,    _("Decrease delay by %i ms (can be set)")%self.stepSize["4"]),
88             "6":        (self.keyNumberRelative,    _("Increase delay by %i ms (can be set)")%self.stepSize["6"]),
89             "7":        (self.keyNumberRelative,    _("Decrease delay by %i ms (can be set)")%self.stepSize["7"]),
90             "9":        (self.keyNumberRelative,    _("Increase delay by %i ms (can be set)")%self.stepSize["9"]),
91             "0":        (self.keyNumberAbsolute,    _("Set delay to %i ms (can be set)")%self.keyStep["0"]),
92             "2":        (self.keyNumberAbsolute,    _("Set delay to %i ms (can be set)")%self.keyStep["2"]),
93             "5":        (self.keyNumberAbsolute,    _("Set delay to %i ms (can be set)")%self.keyStep["5"]),
94             "8":        (self.keyNumberAbsolute,    _("Set delay to %i ms (can be set)")%self.keyStep["8"])
95         }, -1)
96
97         HelpableScreen.__init__(self)
98         MovableScreen.__init__(self, config.plugins.AC3LipSync, [self["actions"]], 600, 460)
99         
100     def __onShow(self):
101         for sAudio in AC3PCM:
102             iDelay = self.AC3delay.getSystemDelay(sAudio)
103             self.savedValue[sAudio] = iDelay
104             self.currentValue[sAudio] = iDelay
105
106         self["AudioSliderBar"].setRange([(self.lowerBound), (self.upperBound)])
107         self.setActiveSlider()
108         self.movePosition()
109
110     def keyLeft(self):
111         if self.AC3delay.whichAudio == PCMGLOB:
112             self.AC3delay.whichAudio = PCM
113         elif self.AC3delay.whichAudio == AC3GLOB:
114             self.AC3delay.whichAudio = AC3
115         
116         self.setActiveSlider()
117
118     def keyRight(self):
119         if self.AC3delay.whichAudio == AC3:
120             self.AC3delay.whichAudio = AC3GLOB
121         elif self.AC3delay.whichAudio == PCM:
122             self.AC3delay.whichAudio = PCMGLOB
123
124         self.setActiveSlider()
125
126     def setActiveSlider(self):
127         # Reset colors of all tabs
128         if self.AC3delay.whichAudio in (AC3,PCM):
129             self["ChannelImg"].setPixmapNum(1)
130             self["GlobalImg"].setPixmapNum(0)
131             self["ChannelLabel"].setForegroundColorNum(1)
132             self["GlobalLabel"].setForegroundColorNum(0)        
133         else:    
134             self["ChannelImg"].setPixmapNum(0)
135             self["GlobalImg"].setPixmapNum(1)
136             self["ChannelLabel"].setForegroundColorNum(0)
137             self["GlobalLabel"].setForegroundColorNum(1)
138         
139         iCurDelay = self.currentValue[self.AC3delay.whichAudio]
140         iDelay = iCurDelay - self.lowerBound
141         self["AudioSliderBar"].setValue(iDelay)
142         self["AudioSlider"].setText(_("%i ms")%iCurDelay)
143
144     def keyDown(self):
145         if self.AC3delay.whichAudio == AC3GLOB or self.AC3delay.whichAudio == PCMGLOB:
146             iStep = -25
147         else:
148             iStep = -1 * self.arrowStepSize
149         self.changeSliderValue(iStep)
150         
151     def keyUp(self):
152         if self.AC3delay.whichAudio == AC3GLOB or self.AC3delay.whichAudio == PCMGLOB:
153             iStep = 25
154         else:
155             iStep = self.arrowStepSize
156         self.changeSliderValue(iStep)
157
158     def keyNumberAbsolute(self, number):
159         sAudio = self.AC3delay.whichAudio
160         sNumber = str(number)
161         if self.AC3delay.whichAudio == AC3GLOB or self.AC3delay.whichAudio == PCMGLOB:
162             iStep = ( self.keyStep[sNumber] // 25 ) * 25
163         else:
164             iStep = self.keyStep[sNumber]        
165         iSliderValue = iStep-self.lowerBound
166         self.setSliderInfo(iSliderValue)
167         self.AC3delay.setSystemDelay(sAudio, self.currentValue[sAudio], True)
168
169     def keyNumberRelative(self, number):
170         sNumber = str(number)
171         if self.AC3delay.whichAudio == AC3GLOB or self.AC3delay.whichAudio == PCMGLOB:
172             iStep = ( self.stepSize[sNumber] // 25 ) * 25
173         else:
174             iStep = self.stepSize[sNumber]
175
176         self.changeSliderValue(iStep)
177
178     def changeSliderValue(self,iValue):
179         sAudio = self.AC3delay.whichAudio
180         iSliderValue = int(self["AudioSliderBar"].getValue())
181         iSliderValue += iValue
182         if iSliderValue < 0:
183             iSliderValue = 0
184         elif iSliderValue > (self.upperBound - self.lowerBound):
185             iSliderValue = (self.upperBound - self.lowerBound)
186         self.setSliderInfo(iSliderValue)
187         self.AC3delay.setSystemDelay(sAudio, self.currentValue[sAudio], True)        
188
189     def keyOk(self):
190         self.close()
191
192     def keyCancel(self):
193         for sAudio in AC3PCM:
194             iSliderValue = self.currentValue[sAudio]
195             if iSliderValue <> self.savedValue[sAudio]:
196                 self.AC3delay.whichAudio = sAudio
197                 self.AC3delay.setSystemDelay(sAudio, self.savedValue[sAudio], False)
198         self.close()
199
200     def keyMenu(self):
201         sAudio = self.AC3delay.whichAudio
202         iDelay = self["AudioSliderBar"].getValue()+self.lowerBound
203         keyList = [
204             (_("Move plugin screen"),"1")
205         ]
206
207         self.session.openWithCallback(self.DoShowMenu,ChoiceBox,_("Menu"),keyList)
208     
209     def DoShowMenu(self, answer):
210         if answer is not None:
211             if answer[1] == "1":
212                 self.startMoving()
213             else:
214                 sResponse = _("Invalid selection")
215                 iType = MessageBox.TYPE_ERROR
216                 self.session.open(MessageBox, sResponse , iType)
217                 
218     def menuSaveDelayToKey(self):
219         sAudio = self.AC3delay.whichAudio
220         iDelay = self["AudioSliderBar"].getValue()+self.lowerBound
221
222         AC3SetCustomValue(self.session,iDelay,self.keyStep)
223         
224     def setSliderInfo(self, iDelay):
225         sAudio = self.AC3delay.whichAudio
226         self.currentValue[sAudio] = iDelay + self.lowerBound
227         iCurDelay = self.currentValue[sAudio]
228         self["AudioSliderBar"].setValue(iDelay)
229         self["AudioSlider"].setText(_("%i ms")%iCurDelay)
230
231     def setChannelInfoText(self):
232         sActiveAudio = str(self.AC3delay.selectedAudioInfo[0])
233         sBitstreamDelay = _("%i ms") %self.AC3delay.systemDelay[AC3]
234         sPCMDelay = _("%i ms") %self.AC3delay.systemDelay[PCM]
235
236         self["ServiceInfo"].setText(sActiveAudio)
237             
238 class AC3SetCustomValue:
239     def __init__(self, session, iDelay, keyStep):
240         self.keyStep = keyStep
241         self.session = session
242         self.iDelay = iDelay
243         self.session.openWithCallback(self.DoSetCustomValue,ChoiceBox,_("Select the key you want to set to %i ms") %(iDelay),self.getKeyList())
244
245     def getKeyList(self):
246         keyList = []
247         for i,iValue in self.keyStep.iteritems():
248             if i != "0":
249                 keyList.append((_("Key %(key)s (current value: %(value)i ms)") %dict(key=i, value=iValue),i))
250         return keyList
251
252     def DoSetCustomValue(self,answer):
253         if answer is None:
254             self.session.open(MessageBox,_("Setting key canceled"), MessageBox.TYPE_INFO)
255         elif answer[1] in ("2" , "5" , "8"):
256             if answer[1] == "2":
257                 config.plugins.AC3LipSync.absoluteStep2.setValue(self.iDelay)
258                 config.plugins.AC3LipSync.absoluteStep2.save()
259             elif  answer[1] == "5":
260                 config.plugins.AC3LipSync.absoluteStep5.setValue(self.iDelay)
261                 config.plugins.AC3LipSync.absoluteStep5.save()
262             elif  answer[1] == "8":
263                 config.plugins.AC3LipSync.absoluteStep8.setValue(self.iDelay)
264                 config.plugins.AC3LipSync.absoluteStep8.save()
265             self.keyStep[answer[1]] = self.iDelay
266             self.session.open(MessageBox,_("Key %(Key)s successfully set to %(delay)i ms") %dict(Key=answer[1],delay=self.iDelay), MessageBox.TYPE_INFO, 5)
267         else:
268             self.session.open(MessageBox,_("Invalid selection"), MessageBox.TYPE_ERROR, 5)
269
270 class AudioTools():
271     def __init__(self):
272         self.activateTimer = eTimer()
273         self.activateTimer.callback.append(self.restartAudio)
274         config.misc.standbyCounter.addNotifier(self.enterStandby, initial_call = False)
275
276     def enterStandby(self,configElement):
277         Standby.inStandby.onClose.append(self.endStandby)
278       
279     def endStandby(self):
280         self.audioRestart()
281
282     def audioRestart(self):
283         self.activateDelay = config.plugins.AC3LipSync.restartAudioDelay.value*1000
284         print "[AudioSync] audio restart in ",self.activateDelay
285         self.activateTimer.start(self.activateDelay, True)
286
287     def restartAudio(self):
288         ac3delay = AC3delay()
289         if (ac3delay.channelAudio == AC3) and (SystemInfo["CanDownmixAC3"]) and (config.av.downmix_ac3.value == False):
290             config.av.downmix_ac3.value = True
291             config.av.downmix_ac3.save()
292             config.av.downmix_ac3.value = False
293             config.av.downmix_ac3.save()
294             print "[AudioSync] audio restartet"
295
296 audioTools = AudioTools()