Feat: multi-speaker in app.py
This commit is contained in:
24
app.py
24
app.py
@@ -52,6 +52,7 @@ def tts_fn(
|
|||||||
style_weight,
|
style_weight,
|
||||||
kata_tone_json_str,
|
kata_tone_json_str,
|
||||||
use_tone,
|
use_tone,
|
||||||
|
speaker,
|
||||||
):
|
):
|
||||||
assert model_holder.current_model is not None
|
assert model_holder.current_model is not None
|
||||||
|
|
||||||
@@ -82,6 +83,8 @@ def tts_fn(
|
|||||||
phone_tone = kata_tone2phone_tone(kata_tone)
|
phone_tone = kata_tone2phone_tone(kata_tone)
|
||||||
tone = [t for _, t in phone_tone]
|
tone = [t for _, t in phone_tone]
|
||||||
|
|
||||||
|
speaker_id = model_holder.current_model.spk2id[speaker]
|
||||||
|
|
||||||
start_time = datetime.datetime.now()
|
start_time = datetime.datetime.now()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -101,6 +104,7 @@ def tts_fn(
|
|||||||
style=style,
|
style=style,
|
||||||
style_weight=style_weight,
|
style_weight=style_weight,
|
||||||
given_tone=tone,
|
given_tone=tone,
|
||||||
|
sid=speaker_id,
|
||||||
)
|
)
|
||||||
except InvalidToneError as e:
|
except InvalidToneError as e:
|
||||||
logger.error(f"Tone error: {e}")
|
logger.error(f"Tone error: {e}")
|
||||||
@@ -109,7 +113,7 @@ def tts_fn(
|
|||||||
end_time = datetime.datetime.now()
|
end_time = datetime.datetime.now()
|
||||||
duration = (end_time - start_time).total_seconds()
|
duration = (end_time - start_time).total_seconds()
|
||||||
|
|
||||||
if tone is None and language == "JP" and not line_split:
|
if tone is None and language == "JP":
|
||||||
# アクセント指定に使えるようにアクセント情報を返す
|
# アクセント指定に使えるようにアクセント情報を返す
|
||||||
norm_text = text_normalize(text)
|
norm_text = text_normalize(text)
|
||||||
kata_tone = g2kata_tone(norm_text)
|
kata_tone = g2kata_tone(norm_text)
|
||||||
@@ -285,14 +289,25 @@ if __name__ == "__main__":
|
|||||||
maximum=2,
|
maximum=2,
|
||||||
value=DEFAULT_SPLIT_INTERVAL,
|
value=DEFAULT_SPLIT_INTERVAL,
|
||||||
step=0.1,
|
step=0.1,
|
||||||
label="分けた場合に挟む無音の長さ(秒)",
|
label="改行ごとに挟む無音の長さ(秒)",
|
||||||
|
)
|
||||||
|
line_split.change(
|
||||||
|
lambda x: (gr.Slider(visible=x)),
|
||||||
|
inputs=[line_split],
|
||||||
|
outputs=[split_interval],
|
||||||
)
|
)
|
||||||
tone = gr.Textbox(
|
tone = gr.Textbox(
|
||||||
label="アクセント調整(数値は 0=低 か1=高 のみ)",
|
label="アクセント調整(数値は 0=低 か1=高 のみ)",
|
||||||
info="改行で分けない場合のみ使えます",
|
info="改行で分けない場合のみ使えます。万能ではありません。",
|
||||||
)
|
)
|
||||||
use_tone = gr.Checkbox(label="アクセント調整を使う", value=False)
|
use_tone = gr.Checkbox(label="アクセント調整を使う", value=False)
|
||||||
|
use_tone.change(
|
||||||
|
lambda x: (gr.Checkbox(value=False) if x else gr.Checkbox()),
|
||||||
|
inputs=[use_tone],
|
||||||
|
outputs=[line_split],
|
||||||
|
)
|
||||||
language = gr.Dropdown(choices=languages, value="JP", label="Language")
|
language = gr.Dropdown(choices=languages, value="JP", label="Language")
|
||||||
|
speaker = gr.Dropdown(label="話者")
|
||||||
with gr.Accordion(label="詳細設定", open=False):
|
with gr.Accordion(label="詳細設定", open=False):
|
||||||
sdp_ratio = gr.Slider(
|
sdp_ratio = gr.Slider(
|
||||||
minimum=0,
|
minimum=0,
|
||||||
@@ -390,6 +405,7 @@ if __name__ == "__main__":
|
|||||||
style_weight,
|
style_weight,
|
||||||
tone,
|
tone,
|
||||||
use_tone,
|
use_tone,
|
||||||
|
speaker,
|
||||||
],
|
],
|
||||||
outputs=[text_output, audio_output, tone],
|
outputs=[text_output, audio_output, tone],
|
||||||
)
|
)
|
||||||
@@ -410,7 +426,7 @@ if __name__ == "__main__":
|
|||||||
load_button.click(
|
load_button.click(
|
||||||
model_holder.load_model_gr,
|
model_holder.load_model_gr,
|
||||||
inputs=[model_name, model_path],
|
inputs=[model_name, model_path],
|
||||||
outputs=[style, tts_button],
|
outputs=[style, tts_button, speaker],
|
||||||
)
|
)
|
||||||
|
|
||||||
style_mode.change(
|
style_mode.change(
|
||||||
|
|||||||
@@ -199,7 +199,7 @@ class ModelHolder:
|
|||||||
|
|
||||||
def load_model_gr(
|
def load_model_gr(
|
||||||
self, model_name: str, model_path: str
|
self, model_name: str, model_path: str
|
||||||
) -> tuple[gr.Dropdown, gr.Button]:
|
) -> tuple[gr.Dropdown, gr.Button, gr.Dropdown]:
|
||||||
if model_name not in self.model_files_dict:
|
if model_name not in self.model_files_dict:
|
||||||
raise ValueError(f"Model `{model_name}` is not found")
|
raise ValueError(f"Model `{model_name}` is not found")
|
||||||
if model_path not in self.model_files_dict[model_name]:
|
if model_path not in self.model_files_dict[model_name]:
|
||||||
@@ -210,10 +210,12 @@ class ModelHolder:
|
|||||||
style_vec_path=os.path.join(self.root_dir, model_name, "style_vectors.npy"),
|
style_vec_path=os.path.join(self.root_dir, model_name, "style_vectors.npy"),
|
||||||
device=self.device,
|
device=self.device,
|
||||||
)
|
)
|
||||||
|
speakers = list(self.current_model.spk2id.keys())
|
||||||
styles = list(self.current_model.style2id.keys())
|
styles = list(self.current_model.style2id.keys())
|
||||||
return (
|
return (
|
||||||
gr.Dropdown(choices=styles, value=styles[0]),
|
gr.Dropdown(choices=styles, value=styles[0]),
|
||||||
gr.Button(interactive=True, value="音声合成"),
|
gr.Button(interactive=True, value="音声合成"),
|
||||||
|
gr.Dropdown(choices=speakers, value=speakers[0]),
|
||||||
)
|
)
|
||||||
|
|
||||||
def update_model_files_gr(self, model_name: str) -> gr.Dropdown:
|
def update_model_files_gr(self, model_name: str) -> gr.Dropdown:
|
||||||
|
|||||||
Reference in New Issue
Block a user