diff options
-rw-r--r-- | helpers/music_effect.py | 21 | ||||
-rw-r--r-- | helpers/music_file.py | 50 |
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)) |