44 lines
1.2 KiB
Python
44 lines
1.2 KiB
Python
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()
|