diff options
Diffstat (limited to 'helpers/music_file.py')
-rw-r--r-- | helpers/music_file.py | 41 |
1 files changed, 14 insertions, 27 deletions
diff --git a/helpers/music_file.py b/helpers/music_file.py index ebe458b..6da547b 100644 --- a/helpers/music_file.py +++ b/helpers/music_file.py | |||
@@ -3,7 +3,6 @@ import pydub | |||
3 | import time | 3 | import time |
4 | from transitions.extensions import HierarchicalMachine as Machine | 4 | from transitions.extensions import HierarchicalMachine as Machine |
5 | 5 | ||
6 | import sounddevice as sd | ||
7 | import os.path | 6 | import os.path |
8 | 7 | ||
9 | from .lock import Lock | 8 | from .lock import Lock |
@@ -27,7 +26,7 @@ class MusicFile(Machine): | |||
27 | { 'trigger': 'pause', 'source': 'loaded_playing', 'dest': 'loaded_paused'}, | 26 | { 'trigger': 'pause', 'source': 'loaded_playing', 'dest': 'loaded_paused'}, |
28 | { 'trigger': 'unpause', 'source': 'loaded_paused', 'dest': 'loaded_playing'}, | 27 | { 'trigger': 'unpause', 'source': 'loaded_paused', 'dest': 'loaded_playing'}, |
29 | { 'trigger': 'stop_playing', 'source': ['loaded_playing','loaded_paused'], 'dest': 'loaded_stopping'}, | 28 | { 'trigger': 'stop_playing', 'source': ['loaded_playing','loaded_paused'], 'dest': 'loaded_stopping'}, |
30 | { 'trigger': 'stopped', 'source': 'loaded_stopping', 'dest': 'loaded_stopped'} | 29 | { 'trigger': 'stopped', 'source': 'loaded_stopping', 'dest': 'loaded_stopped', 'after': 'trigger_stopped_events'} |
31 | ] | 30 | ] |
32 | 31 | ||
33 | Machine.__init__(self, states=states, transitions=transitions, initial='initial') | 32 | Machine.__init__(self, states=states, transitions=transitions, initial='initial') |
@@ -35,7 +34,6 @@ class MusicFile(Machine): | |||
35 | self.volume = 100 | 34 | self.volume = 100 |
36 | self.mapping = mapping | 35 | self.mapping = mapping |
37 | self.filename = filename | 36 | self.filename = filename |
38 | self.stream = None | ||
39 | self.name = name or filename | 37 | self.name = name or filename |
40 | self.audio_segment = None | 38 | self.audio_segment = None |
41 | self.audio_segment_frame_width = 0 | 39 | self.audio_segment_frame_width = 0 |
@@ -50,7 +48,7 @@ class MusicFile(Machine): | |||
50 | try: | 48 | try: |
51 | print("Loading « {} »".format(self.name)) | 49 | print("Loading « {} »".format(self.name)) |
52 | db_gain = gain(self.volume_factor * 100) | 50 | db_gain = gain(self.volume_factor * 100) |
53 | self.audio_segment = pydub.AudioSegment.from_file(self.filename).set_frame_rate(44100).apply_gain(db_gain) | 51 | self.audio_segment = pydub.AudioSegment.from_file(self.filename).set_frame_rate(44100).set_channels(2).set_sample_width(2).apply_gain(db_gain) |
54 | self.audio_segment_frame_width = self.audio_segment.frame_width | 52 | self.audio_segment_frame_width = self.audio_segment.frame_width |
55 | self.sound_duration = self.audio_segment.duration_seconds | 53 | self.sound_duration = self.audio_segment.duration_seconds |
56 | except Exception as e: | 54 | except Exception as e: |
@@ -94,26 +92,10 @@ class MusicFile(Machine): | |||
94 | else: | 92 | else: |
95 | self.a_s_with_effect = None | 93 | self.a_s_with_effect = None |
96 | 94 | ||
97 | self.before_loaded_playing() | ||
98 | self.start_playing() | 95 | self.start_playing() |
99 | 96 | ||
100 | def before_loaded_playing(self): | ||
101 | with self.music_lock: | ||
102 | segment = self.current_audio_segment | ||
103 | |||
104 | self.stream = sd.RawOutputStream(samplerate=segment.frame_rate, | ||
105 | channels=segment.channels, | ||
106 | dtype='int' + str(8*segment.sample_width), # FIXME: ? | ||
107 | latency=1., | ||
108 | callback=self.play_callback, | ||
109 | finished_callback=self.finished_callback | ||
110 | ) | ||
111 | |||
112 | def on_enter_loaded_playing(self): | 97 | def on_enter_loaded_playing(self): |
113 | self.stream.start() | 98 | self.mapping.mixer.add_file(self) |
114 | |||
115 | def on_enter_loaded_paused(self): | ||
116 | self.stream.stop() | ||
117 | 99 | ||
118 | def finished_callback(self): | 100 | def finished_callback(self): |
119 | if self.is_loaded_playing(): | 101 | if self.is_loaded_playing(): |
@@ -121,10 +103,14 @@ class MusicFile(Machine): | |||
121 | if self.is_loaded_stopping(): | 103 | if self.is_loaded_stopping(): |
122 | self.stopped() | 104 | self.stopped() |
123 | 105 | ||
124 | def on_enter_loaded_stopped(self): | 106 | def trigger_stopped_events(self): |
107 | self.mapping.mixer.remove_file(self) | ||
125 | self.wait_event.set() | 108 | self.wait_event.set() |
126 | 109 | ||
127 | def play_callback(self, out_data, frame_count, time_info, status_flags): | 110 | def play_callback(self, out_data_length, frame_count): |
111 | if self.is_loaded_paused(): | ||
112 | return b'\0' * out_data_length | ||
113 | |||
128 | with self.music_lock: | 114 | with self.music_lock: |
129 | [data, nb_frames] = self.get_next_sample(frame_count) | 115 | [data, nb_frames] = self.get_next_sample(frame_count) |
130 | if nb_frames < frame_count: | 116 | if nb_frames < frame_count: |
@@ -135,9 +121,9 @@ class MusicFile(Machine): | |||
135 | data += new_data | 121 | data += new_data |
136 | nb_frames += new_nb_frames | 122 | nb_frames += new_nb_frames |
137 | elif nb_frames == 0: | 123 | elif nb_frames == 0: |
138 | raise sd.CallbackStop | 124 | threading.Thread(name = "MSFinishedCallback", target=self.finished_callback).start() |
139 | 125 | ||
140 | out_data[:] = data.ljust(len(out_data), b'\0') | 126 | return data.ljust(out_data_length, b'\0') |
141 | 127 | ||
142 | def get_next_sample(self, frame_count): | 128 | def get_next_sample(self, frame_count): |
143 | fw = self.audio_segment_frame_width | 129 | fw = self.audio_segment_frame_width |
@@ -189,9 +175,10 @@ class MusicFile(Machine): | |||
189 | 175 | ||
190 | # FIXME: stop fade_out puis seek -5 -> on abandonne le fade ? (cf | 176 | # FIXME: stop fade_out puis seek -5 -> on abandonne le fade ? (cf |
191 | # commentaire dans fonction seek | 177 | # commentaire dans fonction seek |
178 | new_audio_segment = self.current_audio_segment[:ms + ms_fo].fade_out(ms_fo) | ||
192 | with self.music_lock: | 179 | with self.music_lock: |
193 | self.current_audio_segment = self.current_audio_segment[:ms + ms_fo].fade_out(ms_fo) | 180 | self.current_audio_segment = new_audio_segment |
194 | self.stop_playing() | 181 | self.stop_playing() |
195 | if wait: | 182 | if wait: |
196 | self.wait_end() | 183 | self.wait_end() |
197 | else: | 184 | else: |