Spaces:
Running on Zero
Running on Zero
22
Browse files
app.py
CHANGED
|
@@ -274,6 +274,23 @@ CUSTOM_CSS = """
|
|
| 274 |
margin: auto !important;
|
| 275 |
}
|
| 276 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 277 |
/* ---------- Header / 头部 ---------- */
|
| 278 |
#app-header {
|
| 279 |
text-align: center;
|
|
@@ -374,14 +391,9 @@ CUSTOM_CSS = """
|
|
| 374 |
HEADER_HTML = """
|
| 375 |
<div id="app-header" align="center">
|
| 376 |
<h1>
|
| 377 |
-
🎤
|
| 378 |
-
Controllable Singing Voice Synthesis with Flexible Lyric Manipulation and Annotation-free Melody Guidance
|
| 379 |
</h1>
|
| 380 |
|
| 381 |
-
<div class="lang-links">
|
| 382 |
-
<a href="">English</a> | <a href="README_ZH.md">中文</a>
|
| 383 |
-
</div>
|
| 384 |
-
|
| 385 |
<div class="badges" style="margin: 10px 0;">
|
| 386 |
<img src="https://img.shields.io/badge/Python-3.10-3776AB?logo=python&logoColor=white" alt="Python">
|
| 387 |
<img src="https://img.shields.io/badge/License-CC%20BY--NC--SA%204.0-lightgrey" alt="License">
|
|
@@ -488,9 +500,91 @@ def build_ui():
|
|
| 488 |
lines=5,
|
| 489 |
)
|
| 490 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 491 |
# ================================================================
|
| 492 |
-
# ROW
|
| 493 |
# ================================================================
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 494 |
gr.Markdown("#### 🎚️ 伴奏分离 / Vocal Separation", elem_classes="section-title")
|
| 495 |
with gr.Row():
|
| 496 |
separate_vocals_flag = gr.Checkbox(
|
|
@@ -512,7 +606,7 @@ def build_ui():
|
|
| 512 |
)
|
| 513 |
|
| 514 |
# ================================================================
|
| 515 |
-
# ROW
|
| 516 |
# ================================================================
|
| 517 |
with gr.Accordion("⚙️ 高级参数 / Advanced Parameters", open=False):
|
| 518 |
with gr.Row():
|
|
@@ -540,38 +634,6 @@ def build_ui():
|
|
| 540 |
info="-1 表示随机 / -1 means random",
|
| 541 |
)
|
| 542 |
|
| 543 |
-
# All inputs in order expected by synthesize()
|
| 544 |
-
_all_inputs = [
|
| 545 |
-
ref_audio, melody_audio, ref_text, target_text,
|
| 546 |
-
separate_vocals_flag, mix_accompaniment_flag,
|
| 547 |
-
sil_len_to_end, t_shift, nfe_step, cfg_strength, seed,
|
| 548 |
-
]
|
| 549 |
-
|
| 550 |
-
# ================================================================
|
| 551 |
-
# ROW 4 – 预设示例 / Example Presets
|
| 552 |
-
# ================================================================
|
| 553 |
-
gr.HTML("<hr style='border-color:#30363d; margin: 20px 0 12px;'>")
|
| 554 |
-
gr.Markdown("#### 🎵 预设示例 / Example Presets", elem_classes="section-title")
|
| 555 |
-
gr.Markdown(
|
| 556 |
-
"<small style='color:#8b949e;'>点击任意行自动填入输入区域 / Click any row to auto-fill the inputs above</small>"
|
| 557 |
-
)
|
| 558 |
-
|
| 559 |
-
with gr.Tabs():
|
| 560 |
-
with gr.Tab("🎼 Melody Control"):
|
| 561 |
-
gr.Examples(
|
| 562 |
-
examples=EXAMPLES_MELODY_CONTROL,
|
| 563 |
-
inputs=_all_inputs,
|
| 564 |
-
label="Melody Control Examples",
|
| 565 |
-
examples_per_page=5,
|
| 566 |
-
)
|
| 567 |
-
with gr.Tab("✏️ Lyric Edit"):
|
| 568 |
-
gr.Examples(
|
| 569 |
-
examples=EXAMPLES_LYRIC_EDIT,
|
| 570 |
-
inputs=_all_inputs,
|
| 571 |
-
label="Lyric Edit Examples",
|
| 572 |
-
examples_per_page=5,
|
| 573 |
-
)
|
| 574 |
-
|
| 575 |
# ================================================================
|
| 576 |
# ROW 5 – 合成按钮与输出 / Run & Output
|
| 577 |
# ================================================================
|
|
@@ -584,11 +646,18 @@ def build_ui():
|
|
| 584 |
elem_id="output-audio",
|
| 585 |
)
|
| 586 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 587 |
# ================================================================
|
| 588 |
# Event wiring / 事件绑定
|
| 589 |
# ================================================================
|
| 590 |
separate_vocals_flag.change(
|
| 591 |
-
fn=lambda sep: gr.update(interactive=sep, value=False
|
| 592 |
inputs=[separate_vocals_flag],
|
| 593 |
outputs=[mix_accompaniment_flag],
|
| 594 |
)
|
|
@@ -599,13 +668,8 @@ def build_ui():
|
|
| 599 |
outputs=output_audio,
|
| 600 |
)
|
| 601 |
|
| 602 |
-
# ---- 页脚:免责声明
|
| 603 |
gr.HTML(DISCLAIMER_HTML)
|
| 604 |
-
gr.Markdown(
|
| 605 |
-
"<center style='color:#6e7681; font-size:0.78rem; margin-top: 4px;'>"
|
| 606 |
-
"Use <code>|</code> to separate lyric phrases · 用 <code>|</code> 分隔歌词乐句"
|
| 607 |
-
"</center>",
|
| 608 |
-
)
|
| 609 |
|
| 610 |
return demo
|
| 611 |
|
|
|
|
| 274 |
margin: auto !important;
|
| 275 |
}
|
| 276 |
|
| 277 |
+
/* ---------- Badge links: no underline, no gap artifacts ---------- */
|
| 278 |
+
#app-header .badges a {
|
| 279 |
+
text-decoration: none !important;
|
| 280 |
+
display: inline-block;
|
| 281 |
+
line-height: 0;
|
| 282 |
+
margin: 3px 2px;
|
| 283 |
+
}
|
| 284 |
+
#app-header .badges a img,
|
| 285 |
+
#app-header .badges > img {
|
| 286 |
+
display: inline-block;
|
| 287 |
+
vertical-align: middle;
|
| 288 |
+
margin: 0;
|
| 289 |
+
}
|
| 290 |
+
#app-header .badges {
|
| 291 |
+
line-height: 1.8;
|
| 292 |
+
}
|
| 293 |
+
|
| 294 |
/* ---------- Header / 头部 ---------- */
|
| 295 |
#app-header {
|
| 296 |
text-align: center;
|
|
|
|
| 391 |
HEADER_HTML = """
|
| 392 |
<div id="app-header" align="center">
|
| 393 |
<h1>
|
| 394 |
+
🎤 YingMusic-Singer: Controllable Singing Voice Synthesis with Flexible Lyric Manipulation and Annotation-free Melody Guidance
|
|
|
|
| 395 |
</h1>
|
| 396 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 397 |
<div class="badges" style="margin: 10px 0;">
|
| 398 |
<img src="https://img.shields.io/badge/Python-3.10-3776AB?logo=python&logoColor=white" alt="Python">
|
| 399 |
<img src="https://img.shields.io/badge/License-CC%20BY--NC--SA%204.0-lightgrey" alt="License">
|
|
|
|
| 500 |
lines=5,
|
| 501 |
)
|
| 502 |
|
| 503 |
+
# ---------------------------------------------------------------------------
|
| 504 |
+
# Build the Gradio UI / 构建界面
|
| 505 |
+
# ---------------------------------------------------------------------------
|
| 506 |
+
def build_ui():
|
| 507 |
+
with gr.Blocks(
|
| 508 |
+
css=CUSTOM_CSS, title="YingMusic Singer", theme=gr.themes.Base()
|
| 509 |
+
) as demo:
|
| 510 |
+
|
| 511 |
+
# ---- Header ----
|
| 512 |
+
gr.HTML(HEADER_HTML)
|
| 513 |
+
gr.HTML("<hr style='border-color:#30363d; margin: 8px 0 18px;'>")
|
| 514 |
+
|
| 515 |
# ================================================================
|
| 516 |
+
# ROW 1 – 音频输入 + 歌词
|
| 517 |
# ================================================================
|
| 518 |
+
with gr.Row(equal_height=True):
|
| 519 |
+
with gr.Column(scale=1):
|
| 520 |
+
gr.Markdown("#### 🎙️ 音频输入 / Audio Inputs", elem_classes="section-title")
|
| 521 |
+
ref_audio = gr.Audio(
|
| 522 |
+
label="参考音频 / Reference Audio(提供音色 / provides timbre)",
|
| 523 |
+
type="filepath",
|
| 524 |
+
)
|
| 525 |
+
melody_audio = gr.Audio(
|
| 526 |
+
label="旋律音频 / Melody Audio(提供旋律与时长 / provides melody & duration)",
|
| 527 |
+
type="filepath",
|
| 528 |
+
)
|
| 529 |
+
with gr.Column(scale=1):
|
| 530 |
+
gr.Markdown("#### ✏️ 歌词 / Lyrics", elem_classes="section-title")
|
| 531 |
+
ref_text = gr.Textbox(
|
| 532 |
+
label="参考音频歌词 / Reference Text",
|
| 533 |
+
placeholder="例如 / e.g.:该体谅的不执着|如果那天我",
|
| 534 |
+
lines=5,
|
| 535 |
+
)
|
| 536 |
+
target_text = gr.Textbox(
|
| 537 |
+
label="目标合成歌词 / Target Text",
|
| 538 |
+
placeholder="例如 / e.g.:好多天|看不完你",
|
| 539 |
+
lines=5,
|
| 540 |
+
)
|
| 541 |
+
|
| 542 |
+
# ================================================================
|
| 543 |
+
# ROW 2 – 预设示例 / Example Presets ← before vocal separation
|
| 544 |
+
# ================================================================
|
| 545 |
+
gr.HTML("<hr style='border-color:#30363d; margin: 16px 0 12px;'>")
|
| 546 |
+
gr.Markdown("#### 🎵 预设示例 / Example Presets", elem_classes="section-title")
|
| 547 |
+
gr.Markdown(
|
| 548 |
+
"<small style='color:#8b949e;'>点击任意行自动填入输入区域 / Click any row to auto-fill the inputs above</small>"
|
| 549 |
+
)
|
| 550 |
+
|
| 551 |
+
# Hidden advanced-param components so gr.Examples can reference them
|
| 552 |
+
# (real sliders rendered inside the accordion below override these values)
|
| 553 |
+
with gr.Row(visible=False):
|
| 554 |
+
_sep_flag_ex = gr.Checkbox(value=True)
|
| 555 |
+
_mix_flag_ex = gr.Checkbox(value=False)
|
| 556 |
+
_sil_ex = gr.Number(value=0.5)
|
| 557 |
+
_tshift_ex = gr.Number(value=0.5)
|
| 558 |
+
_nfe_ex = gr.Number(value=32)
|
| 559 |
+
_cfg_ex = gr.Number(value=3.0)
|
| 560 |
+
_seed_ex = gr.Number(value=-1, precision=0)
|
| 561 |
+
|
| 562 |
+
_example_inputs = [
|
| 563 |
+
ref_audio, melody_audio, ref_text, target_text,
|
| 564 |
+
_sep_flag_ex, _mix_flag_ex,
|
| 565 |
+
_sil_ex, _tshift_ex, _nfe_ex, _cfg_ex, _seed_ex,
|
| 566 |
+
]
|
| 567 |
+
|
| 568 |
+
with gr.Tabs():
|
| 569 |
+
with gr.Tab("🎼 Melody Control"):
|
| 570 |
+
gr.Examples(
|
| 571 |
+
examples=EXAMPLES_MELODY_CONTROL,
|
| 572 |
+
inputs=_example_inputs,
|
| 573 |
+
label="Melody Control Examples",
|
| 574 |
+
examples_per_page=5,
|
| 575 |
+
)
|
| 576 |
+
with gr.Tab("✏️ Lyric Edit"):
|
| 577 |
+
gr.Examples(
|
| 578 |
+
examples=EXAMPLES_LYRIC_EDIT,
|
| 579 |
+
inputs=_example_inputs,
|
| 580 |
+
label="Lyric Edit Examples",
|
| 581 |
+
examples_per_page=5,
|
| 582 |
+
)
|
| 583 |
+
|
| 584 |
+
# ================================================================
|
| 585 |
+
# ROW 3 – 伴奏分离 / Vocal Separation
|
| 586 |
+
# ================================================================
|
| 587 |
+
gr.HTML("<hr style='border-color:#30363d; margin: 16px 0 12px;'>")
|
| 588 |
gr.Markdown("#### 🎚️ 伴奏分离 / Vocal Separation", elem_classes="section-title")
|
| 589 |
with gr.Row():
|
| 590 |
separate_vocals_flag = gr.Checkbox(
|
|
|
|
| 606 |
)
|
| 607 |
|
| 608 |
# ================================================================
|
| 609 |
+
# ROW 4 – 高级参数 / Advanced Parameters (collapsible)
|
| 610 |
# ================================================================
|
| 611 |
with gr.Accordion("⚙️ 高级参数 / Advanced Parameters", open=False):
|
| 612 |
with gr.Row():
|
|
|
|
| 634 |
info="-1 表示随机 / -1 means random",
|
| 635 |
)
|
| 636 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 637 |
# ================================================================
|
| 638 |
# ROW 5 – 合成按钮与输出 / Run & Output
|
| 639 |
# ================================================================
|
|
|
|
| 646 |
elem_id="output-audio",
|
| 647 |
)
|
| 648 |
|
| 649 |
+
# All inputs for the synthesize() call (uses real sliders, not example placeholders)
|
| 650 |
+
_all_inputs = [
|
| 651 |
+
ref_audio, melody_audio, ref_text, target_text,
|
| 652 |
+
separate_vocals_flag, mix_accompaniment_flag,
|
| 653 |
+
sil_len_to_end, t_shift, nfe_step, cfg_strength, seed,
|
| 654 |
+
]
|
| 655 |
+
|
| 656 |
# ================================================================
|
| 657 |
# Event wiring / 事件绑定
|
| 658 |
# ================================================================
|
| 659 |
separate_vocals_flag.change(
|
| 660 |
+
fn=lambda sep: gr.update(interactive=sep, value=False),
|
| 661 |
inputs=[separate_vocals_flag],
|
| 662 |
outputs=[mix_accompaniment_flag],
|
| 663 |
)
|
|
|
|
| 668 |
outputs=output_audio,
|
| 669 |
)
|
| 670 |
|
| 671 |
+
# ---- 页脚:免责声明 / Footer: disclaimer ----
|
| 672 |
gr.HTML(DISCLAIMER_HTML)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 673 |
|
| 674 |
return demo
|
| 675 |
|