X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=helpers%2Fmusic_file.py;h=6a28d620f69c043019a8e964e3c5a8b2a81aec74;hb=1b4b78f5b6df7182ac066fcc26a7b4f0e8586a47;hp=e6a340da53e56c97dda679a14064f056e01fd670;hpb=71715c049145a074b0f2b8d90c8c8c47830323c3;p=perso%2FImmae%2FProjets%2FPython%2FMusicSampler.git diff --git a/helpers/music_file.py b/helpers/music_file.py index e6a340d..6a28d62 100644 --- a/helpers/music_file.py +++ b/helpers/music_file.py @@ -1,6 +1,5 @@ import threading import pydub -import math import time from transitions.extensions import HierarchicalMachine as Machine @@ -9,12 +8,14 @@ import sounddevice as sd import os.path from .lock import Lock +from . import gain + file_lock = Lock("file") pyaudio = pa.PyAudio() class MusicFile(Machine): - def __init__(self, filename, name = None, gain = 1): + def __init__(self, filename, mapping, name = None, gain = 1): states = [ 'initial', 'loading', @@ -34,11 +35,13 @@ class MusicFile(Machine): Machine.__init__(self, states=states, transitions=transitions, initial='initial') + self.volume = 100 + self.mapping = mapping self.filename = filename self.stream = None self.name = name or filename self.audio_segment = None - self.gain = gain + self.volume_factor = gain self.music_lock = Lock("music__" + filename) self.wait_event = threading.Event() @@ -48,8 +51,8 @@ class MusicFile(Machine): with file_lock: try: print("Loading « {} »".format(self.name)) - volume_factor = 20 * math.log10(self.gain) - self.audio_segment = pydub.AudioSegment.from_file(self.filename).set_frame_rate(44100).apply_gain(volume_factor) + db_gain = gain(self.volume_factor * 100) + self.audio_segment = pydub.AudioSegment.from_file(self.filename).set_frame_rate(44100).apply_gain(db_gain) self.sound_duration = self.audio_segment.duration_seconds except Exception as e: print("failed to load « {} »: {}".format(self.name, e)) @@ -76,11 +79,13 @@ class MusicFile(Machine): return 0 def play(self, fade_in = 0, volume = 100, start_at = 0): - self.db_gain = self.volume_to_gain(volume) + db_gain = gain(volume) + self.mapping.master_gain + self.volume = 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.current_audio_segment = (self.audio_segment + 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() @@ -124,7 +129,7 @@ class MusicFile(Machine): out_data[:] = audio_segment.ljust(len(out_data), b'\0') - def stop(self, fade_out = 0): + def stop(self, fade_out = 0, wait = False): if self.is_loaded_playing(): ms = int(self.sound_position * 1000) ms_fo = max(1, int(fade_out * 1000)) @@ -132,22 +137,25 @@ class MusicFile(Machine): with self.music_lock: self.current_audio_segment = self.current_audio_segment[:ms + ms_fo].fade_out(ms_fo) self.stop_playing() + if wait: + self.wait_end() else: self.stop_playing() self.stopped() - def set_volume(self, value): - if self.is_loaded_stopped(): + def set_gain(self, db_gain): + if not self.is_not_stopped(): return - db_gain = self.volume_to_gain(value) - new_audio_segment = self.current_audio_segment + (db_gain - self.db_gain) - self.db_gain = db_gain + new_audio_segment = self.current_audio_segment + db_gain + with self.music_lock: self.current_audio_segment = new_audio_segment - def volume_to_gain(self, volume): - return 20 * math.log10(max(volume, 0.0001) / 100) + def set_volume(self, value, add = False): + [db_gain, self.volume] = gain(value + int(add) * self.volume, self.volume) + + self.set_gain(db_gain) def wait_end(self): self.wait_event.clear()