yjhuangcd
First commit
9965bf6
"""Utility functions for handling fluidsynth
"""
import os
import pkg_resources
try:
import fluidsynth
_HAS_FLUIDSYNTH = True
except ImportError:
_HAS_FLUIDSYNTH = False
DEFAULT_SF2 = 'TimGM6mb.sf2'
DEFAULT_SAMPLE_RATE = 44100
def get_fluidsynth_instance(synthesizer=None, sfid=0, fs=None):
""" Check if a valid fluidsynth.Synth instance is provided, and if not,
create one.
Parameters
----------
synthesizer : fluidsynth.Synth or str
fluidsynth.Synth instance to use or a string with the path to a .sf2 file.
Default ``None``, which creates a new instance using the TimGM6mb.sf2 file
included with ``pretty_midi``.
sfid : int
Soundfont ID to use if an instance of fluidsynth.Synth is provided.
Default ``0``, which uses the first soundfont.
fs : int
Sampling rate to synthesize at.
Default ``None``, which falls back to ``pretty_midi.fluidsynth.DEFAULT_SAMPLE_RATE``
= 44100 if a new instance must be created.
If ``synthesizer`` is an existing instance and ``fs`` is specified, then
ValueError will be raised if the sample rates are not equal.
Returns
-------
synthesizer : fluidsynth.Synth
fluidsynth.Synth instance
sfid : int
Soundfont ID
new_instance_created : bool
Whether a new instance of fluidsynth.Synth was created.
"""
if not _HAS_FLUIDSYNTH:
raise ImportError("fluidsynth() was called but pyfluidsynth is not installed.")
if synthesizer is None:
synthesizer = pkg_resources.resource_filename(__name__, DEFAULT_SF2)
# Create a fluidsynth instance if one wasn't provided
if isinstance(synthesizer, str):
sf2_path = synthesizer
if not os.path.exists(synthesizer):
raise ValueError("No soundfont file found at the supplied path {}".format(sf2_path))
fs = fs or DEFAULT_SAMPLE_RATE
synthesizer = fluidsynth.Synth(samplerate=fs)
sfid = synthesizer.sfload(sf2_path)
new_instance_created = True
elif isinstance(synthesizer, fluidsynth.Synth):
synth_fs = synthesizer.get_setting('synth.sample-rate')
if fs and synth_fs != fs:
raise ValueError(
f"synthesizer sample rate of {synth_fs} doesn't match provided fs of {fs}")
new_instance_created = False
else:
raise ValueError("synthesizer must be a str or a fluidsynth.Synth instance")
return synthesizer, sfid, new_instance_created