aboutsummaryrefslogtreecommitdiff
path: root/helpers/music_file.py
diff options
context:
space:
mode:
authorIsmaël Bouya <ismael.bouya@normalesup.org>2016-07-18 00:15:15 +0200
committerIsmaël Bouya <ismael.bouya@normalesup.org>2016-07-18 19:50:48 +0200
commit2e4049036ec4d90a9daeff606d821d2ac2d023ce (patch)
tree214eb998546a0a7af02c6efbe3bd64c2f297cbd3 /helpers/music_file.py
parentccda4cb91686d4c2b70f0c26d21c26ac3d03c3b9 (diff)
downloadMusicSampler-2e4049036ec4d90a9daeff606d821d2ac2d023ce.tar.gz
MusicSampler-2e4049036ec4d90a9daeff606d821d2ac2d023ce.tar.zst
MusicSampler-2e4049036ec4d90a9daeff606d821d2ac2d023ce.zip
Coding styles
Diffstat (limited to 'helpers/music_file.py')
-rw-r--r--helpers/music_file.py109
1 files changed, 82 insertions, 27 deletions
diff --git a/helpers/music_file.py b/helpers/music_file.py
index 56060bd..54a3fdc 100644
--- a/helpers/music_file.py
+++ b/helpers/music_file.py
@@ -14,25 +14,62 @@ from .mixer import Mixer
14file_lock = Lock("file") 14file_lock = Lock("file")
15 15
16class MusicFile(Machine): 16class MusicFile(Machine):
17 def __init__(self, filename, mapping, name = None, gain = 1): 17 def __init__(self, filename, mapping, name=None, gain=1):
18 states = [ 18 states = [
19 'initial', 19 'initial',
20 'loading', 20 'loading',
21 'failed', 21 'failed',
22 { 'name': 'loaded', 'children': ['stopped', 'playing', 'paused', 'stopping'] } 22 {
23 'name': 'loaded',
24 'children': ['stopped', 'playing', 'paused', 'stopping']
25 }
23 ] 26 ]
24 transitions = [ 27 transitions = [
25 { 'trigger': 'load', 'source': 'initial', 'dest': 'loading'}, 28 {
26 { 'trigger': 'fail', 'source': 'loading', 'dest': 'failed'}, 29 'trigger': 'load',
27 { 'trigger': 'success', 'source': 'loading', 'dest': 'loaded_stopped'}, 30 'source': 'initial',
28 { 'trigger': 'start_playing', 'source': 'loaded_stopped', 'dest': 'loaded_playing'}, 31 'dest': 'loading'
29 { 'trigger': 'pause', 'source': 'loaded_playing', 'dest': 'loaded_paused'}, 32 },
30 { 'trigger': 'unpause', 'source': 'loaded_paused', 'dest': 'loaded_playing'}, 33 {
31 { 'trigger': 'stop_playing', 'source': ['loaded_playing','loaded_paused'], 'dest': 'loaded_stopping'}, 34 'trigger': 'fail',
32 { 'trigger': 'stopped', 'source': 'loaded_stopping', 'dest': 'loaded_stopped', 'after': 'trigger_stopped_events'} 35 'source': 'loading',
36 'dest': 'failed'
37 },
38 {
39 'trigger': 'success',
40 'source': 'loading',
41 'dest': 'loaded_stopped'
42 },
43 {
44 'trigger': 'start_playing',
45 'source': 'loaded_stopped',
46 'dest': 'loaded_playing'
47 },
48 {
49 'trigger': 'pause',
50 'source': 'loaded_playing',
51 'dest': 'loaded_paused'
52 },
53 {
54 'trigger': 'unpause',
55 'source': 'loaded_paused',
56 'dest': 'loaded_playing'
57 },
58 {
59 'trigger': 'stop_playing',
60 'source': ['loaded_playing','loaded_paused'],
61 'dest': 'loaded_stopping'
62 },
63 {
64 'trigger': 'stopped',
65 'source': 'loaded_stopping',
66 'dest': 'loaded_stopped',
67 'after': 'trigger_stopped_events'
68 }
33 ] 69 ]
34 70
35 Machine.__init__(self, states=states, transitions=transitions, initial='initial') 71 Machine.__init__(self, states=states,
72 transitions=transitions, initial='initial')
36 73
37 self.volume = 100 74 self.volume = 100
38 self.mapping = mapping 75 self.mapping = mapping
@@ -45,7 +82,7 @@ class MusicFile(Machine):
45 self.wait_event = threading.Event() 82 self.wait_event = threading.Event()
46 self.db_gain = 0 83 self.db_gain = 0
47 84
48 threading.Thread(name = "MSMusicLoad", target = self.load).start() 85 threading.Thread(name="MSMusicLoad", target=self.load).start()
49 86
50 def on_enter_loading(self): 87 def on_enter_loading(self):
51 with file_lock: 88 with file_lock:
@@ -53,7 +90,12 @@ class MusicFile(Machine):
53 debug_print("Loading « {} »".format(self.name)) 90 debug_print("Loading « {} »".format(self.name))
54 self.mixer = self.mapping.mixer or Mixer() 91 self.mixer = self.mapping.mixer or Mixer()
55 initial_db_gain = gain(self.initial_volume_factor * 100) 92 initial_db_gain = gain(self.initial_volume_factor * 100)
56 self.audio_segment = pydub.AudioSegment.from_file(self.filename).set_frame_rate(Config.frame_rate).set_channels(Config.channels).set_sample_width(Config.sample_width).apply_gain(initial_db_gain) 93 self.audio_segment = pydub.AudioSegment \
94 .from_file(self.filename) \
95 .set_frame_rate(Config.frame_rate) \
96 .set_channels(Config.channels) \
97 .set_sample_width(Config.sample_width) \
98 .apply_gain(initial_db_gain)
57 self.audio_segment_frame_width = self.audio_segment.frame_width 99 self.audio_segment_frame_width = self.audio_segment.frame_width
58 self.sound_duration = self.audio_segment.duration_seconds 100 self.sound_duration = self.audio_segment.duration_seconds
59 except Exception as e: 101 except Exception as e:
@@ -80,7 +122,7 @@ class MusicFile(Machine):
80 else: 122 else:
81 return 0 123 return 0
82 124
83 def play(self, fade_in = 0, volume = 100, loop = 0, start_at = 0): 125 def play(self, fade_in=0, volume=100, loop=0, start_at=0):
84 self.db_gain = gain(volume) + self.mapping.master_gain 126 self.db_gain = gain(volume) + self.mapping.master_gain
85 self.volume = volume 127 self.volume = volume
86 self.loop = loop 128 self.loop = loop
@@ -92,7 +134,9 @@ class MusicFile(Machine):
92 self.current_frame = int(start_at * self.audio_segment.frame_rate) 134 self.current_frame = int(start_at * self.audio_segment.frame_rate)
93 if ms_fi > 0: 135 if ms_fi > 0:
94 # FIXME: apply it to repeated when looping? 136 # FIXME: apply it to repeated when looping?
95 self.a_s_with_effect = self.current_audio_segment[ms:ms+ms_fi].fade_in(ms_fi) 137 self.a_s_with_effect = self \
138 .current_audio_segment[ms : ms+ms_fi] \
139 .fade_in(ms_fi)
96 self.current_frame_with_effect = 0 140 self.current_frame_with_effect = 0
97 else: 141 else:
98 self.a_s_with_effect = None 142 self.a_s_with_effect = None
@@ -122,12 +166,15 @@ class MusicFile(Machine):
122 if self.is_loaded_playing() and self.loop != 0: 166 if self.is_loaded_playing() and self.loop != 0:
123 self.loop -= 1 167 self.loop -= 1
124 self.current_frame = 0 168 self.current_frame = 0
125 [new_data, new_nb_frames] = self.get_next_sample(frame_count - nb_frames) 169 [new_data, new_nb_frames] = self.get_next_sample(
170 frame_count - nb_frames)
126 data += new_data 171 data += new_data
127 nb_frames += new_nb_frames 172 nb_frames += new_nb_frames
128 elif nb_frames == 0: 173 elif nb_frames == 0:
129 # FIXME: too slow 174 # FIXME: too slow
130 threading.Thread(name = "MSFinishedCallback", target=self.finished_callback).start() 175 threading.Thread(
176 name="MSFinishedCallback",
177 target=self.finished_callback).start()
131 178
132 return data.ljust(out_data_length, b'\0') 179 return data.ljust(out_data_length, b'\0')
133 180
@@ -141,11 +188,13 @@ class MusicFile(Machine):
141 max_val = int(segment.frame_count()) 188 max_val = int(segment.frame_count())
142 189
143 start_i = max(self.current_frame_with_effect, 0) 190 start_i = max(self.current_frame_with_effect, 0)
144 end_i = min(self.current_frame_with_effect + frame_count, max_val) 191 end_i = min(self.current_frame_with_effect + frame_count, max_val)
145 192
146 data += segment._data[(start_i * fw):(end_i * fw)] 193 data += segment._data[start_i*fw : end_i*fw]
147 194
148 frame_count = max(0, self.current_frame_with_effect + frame_count - max_val) 195 frame_count = max(
196 0,
197 self.current_frame_with_effect + frame_count - max_val)
149 198
150 self.current_frame_with_effect += end_i - start_i 199 self.current_frame_with_effect += end_i - start_i
151 self.current_frame += end_i - start_i 200 self.current_frame += end_i - start_i
@@ -159,7 +208,7 @@ class MusicFile(Machine):
159 208
160 start_i = max(self.current_frame, 0) 209 start_i = max(self.current_frame, 0)
161 end_i = min(self.current_frame + frame_count, max_val) 210 end_i = min(self.current_frame + frame_count, max_val)
162 data += segment._data[(start_i * fw):(end_i * fw)] 211 data += segment._data[start_i*fw : end_i*fw]
163 nb_frames += end_i - start_i 212 nb_frames += end_i - start_i
164 self.current_frame += end_i - start_i 213 self.current_frame += end_i - start_i
165 214
@@ -167,21 +216,25 @@ class MusicFile(Machine):
167 216
168 return [data, nb_frames] 217 return [data, nb_frames]
169 218
170 def seek(self, value = 0, delta = False): 219 def seek(self, value=0, delta=False):
171 # We don't want to do that while stopping 220 # We don't want to do that while stopping
172 if not (self.is_loaded_playing() or self.is_loaded_paused()): 221 if not (self.is_loaded_playing() or self.is_loaded_paused()):
173 return 222 return
174 with self.music_lock: 223 with self.music_lock:
175 self.a_s_with_effect = None 224 self.a_s_with_effect = None
176 self.current_frame = max(0, int(delta) * self.current_frame + int(value * self.audio_segment.frame_rate)) 225 self.current_frame = max(
226 0,
227 int(delta) * self.current_frame
228 + int(value * self.audio_segment.frame_rate))
177 # FIXME: si on fait un seek + delta, adapter le "loop" 229 # FIXME: si on fait un seek + delta, adapter le "loop"
178 230
179 def stop(self, fade_out = 0, wait = False): 231 def stop(self, fade_out=0, wait=False):
180 if self.is_loaded_playing(): 232 if self.is_loaded_playing():
181 ms = int(self.sound_position * 1000) 233 ms = int(self.sound_position * 1000)
182 ms_fo = max(1, int(fade_out * 1000)) 234 ms_fo = max(1, int(fade_out * 1000))
183 235
184 new_audio_segment = self.current_audio_segment[:ms + ms_fo].fade_out(ms_fo) 236 new_audio_segment = self.current_audio_segment[: ms+ms_fo] \
237 .fade_out(ms_fo)
185 with self.music_lock: 238 with self.music_lock:
186 self.current_audio_segment = new_audio_segment 239 self.current_audio_segment = new_audio_segment
187 self.stop_playing() 240 self.stop_playing()
@@ -195,8 +248,10 @@ class MusicFile(Machine):
195 self.db_gain += db_gain 248 self.db_gain += db_gain
196 self.volume_factor = 10 ** (self.db_gain / 20) 249 self.volume_factor = 10 ** (self.db_gain / 20)
197 250
198 def set_volume(self, value, delta = False): 251 def set_volume(self, value, delta=False):
199 [db_gain, self.volume] = gain(value + int(delta) * self.volume, self.volume) 252 [db_gain, self.volume] = gain(
253 value + int(delta) * self.volume,
254 self.volume)
200 255
201 self.set_gain(db_gain) 256 self.set_gain(db_gain)
202 257