aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--helpers/action.py2
-rw-r--r--helpers/music_file.py53
2 files changed, 40 insertions, 15 deletions
diff --git a/helpers/action.py b/helpers/action.py
index 327d42f..b921fbf 100644
--- a/helpers/action.py
+++ b/helpers/action.py
@@ -24,7 +24,7 @@ class Action:
24 24
25 def ready(self): 25 def ready(self):
26 if 'music' in self.arguments: 26 if 'music' in self.arguments:
27 return self.arguments['music'].loaded 27 return self.arguments['music'].check_is_loaded()
28 else: 28 else:
29 return True 29 return True
30 30
diff --git a/helpers/music_file.py b/helpers/music_file.py
index 9acdedf..f9c5816 100644
--- a/helpers/music_file.py
+++ b/helpers/music_file.py
@@ -3,29 +3,56 @@ import pydub
3import pygame 3import pygame
4import math 4import math
5import time 5import time
6from transitions.extensions import HierarchicalMachine as Machine
6 7
7class MusicFile: 8class MusicFile(Machine):
8 def __init__(self, filename, lock, channel_id, name = None, gain = 1): 9 def __init__(self, filename, lock, channel_id, name = None, gain = 1):
10 states = [
11 'initial',
12 'loading',
13 'failed',
14 { 'name': 'loaded', 'children': ['stopped', 'playing', 'paused'] }
15 ]
16 transitions = [
17 { 'trigger': 'load', 'source': 'initial', 'dest': 'loading'},
18 { 'trigger': 'fail', 'source': 'loading', 'dest': 'failed'},
19 { 'trigger': 'success', 'source': 'loading', 'dest': 'loaded_stopped'},
20 #{ 'trigger': 'play', 'source': 'loaded_stopped', 'dest': 'loaded_playing'},
21 #{ 'trigger': 'pause', 'source': 'loaded_playing', 'dest': 'loaded_paused'},
22 #{ 'trigger': 'stop', 'source': ['loaded_playing','loaded_paused'], 'dest': 'loaded_stopped'}
23 ]
24
25 Machine.__init__(self, states=states, transitions=transitions, initial='initial')
26
9 self.filename = filename 27 self.filename = filename
10 self.channel_id = channel_id 28 self.channel_id = channel_id
11 self.name = name or filename 29 self.name = name or filename
12 self.raw_data = None 30 self.raw_data = None
13 self.gain = gain 31 self.gain = gain
14 32
15 self.loaded = False
16 self.flag_paused = False 33 self.flag_paused = False
17 threading.Thread(name = "MSMusicLoad", target = self.load_sound, args = [lock]).start() 34 threading.Thread(name = "MSMusicLoad", target = self.load, kwargs = {'lock': lock}).start()
18 35
19 def load_sound(self, lock): 36 def on_enter_loading(self, lock=None):
20 lock.acquire() 37 lock.acquire()
21 print("Loading « {} »".format(self.name)) 38 try:
22 volume_factor = 20 * math.log10(self.gain) 39 print("Loading « {} »".format(self.name))
23 audio_segment = pydub.AudioSegment.from_file(self.filename).set_frame_rate(44100).apply_gain(volume_factor) 40 volume_factor = 20 * math.log10(self.gain)
24 self.sound_duration = audio_segment.duration_seconds 41 audio_segment = pydub.AudioSegment.from_file(self.filename).set_frame_rate(44100).apply_gain(volume_factor)
25 self.raw_data = audio_segment.raw_data 42 self.sound_duration = audio_segment.duration_seconds
26 print("Loaded « {} »".format(self.name)) 43 self.raw_data = audio_segment.raw_data
27 self.loaded = True 44 except Exception as e:
28 lock.release() 45 print("failed to load « {} »: {}".format(self.name, e))
46 self.loading_error = e
47 self.fail()
48 else:
49 self.success()
50 print("Loaded « {} »".format(self.name))
51 finally:
52 lock.release()
53
54 def check_is_loaded(self):
55 return self.state.startswith('loaded_')
29 56
30 def is_playing(self): 57 def is_playing(self):
31 return self.channel().get_busy() 58 return self.channel().get_busy()
@@ -43,8 +70,6 @@ class MusicFile:
43 return 0 70 return 0
44 71
45 def play(self, fade_in = 0, volume = 100, start_at = 0): 72 def play(self, fade_in = 0, volume = 100, start_at = 0):
46 self.channel().set_endevent()
47 self.channel().set_endevent(pygame.USEREVENT)
48 self.set_volume(volume) 73 self.set_volume(volume)
49 74
50 if start_at > 0: 75 if start_at > 0: