"""Convert :class:`voxpopuli.PhonemeList` to mutwo events."""importtypingimportwarningsimportvoxpopulifrommutwoimportcore_constantsfrommutwoimportcore_convertersfrommutwoimportcore_eventsfrommutwoimportmusic_convertersfrommutwoimportmusic_parameters__all__=("EventToPhonemeList","EventToSpeakSynthesis","SimpleEventToPitch","SimpleEventToPhonemeString",)
[docs]classSimpleEventToPhonemeString(core_converters.SimpleEventToAttribute):"""Convert a simple event to a phoneme string."""def__init__(self,attribute_name:str="phoneme",exception_value:str="_"):super().__init__(attribute_name,exception_value)
[docs]classSimpleEventToPitch(music_converters.SimpleEventToPitchList):"""Convert a simple event to a pitch."""
[docs]defconvert(self,*args,**kwargs)->typing.Optional[music_parameters.abc.Pitch]:pitch_list=super().convert(*args,**kwargs)n_pitches=len(pitch_list)ifnotn_pitches:returnNoneelifn_pitches>1:warnings.warn("mutwo.music_converters.SimpleEventToPitch: "f"Found pitch list with {n_pitches} pitches. "f"Only the first pitch will be used: {pitch_list[0]}. ""All remaining pitches will be ignored.",RuntimeWarning,)returnpitch_list[0]
[docs]classEventToPhonemeList(core_converters.abc.EventConverter):"""Convert mutwo event to :class:`voxpopuli.PhonemeList`. :param simple_event_to_pitch: Function or converter which receives a :class:`mutwo.core_events.SimpleEvent` as an input and has to return a :class`mutwo.music_parameters.abc.Pitch` or `None`. :type simple_event_to_pitch: typing.Callable[[core_events.SimpleEvent], typing.Optional[music_parameters.abc.Pitch]] :param simple_event_to_phoneme_string: Function or converter which receives a :class:`mutwo.core_events.SimpleEvent` as an input and has to return a string which belongs to the phonetic alphabet SAMPA. :type simple_event_to_phoneme_string: typing.Callable[[core_events.SimpleEvent], str] **Warning:** This converter assumes that the duration attribute of the input event is in seconds. It multiplies the input duration by a factor of 1000 and parses it to the `voxpopuli.Phoneme` object which expects duration in milliseconds. It is the responsibility of the user to ensure that the duration has the right format. """def__init__(self,simple_event_to_pitch:typing.Callable[[core_events.SimpleEvent],typing.Optional[music_parameters.abc.Pitch]]=SimpleEventToPitch(),simple_event_to_phoneme_string:typing.Callable[[core_events.SimpleEvent],str]=SimpleEventToPhonemeString(),):self._simple_event_to_pitch=simple_event_to_pitchself._simple_event_to_phoneme_string=simple_event_to_phoneme_stringdef_pitch_to_pitch_modification_list(self,pitch:typing.Optional[music_parameters.abc.Pitch])->list[tuple[int,int]]:pitch_modification_list=[]ifpitch:pitch_envelope=pitch.resolve_envelope(100)for(pitch,time,)inzip(pitch_envelope.parameter_tuple,pitch_envelope.absolute_time_tuple):pitch_modification_list.append((int(time),int(pitch.frequency))# type: ignore)# We have to add a second value to ensure the pitch keeps# constant.iflen(pitch_modification_list)==1:pitch_modification_list.append((100,pitch_modification_list[0][-1]))returnpitch_modification_listdef_convert_simple_event(self,simple_event_to_convert:core_events.SimpleEvent,_:core_constants.DurationType,)->tuple[voxpopuli.Phoneme]:pitch=self._simple_event_to_pitch(simple_event_to_convert)phoneme_string=self._simple_event_to_phoneme_string(simple_event_to_convert)pitch_modification_list=self._pitch_to_pitch_modification_list(pitch)# From seconds to milliseconds (the converter assumes# that the input duration is in seconds!)duration=int(simple_event_to_convert.duration.duration_in_floats*1000)phoneme=voxpopuli.Phoneme(phoneme_string,duration,pitch_modification_list)return(phoneme,)
[docs]classEventToSpeakSynthesis(core_converters.abc.Converter):"""Render event to soundfile with speak synthesis engine mbrola. :param voice: The voice object which is responsible in rendering the soundfile. :type voice: voxpopuli.Voice :param event_to_phoneme_list: A converter or function which transforms an event to a :class:`voxpopuli.PhonemeList`. By default this is a :class:`mutwo.mbrola_converters.EventToPhonemeList` object.. :type event_to_phoneme_list: typing.Callable[[core_events.abc.Event], voxpopuli.PhonemeList] **Warning:** You need to install the non-python dependencies for `voxpopuli`, otherwise the converter won't work. """def__init__(self,voice:voxpopuli.Voice=voxpopuli.Voice(),event_to_phoneme_list:typing.Callable[[core_events.abc.Event],voxpopuli.PhonemeList]=EventToPhonemeList(),):self._event_to_phoneme_list=event_to_phoneme_listself._voice=voice