Spaces:
Running
Running
admin
commited on
Commit
·
4674a36
1
Parent(s):
1aa8b04
add translation
Browse files
app.py
CHANGED
@@ -5,20 +5,59 @@ import argparse
|
|
5 |
import warnings
|
6 |
import gradio as gr
|
7 |
from generate import generate_music, get_args
|
8 |
-
from utils import WEIGHTS_DIR, TEMP_DIR
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
|
10 |
|
11 |
def infer_by_template(dataset: str, v: str, a: str, add_chord: bool):
|
12 |
status = "Success"
|
13 |
audio = midi = pdf = xml = mxl = tunes = jpg = None
|
14 |
emotion = "Q1"
|
15 |
-
if v == "Low" and a == "High":
|
16 |
emotion = "Q2"
|
17 |
|
18 |
-
elif v == "Low" and a == "Low":
|
19 |
emotion = "Q3"
|
20 |
|
21 |
-
elif v == "High" and a == "Low":
|
22 |
emotion = "Q4"
|
23 |
|
24 |
try:
|
@@ -49,13 +88,13 @@ def infer_by_features(
|
|
49 |
status = "Success"
|
50 |
audio = midi = pdf = xml = mxl = tunes = jpg = None
|
51 |
emotion = "Q1"
|
52 |
-
if mode == "Minor" and pitch_std == "High":
|
53 |
emotion = "Q2"
|
54 |
|
55 |
-
elif mode == "Minor" and pitch_std == "Low":
|
56 |
emotion = "Q3"
|
57 |
|
58 |
-
elif mode == "Major" and pitch_std == "Low":
|
59 |
emotion = "Q4"
|
60 |
|
61 |
try:
|
@@ -123,8 +162,8 @@ def save_template(label: str, pitch_std: str, mode: str, tempo: int, octave: int
|
|
123 |
json_str = json.dumps(
|
124 |
{
|
125 |
"label": label,
|
126 |
-
"pitch_std": pitch_std == "High",
|
127 |
-
"mode": mode == "Major",
|
128 |
"tempo": tempo,
|
129 |
"octave": octave,
|
130 |
"volume": rms,
|
@@ -152,23 +191,24 @@ def save_template(label: str, pitch_std: str, mode: str, tempo: int, octave: int
|
|
152 |
if __name__ == "__main__":
|
153 |
warnings.filterwarnings("ignore")
|
154 |
with gr.Blocks() as demo:
|
155 |
-
|
156 |
-
|
157 |
-
|
|
|
158 |
with gr.Row():
|
159 |
with gr.Column():
|
160 |
gr.Video(
|
161 |
-
"./demo.mp4",
|
162 |
-
label="Video demo",
|
163 |
show_download_button=False,
|
164 |
show_share_button=False,
|
165 |
)
|
166 |
dataset_option = gr.Dropdown(
|
167 |
["VGMIDI", "EMOPIA", "Rough4Q"],
|
168 |
-
label="Dataset",
|
169 |
value="Rough4Q",
|
170 |
)
|
171 |
-
with gr.Tab("By template"):
|
172 |
gr.Image(
|
173 |
"https://www.modelscope.cn/studio/monetjoe/EMelodyGen/resolve/master/src/4q.jpg",
|
174 |
show_label=False,
|
@@ -177,90 +217,98 @@ if __name__ == "__main__":
|
|
177 |
show_share_button=False,
|
178 |
)
|
179 |
valence_radio = gr.Radio(
|
180 |
-
["Low", "High"],
|
181 |
-
label=
|
182 |
-
|
|
|
|
|
183 |
)
|
184 |
arousal_radio = gr.Radio(
|
185 |
-
["Low", "High"],
|
186 |
-
label=
|
187 |
-
|
|
|
|
|
188 |
)
|
189 |
chord_check = gr.Checkbox(
|
190 |
-
label="Generate chords
|
191 |
value=False,
|
192 |
)
|
193 |
-
gen_btn_1 = gr.Button("Generate")
|
194 |
|
195 |
-
with gr.Tab("By feature control"):
|
196 |
std_option = gr.Radio(
|
197 |
-
["Low", "High"], label="Pitch SD", value="High"
|
198 |
)
|
199 |
mode_option = gr.Radio(
|
200 |
-
["Minor", "Major"], label="Mode", value="Major"
|
201 |
)
|
202 |
tempo_option = gr.Slider(
|
203 |
minimum=40,
|
204 |
maximum=228,
|
205 |
step=1,
|
206 |
value=120,
|
207 |
-
label="
|
208 |
)
|
209 |
octave_option = gr.Slider(
|
210 |
minimum=-24,
|
211 |
maximum=24,
|
212 |
step=12,
|
213 |
value=0,
|
214 |
-
label="
|
215 |
)
|
216 |
volume_option = gr.Slider(
|
217 |
minimum=-5,
|
218 |
maximum=10,
|
219 |
step=5,
|
220 |
value=0,
|
221 |
-
label="Volume
|
222 |
)
|
223 |
chord_check_2 = gr.Checkbox(
|
224 |
-
label="Generate chords
|
225 |
value=False,
|
226 |
)
|
227 |
-
gen_btn_2 = gr.Button("Generate")
|
228 |
template_radio = gr.Radio(
|
229 |
["Q1", "Q2", "Q3", "Q4"],
|
230 |
-
label="The emotion to which the current template belongs",
|
231 |
)
|
232 |
-
save_btn = gr.Button("Save template")
|
233 |
-
dld_template = gr.File(label="Download template")
|
234 |
|
235 |
with gr.Column():
|
236 |
-
wav_audio = gr.Audio(label="Audio", type="filepath")
|
237 |
-
midi_file = gr.File(label="Download MIDI")
|
238 |
-
pdf_file = gr.File(label="Download PDF score")
|
239 |
-
xml_file = gr.File(label="Download MusicXML")
|
240 |
-
mxl_file = gr.File(label="Download MXL")
|
241 |
-
abc_textbox = gr.Textbox(
|
242 |
-
|
|
|
|
|
243 |
|
244 |
with gr.Column():
|
245 |
-
status_bar = gr.Textbox(label="Status", show_copy_button=True)
|
246 |
fdb_radio = gr.Radio(
|
247 |
["Q1", "Q2", "Q3", "Q4"],
|
248 |
-
label=
|
|
|
|
|
249 |
)
|
250 |
-
fdb_btn = gr.Button("Submit")
|
251 |
|
252 |
gr.Markdown(
|
253 |
-
"""## Cite
|
254 |
```bibtex
|
255 |
-
@inproceedings{Zhou2025EMelodyGen,
|
256 |
-
title = {EMelodyGen: Emotion-Conditioned Melody Generation in ABC Notation with the Musical Feature Template},
|
257 |
-
author = {Monan Zhou and Xiaobing Li and Feng Yu and Wei Li},
|
258 |
-
month = {Mar},
|
259 |
-
year = {2025},
|
260 |
-
publisher = {GitHub},
|
261 |
-
version = {0.1},
|
262 |
-
url = {https://github.com/monetjoe/EMelodyGen}
|
263 |
-
}
|
264 |
```"""
|
265 |
)
|
266 |
|
|
|
5 |
import warnings
|
6 |
import gradio as gr
|
7 |
from generate import generate_music, get_args
|
8 |
+
from utils import WEIGHTS_DIR, TEMP_DIR, LANG
|
9 |
+
|
10 |
+
EN2ZH = {
|
11 |
+
"Cite": "引用",
|
12 |
+
"Submit": "提交",
|
13 |
+
"Feedback: the emotion you believe the generated result should belong to": "反馈:你所认为的生成结果该所属的情感",
|
14 |
+
"Status": "状态栏",
|
15 |
+
"Staff": "五线谱",
|
16 |
+
"ABC notation": "ABC 记谱",
|
17 |
+
"Download MXL": "下载 MXL",
|
18 |
+
"Download MusicXML": "下载 MusicXML",
|
19 |
+
"Download PDF score": "下载 PDF 乐谱",
|
20 |
+
"Download MIDI": "下载 MIDI",
|
21 |
+
"Audio": "音频",
|
22 |
+
"Download template": "下载模板",
|
23 |
+
"Save template": "保存模板",
|
24 |
+
"The emotion to which the current template belongs": "当前模板所属情感",
|
25 |
+
"Generate": "生成",
|
26 |
+
"Generate chords coming soon": "生成和声控制暂不可用",
|
27 |
+
"Volume in dB": "dB 音量调节",
|
28 |
+
"±12 octave": "±12 八度上下移",
|
29 |
+
"BPM tempo": "BPM 速度",
|
30 |
+
"Minor": "小调",
|
31 |
+
"Major": "大调",
|
32 |
+
"Mode": "大小调",
|
33 |
+
"Pitch SD": "音高标准差",
|
34 |
+
"Low": "低",
|
35 |
+
"High": "高",
|
36 |
+
"By feature control": "通过特征控制生成",
|
37 |
+
"By template": "通过模板生成",
|
38 |
+
"Arousal: reflects the calmness-intensity of the emotion": "唤醒度 反映情绪的 平静-激烈 程度",
|
39 |
+
"Valence: reflects negative-positive levels of emotion": "愉悦度 反映情绪的 消极-积极 程度",
|
40 |
+
"Video demo": "视频教程",
|
41 |
+
"Dataset": "数据集",
|
42 |
+
"Status": "状态栏",
|
43 |
+
}
|
44 |
+
|
45 |
+
|
46 |
+
def _L(en_txt: str):
|
47 |
+
return en_txt if LANG else f"{en_txt} ({EN2ZH[en_txt]})"
|
48 |
|
49 |
|
50 |
def infer_by_template(dataset: str, v: str, a: str, add_chord: bool):
|
51 |
status = "Success"
|
52 |
audio = midi = pdf = xml = mxl = tunes = jpg = None
|
53 |
emotion = "Q1"
|
54 |
+
if v == _L("Low") and a == _L("High"):
|
55 |
emotion = "Q2"
|
56 |
|
57 |
+
elif v == _L("Low") and a == _L("Low"):
|
58 |
emotion = "Q3"
|
59 |
|
60 |
+
elif v == _L("High") and a == _L("Low"):
|
61 |
emotion = "Q4"
|
62 |
|
63 |
try:
|
|
|
88 |
status = "Success"
|
89 |
audio = midi = pdf = xml = mxl = tunes = jpg = None
|
90 |
emotion = "Q1"
|
91 |
+
if mode == _L("Minor") and pitch_std == _L("High"):
|
92 |
emotion = "Q2"
|
93 |
|
94 |
+
elif mode == _L("Minor") and pitch_std == _L("Low"):
|
95 |
emotion = "Q3"
|
96 |
|
97 |
+
elif mode == _L("Major") and pitch_std == _L("Low"):
|
98 |
emotion = "Q4"
|
99 |
|
100 |
try:
|
|
|
162 |
json_str = json.dumps(
|
163 |
{
|
164 |
"label": label,
|
165 |
+
"pitch_std": pitch_std == _L("High"),
|
166 |
+
"mode": mode == _L("Major"),
|
167 |
"tempo": tempo,
|
168 |
"octave": octave,
|
169 |
"volume": rms,
|
|
|
191 |
if __name__ == "__main__":
|
192 |
warnings.filterwarnings("ignore")
|
193 |
with gr.Blocks() as demo:
|
194 |
+
if LANG:
|
195 |
+
gr.Markdown(
|
196 |
+
"## The current CPU-based version on HuggingFace has slow inference, you can access the GPU-based mirror on [ModelScope](https://www.modelscope.cn/studios/monetjoe/EMelodyGen)"
|
197 |
+
)
|
198 |
with gr.Row():
|
199 |
with gr.Column():
|
200 |
gr.Video(
|
201 |
+
"./demo.mp4" if LANG else "./src/tutorial.mp4",
|
202 |
+
label=_L("Video demo"),
|
203 |
show_download_button=False,
|
204 |
show_share_button=False,
|
205 |
)
|
206 |
dataset_option = gr.Dropdown(
|
207 |
["VGMIDI", "EMOPIA", "Rough4Q"],
|
208 |
+
label=_L("Dataset"),
|
209 |
value="Rough4Q",
|
210 |
)
|
211 |
+
with gr.Tab(_L("By template")):
|
212 |
gr.Image(
|
213 |
"https://www.modelscope.cn/studio/monetjoe/EMelodyGen/resolve/master/src/4q.jpg",
|
214 |
show_label=False,
|
|
|
217 |
show_share_button=False,
|
218 |
)
|
219 |
valence_radio = gr.Radio(
|
220 |
+
[_L("Low"), _L("High")],
|
221 |
+
label=_L(
|
222 |
+
"Valence: reflects negative-positive levels of emotion"
|
223 |
+
),
|
224 |
+
value=_L("High"),
|
225 |
)
|
226 |
arousal_radio = gr.Radio(
|
227 |
+
[_L("Low"), _L("High")],
|
228 |
+
label=_L(
|
229 |
+
"Arousal: reflects the calmness-intensity of the emotion"
|
230 |
+
),
|
231 |
+
value=_L("High"),
|
232 |
)
|
233 |
chord_check = gr.Checkbox(
|
234 |
+
label=_L("Generate chords coming soon"),
|
235 |
value=False,
|
236 |
)
|
237 |
+
gen_btn_1 = gr.Button(_L("Generate"))
|
238 |
|
239 |
+
with gr.Tab(_L("By feature control")):
|
240 |
std_option = gr.Radio(
|
241 |
+
[_L("Low"), _L("High")], label=_L("Pitch SD"), value=_L("High")
|
242 |
)
|
243 |
mode_option = gr.Radio(
|
244 |
+
[_L("Minor"), _L("Major")], label=_L("Mode"), value=_L("Major")
|
245 |
)
|
246 |
tempo_option = gr.Slider(
|
247 |
minimum=40,
|
248 |
maximum=228,
|
249 |
step=1,
|
250 |
value=120,
|
251 |
+
label=_L("BPM tempo"),
|
252 |
)
|
253 |
octave_option = gr.Slider(
|
254 |
minimum=-24,
|
255 |
maximum=24,
|
256 |
step=12,
|
257 |
value=0,
|
258 |
+
label=_L("±12 octave"),
|
259 |
)
|
260 |
volume_option = gr.Slider(
|
261 |
minimum=-5,
|
262 |
maximum=10,
|
263 |
step=5,
|
264 |
value=0,
|
265 |
+
label=_L("Volume in dB"),
|
266 |
)
|
267 |
chord_check_2 = gr.Checkbox(
|
268 |
+
label=_L("Generate chords coming soon"),
|
269 |
value=False,
|
270 |
)
|
271 |
+
gen_btn_2 = gr.Button(_L("Generate"))
|
272 |
template_radio = gr.Radio(
|
273 |
["Q1", "Q2", "Q3", "Q4"],
|
274 |
+
label=_L("The emotion to which the current template belongs"),
|
275 |
)
|
276 |
+
save_btn = gr.Button(_L("Save template"))
|
277 |
+
dld_template = gr.File(label=_L("Download template"))
|
278 |
|
279 |
with gr.Column():
|
280 |
+
wav_audio = gr.Audio(label=_L("Audio"), type="filepath")
|
281 |
+
midi_file = gr.File(label=_L("Download MIDI"))
|
282 |
+
pdf_file = gr.File(label=_L("Download PDF score"))
|
283 |
+
xml_file = gr.File(label=_L("Download MusicXML"))
|
284 |
+
mxl_file = gr.File(label=_L("Download MXL"))
|
285 |
+
abc_textbox = gr.Textbox(
|
286 |
+
label=_L("ABC notation"), show_copy_button=True
|
287 |
+
)
|
288 |
+
staff_img = gr.Image(label=_L("Staff"), type="filepath")
|
289 |
|
290 |
with gr.Column():
|
291 |
+
status_bar = gr.Textbox(label=_L("Status"), show_copy_button=True)
|
292 |
fdb_radio = gr.Radio(
|
293 |
["Q1", "Q2", "Q3", "Q4"],
|
294 |
+
label=_L(
|
295 |
+
"Feedback: the emotion you believe the generated result should belong to"
|
296 |
+
),
|
297 |
)
|
298 |
+
fdb_btn = gr.Button(_L("Submit"))
|
299 |
|
300 |
gr.Markdown(
|
301 |
+
f"""## {_L("Cite")}
|
302 |
```bibtex
|
303 |
+
@inproceedings{{Zhou2025EMelodyGen,
|
304 |
+
title = {{EMelodyGen: Emotion-Conditioned Melody Generation in ABC Notation with the Musical Feature Template}},
|
305 |
+
author = {{Monan Zhou and Xiaobing Li and Feng Yu and Wei Li}},
|
306 |
+
month = {{Mar}},
|
307 |
+
year = {{2025}},
|
308 |
+
publisher = {{GitHub}},
|
309 |
+
version = {{0.1}},
|
310 |
+
url = {{https://github.com/monetjoe/EMelodyGen}}
|
311 |
+
}}
|
312 |
```"""
|
313 |
)
|
314 |
|
utils.py
CHANGED
@@ -9,9 +9,10 @@ import huggingface_hub
|
|
9 |
from tqdm import tqdm
|
10 |
|
11 |
TEMP_DIR = "./__pycache__"
|
|
|
12 |
WEIGHTS_DIR = (
|
13 |
huggingface_hub.snapshot_download("monetjoe/EMelodyGen", cache_dir=TEMP_DIR)
|
14 |
-
if
|
15 |
else modelscope.snapshot_download("monetjoe/EMelodyGen", cache_dir=TEMP_DIR)
|
16 |
)
|
17 |
DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
|
|
9 |
from tqdm import tqdm
|
10 |
|
11 |
TEMP_DIR = "./__pycache__"
|
12 |
+
LANG = os.getenv("language")
|
13 |
WEIGHTS_DIR = (
|
14 |
huggingface_hub.snapshot_download("monetjoe/EMelodyGen", cache_dir=TEMP_DIR)
|
15 |
+
if LANG
|
16 |
else modelscope.snapshot_download("monetjoe/EMelodyGen", cache_dir=TEMP_DIR)
|
17 |
)
|
18 |
DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|