import time import os import fluidsynth from constants import NOTE_TO_MIDI, GENERAL_MIDI_PROGRAMS, SOUNDFONTS from settings_mixin import Settings class AudioMixin: def __init__(self): self.fs = fluidsynth.Synth() self.fs.start(driver="alsa" if os.name != "nt" else "dsound") self.sf_id = None self.update_sf(SOUNDFONTS[Settings.INSTRUMENT]) self.clear_screen() def update_sf(self, path): if self.sf_id is not None and self.sf_id != -1: self.fs.sfunload(self.sf_id) sf2_path = os.path.join(os.path.dirname(__file__), "assets/audio", path) self.sf_id = self.fs.sfload(sf2_path) self.fs.program_select(0, self.sf_id, 0, GENERAL_MIDI_PROGRAMS[Settings.INSTRUMENT]) def play(self, note_name, duration, rest=False): if note_name not in NOTE_TO_MIDI: return midi_num = NOTE_TO_MIDI[note_name] channel = 0 velocity = 100 if not rest: self.fs.noteon(channel, midi_num, velocity) time.sleep(duration) if not rest: self.fs.noteoff(channel, midi_num) def close(self): self.fs.delete()