aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsmaël Bouya <ismael.bouya@normalesup.org>2016-08-12 18:21:22 +0200
committerIsmaël Bouya <ismael.bouya@normalesup.org>2016-08-12 18:23:02 +0200
commitd4217fda2ff3991eb1ee9a9bec6acff751798507 (patch)
tree5a7606c28aa5845d1ffebb78742e2d2c2fe39c5a
parent51f6ce0fdb32061b681d63e8de4d96eb8b59e1e9 (diff)
downloadMusicSampler-d4217fda2ff3991eb1ee9a9bec6acff751798507.tar.gz
MusicSampler-d4217fda2ff3991eb1ee9a9bec6acff751798507.tar.zst
MusicSampler-d4217fda2ff3991eb1ee9a9bec6acff751798507.zip
wait actions are now pausable and resettable1.2.3
This fixes https://git.immae.eu/mantisbt/view.php?id=6
-rw-r--r--config.yml65
-rw-r--r--documentation_en.md19
-rw-r--r--documentation_fr.md15
-rw-r--r--music_sampler/action.py18
-rw-r--r--music_sampler/actions/__init__.py3
-rw-r--r--music_sampler/actions/pause_wait.py8
-rw-r--r--music_sampler/actions/reset_wait.py8
-rw-r--r--music_sampler/actions/unpause_wait.py8
-rw-r--r--music_sampler/actions/wait.py54
-rw-r--r--music_sampler/locales/fr/LC_MESSAGES/music_sampler.po24
-rw-r--r--music_sampler/mapping.py33
11 files changed, 227 insertions, 28 deletions
diff --git a/config.yml b/config.yml
index 37e085a..36c804b 100644
--- a/config.yml
+++ b/config.yml
@@ -75,6 +75,8 @@ music_properties:
75key_properties: 75key_properties:
76 'common': 76 'common':
77 repeat_delay: 1 77 repeat_delay: 1
78 include: blue
79
78 'a': 80 'a':
79 description: 81 description:
80 - 82 -
@@ -145,6 +147,11 @@ key_properties:
145 - Low vol 147 - Low vol
146 - Up vol 148 - Up vol
147 include: green 149 include: green
150 'ù':
151 description:
152 -
153 - stop
154 - wait
148 155
149 'home': 156 'home':
150 description: 157 description:
@@ -160,18 +167,21 @@ key_properties:
160 - "!" 167 - "!"
161 - STOP! 168 - STOP!
162 include: red 169 include: red
170 repeat_delay: 0
163 171
164 'F5': 172 'F5':
165 description: 173 description:
166 - "||" 174 - "||"
167 - PAUSE 175 - PAUSE
168 include: light_green 176 include: light_green
177 repeat_delay: 0
169 178
170 'F6': 179 'F6':
171 description: 180 description:
172 - ">" 181 - ">"
173 - UNPAUSE 182 - UNPAUSE
174 include: light_green 183 include: light_green
184 repeat_delay: 0
175 185
176 'F1': 186 'F1':
177 description: 187 description:
@@ -179,6 +189,7 @@ key_properties:
179 - Stop 189 - Stop
180 - fade 190 - fade
181 include: orange 191 include: orange
192 repeat_delay: 0
182 193
183 'F2': 194 'F2':
184 description: 195 description:
@@ -186,6 +197,7 @@ key_properties:
186 - Stop 197 - Stop
187 - actions 198 - actions
188 include: orange 199 include: orange
200 repeat_delay: 0
189 201
190 'F4': 202 'F4':
191 description: 203 description:
@@ -193,30 +205,51 @@ key_properties:
193 - Skip 205 - Skip
194 - wait 206 - wait
195 include: pink 207 include: pink
208 repeat_delay: 0
209
210 'F8':
211 description:
212 -
213 - Pause
214 - wait
215 'F9':
216 description:
217 -
218 - Unpause
219 - wait
220 'F10':
221 description:
222 -
223 - Reset
224 - wait
196 225
197 'F12': 226 'F12':
198 description: 227 description:
199 - 228 -
200 - vol+ 229 - vol+
201 include: yellow 230 include: yellow
231 repeat_delay: 0
202 232
203 'F11': 233 'F11':
204 description: 234 description:
205 - 235 -
206 - "vol-" 236 - "vol-"
207 include: yellow 237 include: yellow
238 repeat_delay: 0
208 239
209 'right': 240 'right':
210 description: 241 description:
211 - 242 -
212 - +10s 243 - +10s
213 include: blue 244 include: blue
245 repeat_delay: 0
214 246
215 'left': 247 'left':
216 description: 248 description:
217 - 249 -
218 - -10s 250 - -10s
219 include: blue 251 include: blue
252 repeat_delay: 0
220 253
221################################################################# 254#################################################################
222##### Keys: what do the key actually do when you press them ##### 255##### Keys: what do the key actually do when you press them #####
@@ -246,10 +279,8 @@ keys:
246 - stop: 279 - stop:
247 fade_out: 3 280 fade_out: 3
248 wait: true 281 wait: true
249 set_wait_id: y1
250 - wait: 282 - wait:
251 duration: 3 283 duration: 3
252 set_wait_id: y2
253 - play: 284 - play:
254 include: music2 285 include: music2
255 286
@@ -263,7 +294,6 @@ keys:
263 include: music1 294 include: music1
264 - wait: 295 - wait:
265 duration: 3 296 duration: 3
266 set_wait_id: u
267 - play: 297 - play:
268 include: music2 298 include: music2
269 299
@@ -274,7 +304,6 @@ keys:
274 start_at: 30 304 start_at: 30
275 - wait: 305 - wait:
276 duration: 5 306 duration: 5
277 set_wait_id: g
278 - seek: 307 - seek:
279 include: music1 308 include: music1
280 delta: false 309 delta: false
@@ -293,6 +322,11 @@ keys:
293 - play: 322 - play:
294 include: music2 323 include: music2
295 324
325# skip waiting for the end of music1
326 'ù':
327 - interrupt_wait:
328 wait_id: m
329
296# Lowers the volume of music 1 and 2 (if playing), during the duration of noise + 1 second 330# Lowers the volume of music 1 and 2 (if playing), during the duration of noise + 1 second
297 'i': 331 'i':
298 - volume: 332 - volume:
@@ -306,7 +340,6 @@ keys:
306 - wait: 340 - wait:
307 include: noise 341 include: noise
308 duration: 1 342 duration: 1
309 set_wait_id: i
310 - volume: 343 - volume:
311 include: music1 344 include: music1
312 value: 100 345 value: 100
@@ -328,7 +361,6 @@ keys:
328 fade: 5 361 fade: 5
329 - wait: 362 - wait:
330 duration: 5 363 duration: 5
331 set_wait_id: n
332 - volume: 364 - volume:
333 include: music1 365 include: music1
334 value: 100 366 value: 100
@@ -381,20 +413,15 @@ keys:
381# Skip wait 413# Skip wait
382 'F4': 414 'F4':
383 - interrupt_wait: 415 - interrupt_wait:
384 wait_id: n
385 - interrupt_wait:
386 wait_id: m
387 - interrupt_wait:
388 wait_id: i
389 - interrupt_wait:
390 wait_id: y1
391 - interrupt_wait:
392 wait_id: y2
393 - interrupt_wait:
394 wait_id: u
395 - interrupt_wait:
396 wait_id: g
397 416
417 'F8':
418 - pause_wait:
419
420 'F9':
421 - unpause_wait:
422
423 'F10':
424 - reset_wait:
398 425
399# Changing volume 426# Changing volume
400 'F12': 427 'F12':
diff --git a/documentation_en.md b/documentation_en.md
index 899ef1a..e92b85c 100644
--- a/documentation_en.md
+++ b/documentation_en.md
@@ -386,9 +386,22 @@ actions.
386 action. When false, it is thus useless to add actions after that one. 386 action. When false, it is thus useless to add actions after that one.
387- `interrupt_wait`: stop a wait event (normal `wait` or fade out wait). The keys 387- `interrupt_wait`: stop a wait event (normal `wait` or fade out wait). The keys
388 that were waiting will move to the next actions. Parameters: 388 that were waiting will move to the next actions. Parameters:
389 * `wait_id: name` (optional) gives the id of the `wait` to interrupt (defined with 389 * `wait_id: name` (optional) gives the id of the `wait` to interrupt
390 `set_wait_id`, see actions `wait` and `stop`). If not given, interrupts 390 (defined with `set_wait_id`, see actions `wait` and `stop`). If not given,
391 all wait events. 391 interrupts all wait events.
392- `pause_wait`: pauses a wait event (only for a wait with duration). The key
393 that were waiting will keep waiting until the `wait` is unpaused. Parameters:
394 * `wait_id: name` (optional) gives the id of the `wait` to pause. If not
395 given, pauses all compatible wait events.
396- `unpause_wait`: unpauses a paused wait event (only a wait with duration). The
397 countdown will resume for the corresponding keys. Parameters:
398 * `wait_id: name` (optional) gives the id of the `wait` to unpause. If not
399 given, unpauses all compatible wait events.
400- `reset_wait`: resets a wait counter (only a wait with duration). If the wait
401 was paused, it will stay paused and start at the beginning once it is
402 unpaused. Parameters:
403 * `wait_id: name` (optional) gives the id of the `wait` to reset. If not
404 given, resets all compatible wait events.
392- `run_command` : Run a command. Parameters: 405- `run_command` : Run a command. Parameters:
393 * `command: my_command` : Gives the command to run. 406 * `command: my_command` : Gives the command to run.
394 * `wait: true/false` (optional, default false) if true, waits for the 407 * `wait: true/false` (optional, default false) if true, waits for the
diff --git a/documentation_fr.md b/documentation_fr.md
index ff3cfe8..cc2bf8f 100644
--- a/documentation_fr.md
+++ b/documentation_fr.md
@@ -435,6 +435,21 @@ successivement mais sans attendre (donc presque simultanément) : ne pas hésite
435 * `wait_id: name` (facultatif) précise l'identifiant du `wait` à stopper 435 * `wait_id: name` (facultatif) précise l'identifiant du `wait` à stopper
436 (défini par `set_wait_id`, voir les actions `wait` et `stop`). Si absent, 436 (défini par `set_wait_id`, voir les actions `wait` et `stop`). Si absent,
437 interrompt toutes les attentes. 437 interrompt toutes les attentes.
438- `pause_wait`: met une attente en pause (uniquement pour une attente ayant une
439 durée définie). La touche qui attend cet événement ne continuera pas tant que
440 l'attente n'est pas reprise. Paramètres :
441 * `wait_id: name` (facultatif) précise l'identifiant du `wait` à mettre en
442 pause. Si absent, met en pause toutes les attentes compatibles.
443- `unpause_wait`: reprend une attente en pause (uniquement pour une attente
444 ayant une durée définie). Le compte à rebours reprendra pour la touche
445 correspondante en train d'attendre. Paramètres:
446 * `wait_id: name` (facultatif) précise l'identifiant du `wait` à reprendre.
447 Si absent, reprend toutes les attentes compatibles.
448- `reset_wait`: réinitialise une attente (uniquement pour une attente ayant une
449 durée définie). Si l'attente est en pause, le compte à rebours ne recommencera
450 au début que lorsque l'attente sera reprise. Paramètres:
451 * `wait_id: name` (facultatif) précise l'identifiant du `wait` à
452 réinitialiser. Si absent, réinitialise toutes les attentes compatibles.
438- `run_command` : lance une commande. Paramètres : 453- `run_command` : lance une commande. Paramètres :
439 * `command: my_command` : précise la commande à lancer. 454 * `command: my_command` : précise la commande à lancer.
440 * `wait: true/false` (facultatif, défaut : false) : si `wait` est true, 455 * `wait: true/false` (facultatif, défaut : false) : si `wait` est true,
diff --git a/music_sampler/action.py b/music_sampler/action.py
index d269d0e..22a2bdc 100644
--- a/music_sampler/action.py
+++ b/music_sampler/action.py
@@ -98,6 +98,24 @@ class Action:
98 return getattr(getattr(actions, self.action), 'interrupt')( 98 return getattr(getattr(actions, self.action), 'interrupt')(
99 self, **self.arguments) 99 self, **self.arguments)
100 100
101 def pause(self):
102 if getattr(actions, self.action, None) and\
103 hasattr(getattr(actions, self.action), 'pause'):
104 return getattr(getattr(actions, self.action), 'pause')(
105 self, **self.arguments)
106
107 def unpause(self):
108 if getattr(actions, self.action, None) and\
109 hasattr(getattr(actions, self.action), 'unpause'):
110 return getattr(getattr(actions, self.action), 'unpause')(
111 self, **self.arguments)
112
113 def reset(self):
114 if getattr(actions, self.action, None) and\
115 hasattr(getattr(actions, self.action), 'reset'):
116 return getattr(getattr(actions, self.action), 'reset')(
117 self, **self.arguments)
118
101 # Helpers 119 # Helpers
102 def music_list(self, music): 120 def music_list(self, music):
103 if music is not None: 121 if music is not None:
diff --git a/music_sampler/actions/__init__.py b/music_sampler/actions/__init__.py
index 658cef0..7c812cb 100644
--- a/music_sampler/actions/__init__.py
+++ b/music_sampler/actions/__init__.py
@@ -1,10 +1,13 @@
1from . import interrupt_wait 1from . import interrupt_wait
2from . import pause 2from . import pause
3from . import pause_wait
3from . import play 4from . import play
5from . import reset_wait
4from . import run_command 6from . import run_command
5from . import seek 7from . import seek
6from . import stop 8from . import stop
7from . import stop_all_actions 9from . import stop_all_actions
8from . import unpause 10from . import unpause
11from . import unpause_wait
9from . import volume 12from . import volume
10from . import wait 13from . import wait
diff --git a/music_sampler/actions/pause_wait.py b/music_sampler/actions/pause_wait.py
new file mode 100644
index 0000000..e4ab6ea
--- /dev/null
+++ b/music_sampler/actions/pause_wait.py
@@ -0,0 +1,8 @@
1def run(action, wait_id=None, **kwargs):
2 action.mapping.pause_wait(wait_id)
3
4def description(action, wait_id=None, **kwargs):
5 if wait_id is None:
6 return _("pause all waits")
7 else:
8 return _("pause wait with id {}").format(wait_id)
diff --git a/music_sampler/actions/reset_wait.py b/music_sampler/actions/reset_wait.py
new file mode 100644
index 0000000..500bcca
--- /dev/null
+++ b/music_sampler/actions/reset_wait.py
@@ -0,0 +1,8 @@
1def run(action, wait_id=None, **kwargs):
2 action.mapping.reset_wait(wait_id)
3
4def description(action, wait_id=None, **kwargs):
5 if wait_id is None:
6 return _("reset all waits")
7 else:
8 return _("reset wait with id {}").format(wait_id)
diff --git a/music_sampler/actions/unpause_wait.py b/music_sampler/actions/unpause_wait.py
new file mode 100644
index 0000000..25e9a11
--- /dev/null
+++ b/music_sampler/actions/unpause_wait.py
@@ -0,0 +1,8 @@
1def run(action, wait_id=None, **kwargs):
2 action.mapping.unpause_wait(wait_id)
3
4def description(action, wait_id=None, **kwargs):
5 if wait_id is None:
6 return _("unpause all waits")
7 else:
8 return _("unpause wait with id {}").format(wait_id)
diff --git a/music_sampler/actions/wait.py b/music_sampler/actions/wait.py
index bcee649..31439b8 100644
--- a/music_sampler/actions/wait.py
+++ b/music_sampler/actions/wait.py
@@ -1,4 +1,5 @@
1import threading 1import threading
2import time
2 3
3def run(action, duration=0, music=None, set_wait_id=None, **kwargs): 4def run(action, duration=0, music=None, set_wait_id=None, **kwargs):
4 action.mapping.add_wait(action, wait_id=set_wait_id) 5 action.mapping.add_wait(action, wait_id=set_wait_id)
@@ -8,10 +9,17 @@ def run(action, duration=0, music=None, set_wait_id=None, **kwargs):
8 duration, 9 duration,
9 action.sleep_event.set) 10 action.sleep_event.set)
10 11
12 action.sleep_event_initial_duration = duration
13 action.sleep_event_paused = False
14 action.sleep_event_left_time = duration
15
11 if music is not None: 16 if music is not None:
12 music.wait_end() 17 music.wait_end()
13 18
14 action.sleep_event_timer.start() 19 if duration <= 0 or not action.sleep_event_paused:
20 action.sleep_event_timer.start()
21 action.sleep_event_started_time = time.time()
22
15 action.sleep_event.wait() 23 action.sleep_event.wait()
16 24
17def description(action, duration=0, music=None, set_wait_id=None, **kwargs): 25def description(action, duration=0, music=None, set_wait_id=None, **kwargs):
@@ -34,6 +42,50 @@ def description(action, duration=0, music=None, set_wait_id=None, **kwargs):
34 42
35 return _(message).format(*formats) 43 return _(message).format(*formats)
36 44
45def pause(action, **kwargs):
46 if action.sleep_event_paused:
47 return
48
49 action.sleep_event_paused = True
50
51 if not action.sleep_event_timer.is_alive():
52 return
53
54 action.sleep_event_timer.cancel()
55
56 action.sleep_event_left_time = action.sleep_event_left_time\
57 - (time.time() - action.sleep_event_started_time)
58 if action.sleep_event_left_time < 0:
59 action.sleep_event.set()
60
61def unpause(action, **kwargs):
62 if not action.sleep_event_paused:
63 return
64
65 action.sleep_event_paused = False
66
67 action.sleep_event_timer = threading.Timer(
68 action.sleep_event_left_time,
69 action.sleep_event.set)
70
71 action.sleep_event_timer.start()
72 action.sleep_event_started_time = time.time()
73
74def reset(action, **kwargs):
75 action.sleep_event_timer.cancel()
76
77 action.sleep_event_left_time = action.sleep_event_initial_duration
78
79 if action.sleep_event_paused:
80 return
81
82 action.sleep_event_timer = threading.Timer(
83 action.sleep_event_left_time,
84 action.sleep_event.set)
85
86 action.sleep_event_timer.start()
87 action.sleep_event_started_time = time.time()
88
37def interrupt(action, duration=0, music=None, **kwargs): 89def interrupt(action, duration=0, music=None, **kwargs):
38 if action.sleep_event is not None: 90 if action.sleep_event is not None:
39 action.sleep_event.set() 91 action.sleep_event.set()
diff --git a/music_sampler/locales/fr/LC_MESSAGES/music_sampler.po b/music_sampler/locales/fr/LC_MESSAGES/music_sampler.po
index 888d7a5..af27ca9 100644
--- a/music_sampler/locales/fr/LC_MESSAGES/music_sampler.po
+++ b/music_sampler/locales/fr/LC_MESSAGES/music_sampler.po
@@ -103,6 +103,14 @@ msgstr "mise en pause de « {} »"
103msgid "pausing all musics" 103msgid "pausing all musics"
104msgstr "mise en pause des musiques" 104msgstr "mise en pause des musiques"
105 105
106#: music_sampler/actions/pause_wait.py:5
107msgid "pause wait with id {}"
108msgstr "Mettre en pause l'attente d'identifiant {}"
109
110#: music_sampler/actions/pause_wait.py:5
111msgid "pause all waits"
112msgstr "Mettre en pause toutes les attentes"
113
106#: music_sampler/actions/play.py:50 114#: music_sampler/actions/play.py:50
107msgid "starting « {} » at volume {}%" 115msgid "starting « {} » at volume {}%"
108msgstr "lance « {} » au volume {}%" 116msgstr "lance « {} » au volume {}%"
@@ -295,6 +303,14 @@ msgstr "lance « {} » à {}s avec un fondu de {}s au volume {}% en boucle (re
295msgid "starting all musics at {}s with {}s fade_in at volume {}% in loop (restarting if already running)" 303msgid "starting all musics at {}s with {}s fade_in at volume {}% in loop (restarting if already running)"
296msgstr "lance toutes les musiques à {}s avec un fondu de {}s au volume {}% en boucle (redémarre si déjà lancée)" 304msgstr "lance toutes les musiques à {}s avec un fondu de {}s au volume {}% en boucle (redémarre si déjà lancée)"
297 305
306#: music_sampler/actions/reset_wait.py:5
307msgid "reset wait with id {}"
308msgstr "Réinitialise l'attente d'identifiant {}"
309
310#: music_sampler/actions/reset_wait.py:5
311msgid "reset all waits"
312msgstr "Réinitialise toutes les attentes"
313
298#: music_sampler/actions/run_command.py:15 314#: music_sampler/actions/run_command.py:15
299msgid "running command {}" 315msgid "running command {}"
300msgstr "lance la commande {}" 316msgstr "lance la commande {}"
@@ -367,6 +383,14 @@ msgstr "reprend « {} »"
367msgid "unpausing all musics" 383msgid "unpausing all musics"
368msgstr "reprend toutes les musiques" 384msgstr "reprend toutes les musiques"
369 385
386#: music_sampler/actions/unpause_wait.py:5
387msgid "unpause wait with id {}"
388msgstr "Reprendre l'attente d'identifiant {}"
389
390#: music_sampler/actions/unpause_wait.py:5
391msgid "unpause all waits"
392msgstr "Reprendre toutes les attentes"
393
370#: music_sampler/actions/volume.py:32 394#: music_sampler/actions/volume.py:32
371msgid "{:+d}% to volume of « {} »" 395msgid "{:+d}% to volume of « {} »"
372msgstr "{:+d}% sur le volume de « {} »" 396msgstr "{:+d}% sur le volume de « {} »"
diff --git a/music_sampler/mapping.py b/music_sampler/mapping.py
index 99c9977..9e40d40 100644
--- a/music_sampler/mapping.py
+++ b/music_sampler/mapping.py
@@ -206,15 +206,17 @@ class Mapping(RelativeLayout):
206 self.wait_ids[None] = [] 206 self.wait_ids[None] = []
207 self.wait_ids[None].append(action_or_wait) 207 self.wait_ids[None].append(action_or_wait)
208 208
209 def interrupt_wait(self, wait_id=None): 209 def matching_wait_ids(self, wait_id=None):
210 if wait_id is None: 210 if wait_id is None:
211 ids_to_interrupt = list(self.wait_ids.keys()) 211 matching_ids = list(self.wait_ids.keys())
212 elif wait_id in self.wait_ids: 212 elif wait_id in self.wait_ids:
213 ids_to_interrupt = [wait_id] 213 matching_ids = [wait_id]
214 else: 214 else:
215 ids_to_interrupt = [] 215 matching_ids = []
216 return matching_ids
216 217
217 for _wait_id in ids_to_interrupt: 218 def interrupt_wait(self, wait_id=None):
219 for _wait_id in self.matching_wait_ids(wait_id=wait_id):
218 action_or_waits = self.wait_ids[_wait_id] 220 action_or_waits = self.wait_ids[_wait_id]
219 del(self.wait_ids[_wait_id]) 221 del(self.wait_ids[_wait_id])
220 for action_or_wait in action_or_waits: 222 for action_or_wait in action_or_waits:
@@ -223,6 +225,27 @@ class Mapping(RelativeLayout):
223 else: 225 else:
224 action_or_wait.set() 226 action_or_wait.set()
225 227
228 def pause_wait(self, wait_id=None):
229 for _wait_id in self.matching_wait_ids(wait_id=wait_id):
230 action_or_waits = self.wait_ids[_wait_id]
231 for action_or_wait in action_or_waits:
232 if isinstance(action_or_wait, Action):
233 action_or_wait.pause()
234
235 def unpause_wait(self, wait_id=None):
236 for _wait_id in self.matching_wait_ids(wait_id=wait_id):
237 action_or_waits = self.wait_ids[_wait_id]
238 for action_or_wait in action_or_waits:
239 if isinstance(action_or_wait, Action):
240 action_or_wait.unpause()
241
242 def reset_wait(self, wait_id=None):
243 for _wait_id in self.matching_wait_ids(wait_id=wait_id):
244 action_or_waits = self.wait_ids[_wait_id]
245 for action_or_wait in action_or_waits:
246 if isinstance(action_or_wait, Action):
247 action_or_wait.reset()
248
226 # Methods to control running keys 249 # Methods to control running keys
227 def start_running(self, key, start_time): 250 def start_running(self, key, start_time):
228 self.running.append((key, start_time)) 251 self.running.append((key, start_time))