Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def from_list(cls, properties_list):
assert isinstance(properties_list, (list, tuple))
properties_dict = cls()
for note_property in properties_list:
if isinstance(note_property, NotePlaybackAdjustment):
properties_dict["playback_adjustments"].append(note_property)
elif isinstance(note_property, str):
# if there's a colon, it represents a key / value pair, e.g. "articulation: staccato"
if ":" in note_property:
colon_index = note_property.index(":")
key, value = note_property[:colon_index].replace(" ", "").lower(), \
note_property[colon_index+1:].strip().lower()
else:
# otherwise, leave the key undecided for now
key = None
value = note_property.strip().lower()
# split values into a list based on the slash delimiter
values = [x.strip() for x in value.split("/")]
if key is None:
def _split_at_param_names(string: str):
if "pitch" in string and not string.startswith("pitch"):
i = string.index("pitch")
return NotePlaybackAdjustment._split_at_param_names(string[:i]) + \
NotePlaybackAdjustment._split_at_param_names(string[i:])
elif "volume" in string and not string.startswith("volume"):
i = string.index("volume")
return NotePlaybackAdjustment._split_at_param_names(string[:i]) + \
NotePlaybackAdjustment._split_at_param_names(string[i:])
elif "length" in string and not string.startswith("length"):
i = string.index("length")
return NotePlaybackAdjustment._split_at_param_names(string[:i]) + \
NotePlaybackAdjustment._split_at_param_names(string[i:])
return string,
"piano": "GrandPiano.sf2"
},
"default_audio_driver": None,
"default_midi_output_device": None,
"default_max_midi_pitch_bend": 48,
"osc_message_addresses": {
"start_note": "start_note",
"end_note": "end_note",
"change_pitch": "change_pitch",
"change_volume": "change_volume",
"change_quality": "change_quality"
},
"adjustments": PlaybackDictionary(articulations={
"staccato": NotePlaybackAdjustment.scale_params(length_scale=0.5),
"staccatissimo": NotePlaybackAdjustment.scale_params(length_scale=0.3),
"tenuto": NotePlaybackAdjustment.scale_params(length_scale=1.2),
"accent": NotePlaybackAdjustment.scale_params(volume_scale=1.2),
"marcato": NotePlaybackAdjustment.scale_params(volume_scale=1.5),
})
}
class PlaybackSettings(SavesToJSON):
def __init__(self, **settings):
self.named_soundfonts = _playback_settings_factory_defaults["named_soundfonts"] \
if "named_soundfonts" not in settings else settings["named_soundfonts"]
self.default_audio_driver = _playback_settings_factory_defaults["default_audio_driver"] \
if "default_audio_driver" not in settings else settings["default_audio_driver"]
self.default_midi_output_device = _playback_settings_factory_defaults["default_midi_output_device"] \
if "default_midi_output_device" not in settings else settings["default_midi_output_device"]
self.default_max_midi_pitch_bend = _playback_settings_factory_defaults["default_max_midi_pitch_bend"] \
def _from_dict(cls, json_dict):
# convert all adjustments from dictionaries to NotePlaybackAdjustments
for notation_category in json_dict:
for notation_name in json_dict[notation_category]:
if json_dict[notation_category][notation_name] is not None:
json_dict[notation_category][notation_name] = \
NotePlaybackAdjustment._from_dict(json_dict[notation_category][notation_name])
return cls(**json_dict)
if value in PlaybackAdjustmentsDictionary.all_noteheads:
properties_dict["noteheads"].append(value)
else:
logging.warning("Notehead {} not understood".format(value))
properties_dict["noteheads"].append("normal")
elif key in "notations": # note that this allows the singular "notation" too
for value in values:
if value in PlaybackAdjustmentsDictionary.all_notations:
properties_dict["notations"].append(value)
else:
logging.warning("Notation {} not understood".format(value))
elif key in "playback_adjustments": # note that this allows the singular "playback_adjustment" too
for value in values:
properties_dict["playback_adjustments"].append(NotePlaybackAdjustment.from_string(value))
elif key in ("key", "spelling", "spellingpolicy", "spelling_policy"):
try:
properties_dict["spelling_policy"] = SpellingPolicy.from_string(values[0])
except ValueError:
logging.warning("Spelling policy \"{}\" not understood".format(values[0]))
elif key.startswith("param_") or key.endswith("_param"):
if not len(values) == 1:
raise ValueError("Cannot have multiple values for a parameter property.")
properties_dict[key] = json.loads(value)
elif key == "voice":
if not len(values) == 1:
raise ValueError("Cannot have multiple values for a voice property.")
properties_dict["voice"] = value
def set(self, notation_detail: str, adjustment: Union[str, NotePlaybackAdjustment]) -> None:
"""
Set the given notation detail to have the given :class:`NotePlaybackAdjustment`.
Based on the name of the notation detail, it is automatically determined whether or not we are talking about
an articulation, a notehead, or another kind of notation.
:param notation_detail: name of the notation detail, e.g. "staccato" or "harmonic"
:param adjustment: the adjustment to make for that notation. Either a :class:`NotePlaybackAdjustment` or a
string to be parsed to a :class:`NotePlaybackAdjustment` using :code:`NotePlaybackAdjustment.from_string`
"""
if isinstance(adjustment, str):
adjustment = NotePlaybackAdjustment.from_string(adjustment)
if "notehead" in notation_detail:
notation_detail = notation_detail.replace("notehead", "").replace(" ", "").lower()
if notation_detail in PlaybackAdjustmentsDictionary.all_noteheads:
self["noteheads"][notation_detail] = adjustment
elif notation_detail in PlaybackAdjustmentsDictionary.all_articulations:
self["articulations"][notation_detail] = adjustment
elif notation_detail in PlaybackAdjustmentsDictionary.all_notations:
self["notations"][notation_detail] = adjustment
else:
raise ValueError("Playback property not understood.")
"default_max_soundfont_pitch_bend": 48,
"default_max_streaming_midi_pitch_bend": 2,
"soundfont_volume_to_velocity_curve": Envelope.from_points((0, 0), (0.1, 40), (1, 127)),
"streaming_midi_volume_to_velocity_curve": Envelope.from_points((0, 0), (1, 127)),
"osc_message_addresses": {
"start_note": "start_note",
"end_note": "end_note",
"change_pitch": "change_pitch",
"change_volume": "change_volume",
"change_parameter": "change_parameter"
},
"adjustments": PlaybackAdjustmentsDictionary(articulations={
"staccato": NotePlaybackAdjustment.scale_params(length=0.5),
"staccatissimo": NotePlaybackAdjustment.scale_params(length=0.3),
"tenuto": NotePlaybackAdjustment.scale_params(length=1.2),
"accent": NotePlaybackAdjustment.scale_params(volume=1.2),
"marcato": NotePlaybackAdjustment.scale_params(volume=1.5),
}),
"try_system_fluidsynth_first": False,
}
_settings_name = "Playback settings"
_json_path = "settings/playbackSettings.json"
_is_root_setting = True
def __init__(self, settings_dict: dict = None):
# This is here to help with auto-completion so that the IDE knows what attributes are available
self.named_soundfonts = self.default_soundfont = self.default_audio_driver = \
self.default_midi_output_device = self.default_max_soundfont_pitch_bend = \
self.default_max_streaming_midi_pitch_bend = self.soundfont_volume_to_velocity_curve = \
self.streaming_midi_volume_to_velocity_curve = self.osc_message_addresses = \
self.adjustments = self.try_system_fluidsynth_first = self.soundfont_search_paths = None
def __init__(self, **kwargs):
NotePropertiesDictionary._standardize_plural_entry("articulations", kwargs)
NotePropertiesDictionary._standardize_plural_entry("noteheads", kwargs)
if len(kwargs["noteheads"]) == 0:
kwargs["noteheads"] = ["normal"]
NotePropertiesDictionary._standardize_plural_entry("notations", kwargs)
NotePropertiesDictionary._standardize_plural_entry("texts", kwargs)
NotePropertiesDictionary._standardize_plural_entry("playback_adjustments", kwargs)
for i, adjustment in enumerate(kwargs["playback_adjustments"]):
if isinstance(adjustment, str):
kwargs["playback_adjustments"][i] = NotePlaybackAdjustment.from_string(adjustment)
if "spelling_policy" not in kwargs:
kwargs["spelling_policy"] = None
if "temp" not in kwargs:
# this is a throwaway directory that is not kept when we save to json
kwargs["temp"] = {}
super().__init__(**kwargs)
self._convert_params_to_envelopes_if_needed()
def from_unknown_format(cls, properties):
"""
Interprets a number of data formats as a NotePropertiesDictionary
:param properties: can be of several formats:
- a dictionary of note properties, using the standard format
- a list of properties, each of which is a string or a NotePlaybackAdjustment. Each string may be
colon-separated key / value pair (e.g. "articulation: staccato"), or simply the value (e.g. "staccato"),
in which case an attempt is made to guess the key.
- a string of comma-separated properties, which just gets split and treated like a list
- a NotePlaybackAdjustment, which just put in a list and treated like a list input
:return: a newly constructed NotePropertiesDictionary
"""
if isinstance(properties, str):
return NotePropertiesDictionary.from_string(properties)
elif isinstance(properties, NotePlaybackAdjustment):
return NotePropertiesDictionary.from_list([properties])
elif isinstance(properties, list):
return NotePropertiesDictionary.from_list(properties)
elif properties is None:
return cls()
else:
assert isinstance(properties, dict), "Properties argument wrongly formatted."
return cls(**properties)
"default_soundfont": "general_midi",
"default_audio_driver": "auto",
"default_midi_output_device": None,
"default_max_soundfont_pitch_bend": 48,
"default_max_streaming_midi_pitch_bend": 2,
"soundfont_volume_to_velocity_curve": Envelope.from_points((0, 0), (0.1, 40), (1, 127)),
"streaming_midi_volume_to_velocity_curve": Envelope.from_points((0, 0), (1, 127)),
"osc_message_addresses": {
"start_note": "start_note",
"end_note": "end_note",
"change_pitch": "change_pitch",
"change_volume": "change_volume",
"change_parameter": "change_parameter"
},
"adjustments": PlaybackAdjustmentsDictionary(articulations={
"staccato": NotePlaybackAdjustment.scale_params(length=0.5),
"staccatissimo": NotePlaybackAdjustment.scale_params(length=0.3),
"tenuto": NotePlaybackAdjustment.scale_params(length=1.2),
"accent": NotePlaybackAdjustment.scale_params(volume=1.2),
"marcato": NotePlaybackAdjustment.scale_params(volume=1.5),
}),
"try_system_fluidsynth_first": False,
}
_settings_name = "Playback settings"
_json_path = "settings/playbackSettings.json"
_is_root_setting = True
def __init__(self, settings_dict: dict = None):
# This is here to help with auto-completion so that the IDE knows what attributes are available
self.named_soundfonts = self.default_soundfont = self.default_audio_driver = \
self.default_midi_output_device = self.default_max_soundfont_pitch_bend = \