vits-api / module /polyphonic /polyphonic.py
Artrajz's picture
Update: GPT-SoVITS v2 (#186)
e0c636b unverified
Raw
History Blame Contribute Delete
4 kB
import os
import pypinyin
import yaml
import jieba
from pypinyin.contrib.tone_convert import to_tone, to_initials, to_finals_tone3
from config import config, BASE_DIR
# 定义自定义的表示器来确保列表显示在同一行
class MyDumper(yaml.Dumper):
def increase_indent(self, flow=False, indentless=False):
return super(MyDumper, self).increase_indent(flow, False)
# 自定义表示器来强制使用单引号和流格式
def represent_list(self, data):
value = self.represent_sequence('tag:yaml.org,2002:seq', data, flow_style=True)
for item in value.value:
item.style = "'"
return value
def represent_str(self, data):
if isinstance(data, str):
return self.represent_scalar('tag:yaml.org,2002:str', data, style="'")
return self.represent_scalar('tag:yaml.org,2002:str', data)
MyDumper.add_representer(list, represent_list)
MyDumper.add_representer(str, represent_str)
def load_polyphonic_dict(path: str) -> dict:
with open(path, 'r', encoding='utf-8') as polyphonic_file:
# 解析yaml
polyphonic_dict = yaml.load(polyphonic_file, Loader=yaml.FullLoader)
return polyphonic_dict
def save_polyphonic_dict(path: str, polyphonic_dict: dict):
with open(path, 'w', encoding='utf-8') as polyphonic_file:
yaml.dump(polyphonic_dict, polyphonic_file, Dumper=MyDumper, allow_unicode=True, default_flow_style=False,
sort_keys=False)
class Polyphonic:
def __init__(self):
self.path: str = os.path.join(BASE_DIR, config.system.data_path, config.polyphonic.dict_path)
self.polyphonic_dict = load_polyphonic_dict(self.path)
self.polyphonic_words = self.polyphonic_dict["polyphonic"]
for word in self.polyphonic_words.keys():
jieba.add_word(word)
pypinyin.load_phrases_dict(self.polyphonic_dict)
def correct_pronunciation(self, word: str, pinyin: list[list[str]] | tuple[list[str], list[str]], style=1):
if word in self.polyphonic_words.keys():
_pinyin = self.polyphonic_words[word]
if style == 1:
pinyin: list[list[str]] = [[to_tone(x)] for x in _pinyin]
elif style == 2:
initials = [to_initials(x) for x in _pinyin]
finals = [to_finals_tone3(x, neutral_tone_with_five=True) for x in _pinyin]
pinyin: tuple[list[str], list[str]] = (initials, finals)
elif style == 3: # GPT-SoVITS v2
pinyin: list[str] = [to_tone(x) for x in _pinyin]
return pinyin
def update_polyphonic(self):
self.polyphonic_dict = load_polyphonic_dict(self.path)
self.polyphonic_words = self.polyphonic_dict["polyphonic"]
for word in self.polyphonic_words.keys():
jieba.add_word(word)
pypinyin.load_phrases_dict(self.polyphonic_dict)
def save_polyphonic(self):
save_polyphonic_dict(self.path, self.polyphonic_dict)
corrector: Polyphonic | None = None
def load_polyphonic():
global corrector
if corrector is None:
corrector = Polyphonic()
def get_polyphonic_dict():
if corrector is None:
load_polyphonic()
return corrector.polyphonic_dict
def correct_pronunciation(word, pinyin, style=1):
if corrector is None:
load_polyphonic()
return corrector.correct_pronunciation(word, pinyin, style)
def add_polyphonic(word, pinyin):
if corrector is None:
load_polyphonic()
if len(word) != len(pinyin):
return False
corrector.polyphonic_words[word] = pinyin
corrector.save_polyphonic()
return True
def delete_polyphonic(word):
if corrector is None:
load_polyphonic()
if word in corrector.polyphonic_words.keys():
del corrector.polyphonic_words[word]
corrector.save_polyphonic()
return True
return False
def update_polyphonic():
if corrector is None:
load_polyphonic()
corrector.update_polyphonic()