- self.set_volume(volume)
-
- if start_at > 0:
- raw_data_length = len(self.raw_data)
- start_offset = int((raw_data_length / self.sound_duration) * start_at)
- start_offset = start_offset - (start_offset % 2)
- sound = pygame.mixer.Sound(self.raw_data[start_offset:])
- else:
- sound = pygame.mixer.Sound(self.raw_data)
-
- self.started_at = time.time()
- self.channel().play(sound, fade_ms = int(fade_in * 1000))
- self.flag_paused = False
-
- def pause(self):
- self.paused_at = time.time()
- self.channel().pause()
- self.flag_paused = True
-
- def unpause(self):
- self.started_at += (time.time() - self.paused_at)
- self.channel().unpause()
- self.flag_paused = False
+ self.db_gain = self.volume_to_gain(volume)
+ ms = int(start_at * 1000)
+ ms_fi = max(1, int(fade_in * 1000))
+ with self.music_lock:
+ self.current_audio_segment = (self.audio_segment + self.db_gain).fade(from_gain=-120, duration=ms_fi, start=ms)
+ self.before_loaded_playing(initial_frame = int(start_at * self.audio_segment.frame_rate))
+ self.start_playing()
+
+ def before_loaded_playing(self, initial_frame = 0):
+ self.current_frame = initial_frame
+ with self.music_lock:
+ segment = self.current_audio_segment
+
+ self.stream = sd.RawOutputStream(samplerate=segment.frame_rate,
+ channels=segment.channels,
+ dtype='int' + str(8*segment.sample_width), # FIXME: ?
+ latency=1.,
+ callback=self.play_callback,
+ finished_callback=self.finished_callback
+ )
+
+ def on_enter_loaded_playing(self):
+ self.stream.start()
+
+ def on_enter_loaded_paused(self):
+ self.stream.stop()
+
+ def finished_callback(self):
+ if self.is_loaded_playing():
+ self.stop_playing()
+ if self.is_loaded_stopping():
+ self.stopped()
+
+ def play_callback(self, out_data, frame_count, time_info, status_flags):
+ with self.music_lock:
+ audio_segment = self.current_audio_segment.get_sample_slice_data(
+ start_sample=self.current_frame,
+ end_sample=self.current_frame + frame_count
+ )
+ self.current_frame += frame_count
+ if len(audio_segment) == 0:
+ raise sd.CallbackStop
+
+ out_data[:] = audio_segment.ljust(len(out_data), b'\0')