Spaces:
Runtime error
Runtime error
| import gradio as gr | |
| import numpy as np | |
| import spaces | |
| from ipa import g2p | |
| from ipa.ipa import text_to_ipa | |
| from models import models_config | |
| def _do_tts(model_id, ipa, language_name, speaker_name=None, speaker_wav=None): | |
| model = models_config[model_id]["model"] | |
| if speaker_wav is not None: | |
| return model.tts( | |
| ipa, | |
| speaker_wav=speaker_wav, | |
| language_name=language_name, | |
| split_sentences=False, | |
| ) | |
| return model.tts( | |
| ipa, | |
| speaker_name=speaker_name, | |
| language_name=language_name, | |
| split_sentences=False, | |
| ) | |
| def text_to_speech( | |
| model_id: str, | |
| use_default_emb_or_custom: str, | |
| speaker_wav, | |
| speaker: str, | |
| language: str, | |
| dialect: str, | |
| speed: float, | |
| text: str, | |
| ): | |
| if len(text) == 0: | |
| raise gr.Error("請勿輸入空字串。") | |
| tag = language | |
| if language not in g2p: | |
| tag = f"{language}_{dialect}" | |
| ignore_comma = "gt3" not in model_id | |
| ipa = text_to_ipa(text, tag, g2p, ignore_comma) | |
| models_config[model_id]["model"].tts_model.length_scale = speed | |
| if use_default_emb_or_custom == "預設語者": | |
| wav = _do_tts( | |
| model_id, | |
| ipa, | |
| speaker_name=speaker | |
| if len(models_config[model_id]["speaker_mapping"]) > 1 | |
| else None, | |
| language_name=language, | |
| ) | |
| else: | |
| wav = _do_tts( | |
| model_id, | |
| ipa, | |
| speaker_wav=speaker_wav, | |
| language_name=language, | |
| ) | |
| return ( | |
| models_config[model_id]["model"].tts_model.config.audio.sample_rate, | |
| np.array(wav), | |
| ) | |
| def when_model_selected(model_id): | |
| model_config = models_config[model_id] | |
| speaker_drop_down_choices = [ | |
| (k, v) for k, v in model_config["speaker_mapping"].items() | |
| ] | |
| language_radio_choices = [ | |
| (k, v) for k, v in model_config["language_mapping"].items() | |
| ] | |
| use_default_emb_or_ref_radio_visible = False | |
| if model_config["model"].tts_model.config.model_args.speaker_encoder_model_path: | |
| use_default_emb_or_ref_radio_visible = True | |
| return ( | |
| gr.update( | |
| choices=speaker_drop_down_choices, | |
| value=speaker_drop_down_choices[0][1] | |
| if len(speaker_drop_down_choices) > 0 | |
| else None, | |
| interactive=len(speaker_drop_down_choices) > 1, | |
| ), | |
| gr.update( | |
| choices=language_radio_choices, | |
| value=language_radio_choices[0][1], | |
| interactive=len(language_radio_choices) > 1, | |
| ), | |
| gr.update(visible=use_default_emb_or_ref_radio_visible, value="預設語者"), | |
| ) | |
| def use_default_emb_or_custom_radio_input(use_default_emb_or_custom): | |
| if use_default_emb_or_custom == "客製化語者": | |
| return gr.update(visible=True), gr.update(visible=False) | |
| return gr.update(visible=False), gr.update(visible=True) | |
| def language_radio_changed(language): | |
| if language in g2p: | |
| dialect_choices = [("None", "")] | |
| else: | |
| dialect_choices = [ | |
| (tag.split("_")[1], tag.split("_")[1]) | |
| for tag in g2p.keys() | |
| if language in tag | |
| ] | |
| return gr.update( | |
| choices=dialect_choices, | |
| value=dialect_choices[0][1], | |
| interactive=len(dialect_choices) > 1, | |
| visible=language not in g2p, | |
| ) | |
| def update_example(language): | |
| component_props = examples.dataset.component_props | |
| if language in g2p: | |
| component_props[0]["visible"] = False | |
| component_props[0]["choices"] = [("None", "")] | |
| else: | |
| component_props[0]["visible"] = True | |
| component_props[0]["choices"] = [ | |
| (tag.split("_")[1], tag.split("_")[1]) | |
| for tag in g2p.keys() | |
| if language in tag | |
| ] | |
| if language == "阿美": | |
| return gr.Dataset( | |
| component_props=component_props, | |
| samples=[ | |
| [ | |
| "南勢", | |
| "U payniyaru’ nu pangcah i matiya, u ina haw ku miterungay, mikadavu ku vavainay i vavahiyan a luma.", | |
| "阿美族的原始社會,是以女人為主的母系社會,男子授室入贅女家。", | |
| ], | |
| [ | |
| "恆春", | |
| "O todong no cecayay a kitakit ko sa’osi to itiya:ay ho a kasaniyaro’.", | |
| "當時的部落如同一個國家的概念。", | |
| ], | |
| [ | |
| "馬蘭", | |
| "O sata’angayay a pisanga’an to tilong ko Tafalong itiya ho, mapaliwal i kasaniyaroaro’ ko misatilongan to sakacaloway no finawlan i ’orip a lalosidan.", | |
| "而太巴塱部落則是當時最大的製造陶埸域,供應各部落族人日常生活的陶器用品。", | |
| ], | |
| [ | |
| "秀姑巒", | |
| "ci ngangan ko Pangcah to Awa^, ’Afo^, Oning, Falah sanay a ngangan.", | |
| "所以阿美族有Awa^(一無所有)、’Afo^(碳灰)、Oning(污垢)、Falah(丟棄)……等這樣的名字。", | |
| ], | |
| [ | |
| "海岸", | |
| "mikayat ko kawili kawanan a kamay to tatihi, masakawanan ko rakat a mitaliyok, lahoday ko piperok, mato’asay, o wawa ato lafang maemin mangaay a masakero.", | |
| "單純的手牽手,向右移動來繞圓圈,很輕鬆,老少咸宜全下場跳。", | |
| ], | |
| ], | |
| ) | |
| if language == "賽德克": | |
| return gr.Dataset( | |
| component_props=component_props, | |
| samples=[ | |
| [ | |
| "德固達雅", | |
| "Netun so laqi tnqliyan de, asi ka mangal ngayan rrudan na seediq tnquli ka ngayan laqi tnqliyan.", | |
| "若是收養的子女,被收養子女的名字就要承傳收養者家族先人的名字。", | |
| ], | |
| [ | |
| "德鹿谷", | |
| "Mnsuwil mangal hangan samac ni pnegalang uri.", | |
| "有時也以動植物命名。", | |
| ], | |
| [ | |
| "都達", | |
| "so ana manu hhmaan Sediq u niqan balay snlhayan na.", | |
| "農耕行為極度神聖化。", | |
| ], | |
| ], | |
| ) | |
| if language == "太魯閣": | |
| return gr.Dataset( | |
| component_props=component_props, | |
| samples=[ | |
| [ | |
| "", | |
| "Rudan Truku sexual o kmgaaw ptasan dqras kana, ida qtaan bi bitaq sayang ka rudan ptasan dqras.", | |
| "過去太魯閣族的耆老都是文面的,直到最近文面老人還能夠看得到。", | |
| ], | |
| ], | |
| ) | |
| def get_title(): | |
| with open("DEMO.md") as tong: | |
| return tong.readline().strip('# ') | |
| demo = gr.Blocks( | |
| title=get_title(), | |
| css="@import url(https://tauhu.tw/tauhu-oo.css);", | |
| theme=gr.themes.Default( | |
| font=( | |
| "tauhu-oo", | |
| gr.themes.GoogleFont("Source Sans Pro"), | |
| "ui-sans-serif", | |
| "system-ui", | |
| "sans-serif", | |
| ) | |
| ), | |
| ) | |
| with demo: | |
| default_model_id = list(models_config.keys())[0] | |
| model_drop_down = gr.Dropdown( | |
| models_config.keys(), | |
| value=default_model_id, | |
| label="模型", | |
| ) | |
| use_default_emb_or_custom_radio = gr.Radio( | |
| label="語者類型", | |
| choices=["預設語者", "客製化語者"], | |
| value="預設語者", | |
| visible=True, | |
| show_label=False, | |
| ) | |
| speaker_wav = gr.Audio( | |
| label="客製化語音", | |
| visible=False, | |
| editable=False, | |
| type="filepath", | |
| waveform_options=gr.WaveformOptions( | |
| show_controls=False, | |
| sample_rate=16000, | |
| ), | |
| ) | |
| speaker_drop_down = gr.Dropdown( | |
| choices=[ | |
| (k, v) | |
| for k, v in models_config[default_model_id]["speaker_mapping"].items() | |
| ], | |
| value=list(models_config[default_model_id]["speaker_mapping"].values())[0], | |
| label="語者", | |
| interactive=len(models_config[default_model_id]["speaker_mapping"]) > 1, | |
| visible=True, | |
| ) | |
| use_default_emb_or_custom_radio.change( | |
| use_default_emb_or_custom_radio_input, | |
| inputs=[use_default_emb_or_custom_radio], | |
| outputs=[speaker_wav, speaker_drop_down], | |
| ) | |
| default_language = list( | |
| models_config[default_model_id]["language_mapping"].values() | |
| )[0] | |
| language_radio = gr.Radio( | |
| choices=[ | |
| (k, v) | |
| for k, v in models_config[default_model_id]["language_mapping"].items() | |
| ], | |
| value=default_language, | |
| label="語言", | |
| interactive=len(models_config[default_model_id]["language_mapping"]) > 1, | |
| ) | |
| default_dialect_choices = [ | |
| tag.split("_")[1] for tag in g2p.keys() if default_language in tag | |
| ] | |
| dialect_radio = gr.Radio( | |
| choices=default_dialect_choices, | |
| value=default_dialect_choices[0], | |
| label="方言", | |
| interactive=len(default_dialect_choices) > 1, | |
| ) | |
| model_drop_down.change( | |
| when_model_selected, | |
| inputs=[model_drop_down], | |
| outputs=[speaker_drop_down, language_radio, use_default_emb_or_custom_radio], | |
| ) | |
| input_text = gr.Textbox( | |
| label="輸入文字", | |
| value="", | |
| ) | |
| speed = gr.Slider(maximum=1.5, minimum=0.5, value=1, label="語速") | |
| with open("DEMO.md") as tong: | |
| gr.Markdown(tong.read()) | |
| gr.Interface( | |
| text_to_speech, | |
| inputs=[ | |
| model_drop_down, | |
| use_default_emb_or_custom_radio, | |
| speaker_wav, | |
| speaker_drop_down, | |
| language_radio, | |
| dialect_radio, | |
| speed, | |
| input_text, | |
| ], | |
| outputs=[ | |
| gr.Audio(interactive=False, label="合成語音", show_download_button=True), | |
| ], | |
| allow_flagging="auto", | |
| ) | |
| dummy_chinese_text = gr.Textbox(visible=False, label="中文") | |
| examples = gr.Examples( | |
| [ | |
| [ | |
| "南勢", | |
| "U payniyaru’ nu pangcah i matiya, u ina haw ku miterungay, mikadavu ku vavainay i vavahiyan a luma.", | |
| "阿美族的原始社會,是以女人為主的母系社會,男子授室入贅女家。", | |
| ], | |
| [ | |
| "恆春", | |
| "O todong no cecayay a kitakit ko sa’osi to itiya:ay ho a kasaniyaro’.", | |
| "當時的部落如同一個國家的概念。", | |
| ], | |
| [ | |
| "馬蘭", | |
| "O sata’angayay a pisanga’an to tilong ko Tafalong itiya ho, mapaliwal i kasaniyaroaro’ ko misatilongan to sakacaloway no finawlan i ’orip a lalosidan.", | |
| "而太巴塱部落則是當時最大的製造陶埸域,供應各部落族人日常生活的陶器用品。", | |
| ], | |
| [ | |
| "秀姑巒", | |
| "ci ngangan ko Pangcah to Awa^, ’Afo^, Oning, Falah sanay a ngangan.", | |
| "所以阿美族有Awa^(一無所有)、’Afo^(碳灰)、Oning(污垢)、Falah(丟棄)……等這樣的名字。", | |
| ], | |
| [ | |
| "海岸", | |
| "mikayat ko kawili kawanan a kamay to tatihi, masakawanan ko rakat a mitaliyok, lahoday ko piperok, mato’asay, o wawa ato lafang maemin mangaay a masakero.", | |
| "單純的手牽手,向右移動來繞圓圈,很輕鬆,老少咸宜全下場跳。", | |
| ], | |
| ], | |
| label="範例", | |
| inputs=[dialect_radio, input_text, dummy_chinese_text], | |
| cache_examples=False, | |
| ) | |
| language_radio.change( | |
| language_radio_changed, inputs=[language_radio], outputs=[dialect_radio] | |
| ).then(update_example, inputs=[language_radio], outputs=[examples.dataset]) | |
| demo.launch() | |