ASLP-lab/DiffRhythm
689
1# Copyright (c) 2024 Amphion.2#3# This source code is licensed under the MIT license found in the4# LICENSE file in the root directory of this source tree.5 6from phonemizer.backend import EspeakBackend7from phonemizer.separator import Separator8from phonemizer.utils import list2str, str2list9from typing import List, Union10import os11import json12import sys13 14# separator=Separator(phone=' ', word=' _ ', syllable='|'),15separator = Separator(word=" _ ", syllable="|", phone=" ")16 17phonemizer_zh = EspeakBackend(18 "cmn", preserve_punctuation=False, with_stress=False, language_switch="remove-flags"19)20# phonemizer_zh.separator = separator21 22phonemizer_en = EspeakBackend(23 "en-us",24 preserve_punctuation=False,25 with_stress=False,26 language_switch="remove-flags",27)28# phonemizer_en.separator = separator29 30phonemizer_ja = EspeakBackend(31 "ja", preserve_punctuation=False, with_stress=False, language_switch="remove-flags"32)33# phonemizer_ja.separator = separator34 35phonemizer_ko = EspeakBackend(36 "ko", preserve_punctuation=False, with_stress=False, language_switch="remove-flags"37)38# phonemizer_ko.separator = separator39 40phonemizer_fr = EspeakBackend(41 "fr-fr",42 preserve_punctuation=False,43 with_stress=False,44 language_switch="remove-flags",45)46# phonemizer_fr.separator = separator47 48phonemizer_de = EspeakBackend(49 "de", preserve_punctuation=False, with_stress=False, language_switch="remove-flags"50)51# phonemizer_de.separator = separator52 53 54lang2backend = {55 "zh": phonemizer_zh,56 "ja": phonemizer_ja,57 "en": phonemizer_en,58 "fr": phonemizer_fr,59 "ko": phonemizer_ko,60 "de": phonemizer_de,61}62 63with open("./diffrhythm/g2p/utils/mls_en.json", "r") as f:64 json_data = f.read()65token = json.loads(json_data)66 67 68def phonemizer_g2p(text, language):69 langbackend = lang2backend[language]70 phonemes = _phonemize(71 langbackend,72 text,73 separator,74 strip=True,75 njobs=1,76 prepend_text=False,77 preserve_empty_lines=False,78 )79 token_id = []80 if isinstance(phonemes, list):81 for phone in phonemes:82 phonemes_split = phone.split(" ")83 token_id.append([token[p] for p in phonemes_split if p in token])84 else:85 phonemes_split = phonemes.split(" ")86 token_id = [token[p] for p in phonemes_split if p in token]87 return phonemes, token_id88 89 90def _phonemize( # pylint: disable=too-many-arguments91 backend,92 text: Union[str, List[str]],93 separator: Separator,94 strip: bool,95 njobs: int,96 prepend_text: bool,97 preserve_empty_lines: bool,98):99 """Auxiliary function to phonemize()100 101 Does the phonemization and returns the phonemized text. Raises a102 RuntimeError on error.103 104 """105 # remember the text type for output (either list or string)106 text_type = type(text)107 108 # force the text as a list109 text = [line.strip(os.linesep) for line in str2list(text)]110 111 # if preserving empty lines, note the index of each empty line112 if preserve_empty_lines:113 empty_lines = [n for n, line in enumerate(text) if not line.strip()]114 115 # ignore empty lines116 text = [line for line in text if line.strip()]117 118 if text:119 # phonemize the text120 phonemized = backend.phonemize(121 text, separator=separator, strip=strip, njobs=njobs122 )123 else:124 phonemized = []125 126 # if preserving empty lines, reinsert them into text and phonemized lists127 if preserve_empty_lines:128 for i in empty_lines: # noqa129 if prepend_text:130 text.insert(i, "")131 phonemized.insert(i, "")132 133 # at that point, the phonemized text is a list of str. Format it as134 # expected by the parameters135 if prepend_text:136 return list(zip(text, phonemized))137 if text_type == str:138 return list2str(phonemized)139 return phonemized140 