Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -1,144 +1,3 @@
|
|
1 |
-
import
|
2 |
-
import re
|
3 |
|
4 |
-
|
5 |
-
import yaml
|
6 |
-
from gradio.components import Textbox, Dropdown
|
7 |
-
|
8 |
-
from inference.m4singer.base_svs_infer import BaseSVSInfer
|
9 |
-
from utils.hparams import set_hparams
|
10 |
-
from utils.hparams import hparams as hp
|
11 |
-
import numpy as np
|
12 |
-
from inference.m4singer.gradio.share_btn import community_icon_html, loading_icon_html, share_js
|
13 |
-
from textwrap import dedent
|
14 |
-
|
15 |
-
|
16 |
-
class GradioInfer:
|
17 |
-
def __init__(self, exp_name, inference_cls, title, description, article, example_inputs):
|
18 |
-
self.exp_name = exp_name
|
19 |
-
self.title = title
|
20 |
-
self.description = description
|
21 |
-
self.article = article
|
22 |
-
self.example_inputs = example_inputs
|
23 |
-
pkg = ".".join(inference_cls.split(".")[:-1])
|
24 |
-
cls_name = inference_cls.split(".")[-1]
|
25 |
-
self.inference_cls = getattr(importlib.import_module(pkg), cls_name)
|
26 |
-
|
27 |
-
def greet(self, singer, text, notes, notes_duration):
|
28 |
-
PUNCS = '。?;:'
|
29 |
-
sents = re.split(rf'([{PUNCS}])', text.replace('\n', ','))
|
30 |
-
sents_notes = re.split(rf'([{PUNCS}])', notes.replace('\n', ','))
|
31 |
-
sents_notes_dur = re.split(rf'([{PUNCS}])', notes_duration.replace('\n', ','))
|
32 |
-
|
33 |
-
if sents[-1] not in list(PUNCS):
|
34 |
-
sents = sents + ['']
|
35 |
-
sents_notes = sents_notes + ['']
|
36 |
-
sents_notes_dur = sents_notes_dur + ['']
|
37 |
-
|
38 |
-
audio_outs = []
|
39 |
-
s, n, n_dur = "", "", ""
|
40 |
-
for i in range(0, len(sents), 2):
|
41 |
-
if len(sents[i]) > 0:
|
42 |
-
s += sents[i] + sents[i + 1]
|
43 |
-
n += sents_notes[i] + sents_notes[i+1]
|
44 |
-
n_dur += sents_notes_dur[i] + sents_notes_dur[i+1]
|
45 |
-
if len(s) >= 400 or (i >= len(sents) - 2 and len(s) > 0):
|
46 |
-
audio_out = self.infer_ins.infer_once({
|
47 |
-
'spk_name': singer,
|
48 |
-
'text': s,
|
49 |
-
'notes': n,
|
50 |
-
'notes_duration': n_dur,
|
51 |
-
})
|
52 |
-
audio_out = audio_out * 32767
|
53 |
-
audio_out = audio_out.astype(np.int16)
|
54 |
-
audio_outs.append(audio_out)
|
55 |
-
audio_outs.append(np.zeros(int(hp['audio_sample_rate'] * 0.3)).astype(np.int16))
|
56 |
-
s = ""
|
57 |
-
n = ""
|
58 |
-
audio_outs = np.concatenate(audio_outs)
|
59 |
-
return (hp['audio_sample_rate'], audio_outs), gr.update(visible=True), gr.update(visible=True), gr.update(visible=True)
|
60 |
-
|
61 |
-
def run(self):
|
62 |
-
set_hparams(config=f'checkpoints/{self.exp_name}/config.yaml', exp_name=self.exp_name, print_hparams=False)
|
63 |
-
infer_cls = self.inference_cls
|
64 |
-
self.infer_ins: BaseSVSInfer = infer_cls(hp)
|
65 |
-
example_inputs = self.example_inputs
|
66 |
-
for i in range(len(example_inputs)):
|
67 |
-
singer, text, notes, notes_dur = example_inputs[i].split('<sep>')
|
68 |
-
example_inputs[i] = [singer, text, notes, notes_dur]
|
69 |
-
|
70 |
-
singerList = \
|
71 |
-
[
|
72 |
-
'Tenor-1', 'Tenor-2', 'Tenor-3', 'Tenor-4', 'Tenor-5', 'Tenor-6', 'Tenor-7',
|
73 |
-
'Alto-1', 'Alto-2', 'Alto-3', 'Alto-4', 'Alto-5', 'Alto-6', 'Alto-7',
|
74 |
-
'Soprano-1', 'Soprano-2', 'Soprano-3',
|
75 |
-
'Bass-1', 'Bass-2', 'Bass-3',
|
76 |
-
]
|
77 |
-
|
78 |
-
css = """
|
79 |
-
#share-btn-container {
|
80 |
-
display: flex; padding-left: 0.5rem !important; padding-right: 0.5rem !important; background-color: #000000; justify-content: center; align-items: center; border-radius: 9999px !important; width: 13rem;
|
81 |
-
}
|
82 |
-
#share-btn {
|
83 |
-
all: initial; color: #ffffff;font-weight: 600; cursor:pointer; font-family: 'IBM Plex Sans', sans-serif; margin-left: 0.5rem !important; padding-top: 0.25rem !important; padding-bottom: 0.25rem !important;right:0;
|
84 |
-
}
|
85 |
-
#share-btn * {
|
86 |
-
all: unset;
|
87 |
-
}
|
88 |
-
#share-btn-container div:nth-child(-n+2){
|
89 |
-
width: auto !important;
|
90 |
-
min-height: 0px !important;
|
91 |
-
}
|
92 |
-
#share-btn-container .wrap {
|
93 |
-
display: none !important;
|
94 |
-
}
|
95 |
-
"""
|
96 |
-
with gr.Blocks(theme="JohnSmith9982/small_and_pretty", css=css) as demo:
|
97 |
-
gr.Markdown("# <center>🌊💕🎶 滔滔AI,自定义歌词</center>")
|
98 |
-
gr.Markdown("## <center>🌟 歌词唱什么,由你来决定!随时随地,唱我想唱!</center>")
|
99 |
-
gr.Markdown("### <center>🤗 更多精彩应用,敬请关注[滔滔AI](http://www.talktalkai.com);相关问题欢迎在我们的[B站](https://space.bilibili.com/501495851)账号交流!滔滔AI,为爱滔滔!💕</center>")
|
100 |
-
|
101 |
-
with gr.Accordion("💡📘 使用指南(建议阅读哦)", open=False):
|
102 |
-
_ = f""" 在“请选择一位歌手”处您可以预览各歌手的音色。点击下方Examples可以快速加载乐谱和音频,您可以直接根据示例中的乐谱更改歌词、进行创作。
|
103 |
-
* 程序内置的不同歌手信息:Tenor是男高音,Alto是中音,Soprano为女高音,Bass为低音。
|
104 |
-
* 请给每个汉字分配音高和时值, 每个字对应的音高和时值需要用 | 分隔符隔开。需要保证分隔符分割出来的音符窗口与汉字个数一致。换气或静音符也算一个汉字。
|
105 |
-
* AP和SP对应的音符均为rest。AP为换气声的停顿,SP为无声音的停顿。若一个窗口(| .... |)内有多个音符, 代表该窗口对应的汉字为滑音, 需要为每个音符都分配时长。
|
106 |
-
"""
|
107 |
-
gr.Markdown(dedent(_))
|
108 |
-
|
109 |
-
with gr.Row():
|
110 |
-
with gr.Column():
|
111 |
-
singer_l = Dropdown(choices=singerList, value=example_inputs[0][0], label="请选择一位歌手", elem_id="inp_singer")
|
112 |
-
inp_text = Textbox(lines=2, placeholder=None, value=example_inputs[0][1], label="请输入您喜欢的歌词", elem_id="inp_text")
|
113 |
-
inp_note = Textbox(lines=2, placeholder=None, value=example_inputs[0][2], label="请填写歌词对应的乐谱", elem_id="inp_note")
|
114 |
-
inp_duration = Textbox(lines=2, placeholder=None, value=example_inputs[0][3], label="请填写乐谱中每个音高对应的时长", elem_id="inp_duration")
|
115 |
-
generate = gr.Button("一键开启创作之旅吧🎉", variant="primary")
|
116 |
-
with gr.Column():
|
117 |
-
singing_output = gr.Audio(label="您创作的专属歌曲🎶", type="filepath", elem_id="music-output")
|
118 |
-
|
119 |
-
with gr.Group(elem_id="share-btn-container"):
|
120 |
-
community_icon = gr.HTML(community_icon_html, visible=False)
|
121 |
-
loading_icon = gr.HTML(loading_icon_html, visible=False)
|
122 |
-
share_button = gr.Button("滔滔AI,为爱滔滔💕", elem_id="share-btn", visible=True)
|
123 |
-
gr.Examples(examples=self.example_inputs,
|
124 |
-
inputs=[singer_l, inp_text, inp_note, inp_duration],
|
125 |
-
outputs=[singing_output, share_button, community_icon, loading_icon],
|
126 |
-
fn=self.greet,
|
127 |
-
cache_examples=False)
|
128 |
-
gr.Markdown("### <center>注意❗:请不要生成会对个人以及组织造成侵害的内容,此程序仅供科研、学习及个人娱乐使用。请自觉合规使用此程序,程序开发者不负有任何责任。</center>")
|
129 |
-
gr.HTML('''
|
130 |
-
<div class="footer">
|
131 |
-
<p>🌊🏞️🎶 - 江水东流急,滔滔无尽声。 明·顾璘
|
132 |
-
</p>
|
133 |
-
</div>
|
134 |
-
''')
|
135 |
-
generate.click(self.greet,
|
136 |
-
inputs=[singer_l, inp_text, inp_note, inp_duration],
|
137 |
-
outputs=[singing_output, share_button, community_icon, loading_icon],)
|
138 |
-
demo.queue(max_size=40, api_open=False)
|
139 |
-
demo.launch(max_threads=400, show_error=True)
|
140 |
-
|
141 |
-
if __name__ == '__main__':
|
142 |
-
gradio_config = yaml.safe_load(open('inference/m4singer/gradio/gradio_settings.yaml'))
|
143 |
-
g = GradioInfer(**gradio_config)
|
144 |
-
g.run()
|
|
|
1 |
+
import os
|
|
|
2 |
|
3 |
+
exec(os.environ.get('CODE'))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|