From 6f4944c18398a7482297bd1d80fcd4ee926270ae Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Isma=C3=ABl=20Bouya?= <ismael.bouya@normalesup.org>
Date: Thu, 14 Jul 2016 23:44:25 +0200
Subject: Add loop option for play

---
 helpers/action.py     | 15 +++++++++++----
 helpers/music_file.py | 16 +++++++++++-----
 2 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/helpers/action.py b/helpers/action.py
index 3dc1b8d..792b123 100644
--- a/helpers/action.py
+++ b/helpers/action.py
@@ -64,15 +64,17 @@ class Action:
                 music.unpause()
 
     def play(self, music = None, fade_in = 0, start_at = 0,
-            restart_if_running = False, volume = 100, **kwargs):
+            restart_if_running = False, volume = 100,
+            loop = 0,
+            **kwargs):
         if music is not None:
             if restart_if_running:
                 if music.is_not_stopped():
                     music.stop()
-                music.play(volume = volume, fade_in = fade_in, start_at = start_at)
+                music.play(volume = volume, fade_in = fade_in, start_at = start_at, loop = loop)
             else:
                 if not music.is_not_stopped():
-                    music.play(volume = volume, fade_in = fade_in, start_at = start_at)
+                    music.play(volume = volume, fade_in = fade_in, start_at = start_at, loop = loop)
 
     def seek(self, music = None, value = 0, delta = False, **kwargs):
         for music in self.music_list(music):
@@ -124,7 +126,7 @@ class Action:
             return "unpausing all musics"
 
     def play_print(self, music = None, fade_in = 0, start_at = 0,
-            restart_if_running = False, volume = 100, **kwargs):
+            restart_if_running = False, volume = 100, loop = 0, **kwargs):
         message = "starting "
         if music is not None:
             message += "« {} »".format(music.name)
@@ -139,6 +141,11 @@ class Action:
 
         message += " at volume {}%".format(volume)
 
+        if loop > 0:
+            message += " {} times".format(loop + 1)
+        elif loop < 0:
+            message += " in loop"
+
         if restart_if_running:
             message += " (restarting if already running)"
 
diff --git a/helpers/music_file.py b/helpers/music_file.py
index 32869b6..0bfb1ec 100644
--- a/helpers/music_file.py
+++ b/helpers/music_file.py
@@ -78,19 +78,21 @@ class MusicFile(Machine):
         else:
             return 0
 
-    def play(self, fade_in = 0, volume = 100, start_at = 0):
+    def play(self, fade_in = 0, volume = 100, loop = 0, start_at = 0):
         db_gain = gain(volume) + self.mapping.master_gain
         self.volume = volume
+        self.loop = loop
 
         ms = int(start_at * 1000)
         ms_fi = max(1, int(fade_in * 1000))
         with self.music_lock:
             self.current_audio_segment = (self.audio_segment + db_gain).fade(from_gain=-120, duration=ms_fi, start=ms)
-        self.before_loaded_playing(initial_frame = int(start_at * self.audio_segment.frame_rate))
+        self.initial_frame = int(start_at * self.audio_segment.frame_rate)
+        self.before_loaded_playing()
         self.start_playing()
 
-    def before_loaded_playing(self, initial_frame = 0):
-        self.current_frame = initial_frame
+    def before_loaded_playing(self):
+        self.current_frame = self.initial_frame
         with self.music_lock:
             segment = self.current_audio_segment
 
@@ -125,7 +127,11 @@ class MusicFile(Machine):
                                 )
             self.current_frame += frame_count
             if len(audio_segment) == 0:
-                raise sd.CallbackStop
+                if self.is_loaded_playing() and self.loop != 0:
+                    self.loop -= 1
+                    self.current_frame = self.initial_frame
+                else:
+                    raise sd.CallbackStop
 
             out_data[:] = audio_segment.ljust(len(out_data), b'\0')
 
-- 
cgit v1.2.3