aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--helpers/music_effect.py21
-rw-r--r--helpers/music_file.py50
2 files changed, 33 insertions, 38 deletions
diff --git a/helpers/music_effect.py b/helpers/music_effect.py
index ef8dc90..23583cd 100644
--- a/helpers/music_effect.py
+++ b/helpers/music_effect.py
@@ -3,7 +3,7 @@ class GainEffect:
3 'fade' 3 'fade'
4 ] 4 ]
5 5
6 def __init__(self, effect, audio_segment, start, end, **kwargs): 6 def __init__(self, effect, audio_segment, initial_loop, start, end, **kwargs):
7 if effect in self.effect_types: 7 if effect in self.effect_types:
8 self.effect = effect 8 self.effect = effect
9 else: 9 else:
@@ -12,30 +12,41 @@ class GainEffect:
12 self.start = start 12 self.start = start
13 self.end = end 13 self.end = end
14 self.audio_segment = audio_segment 14 self.audio_segment = audio_segment
15 self.initial_loop = initial_loop
15 getattr(self, self.effect + "_init")(**kwargs) 16 getattr(self, self.effect + "_init")(**kwargs)
16 17
17 def get_last_gain(self): 18 def get_last_gain(self):
18 return getattr(self, self.effect + "_get_last_gain")() 19 return getattr(self, self.effect + "_get_last_gain")()
19 20
20 def get_next_gain(self, current_frame, frame_count): 21 def get_next_gain(self, current_frame, current_loop, frame_count):
21 # This returns two values: 22 # This returns two values:
22 # - The first one is the gain to apply on that frame 23 # - The first one is the gain to apply on that frame
23 # - The last one is True or False depending on whether it is the last 24 # - The last one is True or False depending on whether it is the last
24 # call to the function and the last gain should be saved permanently 25 # call to the function and the last gain should be saved permanently
25 return getattr(self, self.effect + "_get_next_gain")( 26 return getattr(self, self.effect + "_get_next_gain")(
26 current_frame, 27 current_frame,
28 current_loop,
27 frame_count) 29 frame_count)
28 30
29 # Fading 31 # Fading
30 def fade_init(self, gain=0, **kwargs): 32 def fade_init(self, gain=0, **kwargs):
31 self.first_frame = int(self.audio_segment.frame_rate * self.start) 33 self.audio_segment_frame_count = self.audio_segment.frame_count()
32 self.last_frame = int(self.audio_segment.frame_rate * self.end) 34 self.first_frame = int(
35 self.audio_segment_frame_count * self.initial_loop +\
36 self.audio_segment.frame_rate * self.start)
37 self.last_frame = int(
38 self.audio_segment_frame_count * self.initial_loop +\
39 self.audio_segment.frame_rate * self.end)
33 self.gain= gain 40 self.gain= gain
34 41
35 def fade_get_last_gain(self): 42 def fade_get_last_gain(self):
36 return self.gain 43 return self.gain
37 44
38 def fade_get_next_gain(self, current_frame, frame_count): 45 def fade_get_next_gain(self, current_frame, current_loop, frame_count):
46 current_frame = current_frame \
47 + (current_loop - self.initial_loop) \
48 * self.audio_segment_frame_count
49
39 if current_frame >= self.last_frame: 50 if current_frame >= self.last_frame:
40 return [self.gain, True] 51 return [self.gain, True]
41 elif current_frame < self.first_frame: 52 elif current_frame < self.first_frame:
diff --git a/helpers/music_file.py b/helpers/music_file.py
index 810bc22..a37a708 100644
--- a/helpers/music_file.py
+++ b/helpers/music_file.py
@@ -127,20 +127,22 @@ class MusicFile(Machine):
127 def play(self, fade_in=0, volume=100, loop=0, start_at=0): 127 def play(self, fade_in=0, volume=100, loop=0, start_at=0):
128 self.set_gain(gain(volume) + self.mapping.master_gain, absolute=True) 128 self.set_gain(gain(volume) + self.mapping.master_gain, absolute=True)
129 self.volume = volume 129 self.volume = volume
130 self.loop = loop 130 self.current_loop = 0
131 self.loop_left = loop
131 132
132 ms = int(start_at * 1000)
133 ms_fi = int(fade_in * 1000)
134 with self.music_lock: 133 with self.music_lock:
135 self.current_audio_segment = self.audio_segment 134 self.current_audio_segment = self.audio_segment
136 self.current_frame = int(start_at * self.audio_segment.frame_rate) 135 self.current_frame = int(start_at * self.audio_segment.frame_rate)
137 if ms_fi > 0: 136 if fade_in > 0:
138 self.a_s_with_effect = self \ 137 db_gain = gain(self.volume, 0)[0]
139 .current_audio_segment[ms : ms+ms_fi] \ 138 self.set_gain(-db_gain)
140 .fade_in(ms_fi) 139 self.gain_effects.append(GainEffect(
141 self.current_frame_with_effect = 0 140 "fade",
142 else: 141 self.current_audio_segment,
143 self.a_s_with_effect = None 142 self.current_loop,
143 self.sound_position,
144 self.sound_position + fade_in,
145 gain=db_gain))
144 146
145 self.start_playing() 147 self.start_playing()
146 148
@@ -164,8 +166,9 @@ class MusicFile(Machine):
164 with self.music_lock: 166 with self.music_lock:
165 [data, nb_frames] = self.get_next_sample(frame_count) 167 [data, nb_frames] = self.get_next_sample(frame_count)
166 if nb_frames < frame_count: 168 if nb_frames < frame_count:
167 if self.is_loaded_playing() and self.loop != 0: 169 if self.is_loaded_playing() and self.loop_left != 0:
168 self.loop -= 1 170 self.loop_left -= 1
171 self.current_loop += 1
169 self.current_frame = 0 172 self.current_frame = 0
170 [new_data, new_nb_frames] = self.get_next_sample( 173 [new_data, new_nb_frames] = self.get_next_sample(
171 frame_count - nb_frames) 174 frame_count - nb_frames)
@@ -184,25 +187,6 @@ class MusicFile(Machine):
184 187
185 data = b"" 188 data = b""
186 nb_frames = 0 189 nb_frames = 0
187 if self.a_s_with_effect is not None:
188 segment = self.a_s_with_effect
189 max_val = int(segment.frame_count())
190
191 start_i = max(self.current_frame_with_effect, 0)
192 end_i = min(self.current_frame_with_effect + frame_count, max_val)
193
194 data += segment._data[start_i*fw : end_i*fw]
195
196 frame_count = max(
197 0,
198 self.current_frame_with_effect + frame_count - max_val)
199
200 self.current_frame_with_effect += end_i - start_i
201 self.current_frame += end_i - start_i
202 nb_frames += end_i - start_i
203
204 if frame_count > 0:
205 self.a_s_with_effect = None
206 190
207 segment = self.current_audio_segment 191 segment = self.current_audio_segment
208 max_val = int(segment.frame_count()) 192 max_val = int(segment.frame_count())
@@ -213,7 +197,6 @@ class MusicFile(Machine):
213 nb_frames += end_i - start_i 197 nb_frames += end_i - start_i
214 self.current_frame += end_i - start_i 198 self.current_frame += end_i - start_i
215 199
216 # FIXME: self.effects_next_gain should take into account the loop number
217 volume_factor = self.volume_factor(self.effects_next_gain(nb_frames)) 200 volume_factor = self.volume_factor(self.effects_next_gain(nb_frames))
218 201
219 data = audioop.mul(data, Config.sample_width, volume_factor) 202 data = audioop.mul(data, Config.sample_width, volume_factor)
@@ -226,7 +209,6 @@ class MusicFile(Machine):
226 return 209 return
227 with self.music_lock: 210 with self.music_lock:
228 self.abandon_all_effects() 211 self.abandon_all_effects()
229 self.a_s_with_effect = None
230 self.current_frame = max( 212 self.current_frame = max(
231 0, 213 0,
232 int(delta) * self.current_frame 214 int(delta) * self.current_frame
@@ -238,6 +220,7 @@ class MusicFile(Machine):
238 for gain_effect in self.gain_effects: 220 for gain_effect in self.gain_effects:
239 [new_gain, last_gain] = gain_effect.get_next_gain( 221 [new_gain, last_gain] = gain_effect.get_next_gain(
240 self.current_frame, 222 self.current_frame,
223 self.current_loop,
241 frame_count) 224 frame_count)
242 if last_gain: 225 if last_gain:
243 self.set_gain(new_gain) 226 self.set_gain(new_gain)
@@ -289,6 +272,7 @@ class MusicFile(Machine):
289 self.gain_effects.append(GainEffect( 272 self.gain_effects.append(GainEffect(
290 "fade", 273 "fade",
291 self.current_audio_segment, 274 self.current_audio_segment,
275 self.current_loop,
292 self.sound_position, 276 self.sound_position,
293 self.sound_position + fade, 277 self.sound_position + fade,
294 gain=db_gain)) 278 gain=db_gain))