File size: 8,360 Bytes
dee8df0 6b1f7f2 dee8df0 6b1f7f2 dee8df0 6b1f7f2 dee8df0 6b1f7f2 dee8df0 6b1f7f2 786959b dee8df0 6b1f7f2 786959b dee8df0 6b1f7f2 7b3fa89 dee8df0 6b1f7f2 dee8df0 786959b 614a4e6 dee8df0 7b3fa89 dee8df0 6b1f7f2 dee8df0 7b3fa89 6b1f7f2 085827b 6c2ab00 085827b 6b1f7f2 dee8df0 6b1f7f2 085827b 6b1f7f2 dee8df0 6b1f7f2 786959b 6b1f7f2 085827b 6b1f7f2 dee8df0 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | """Hum research Space: record, choose a rendering path, hear the result."""
from __future__ import annotations
import gradio as gr
from logic import INSTRUMENTS
from pipeline import generate_all
SOLO_STYLE = (
"instrumental solo {instrument}, clear single melody, intimate dry recording, "
"natural instrumental tone"
)
ARRANGEMENT_STYLE = (
"instrumental chamber pop, {instrument} melody, acoustic bass, "
"brushed drums, soft strings, warm intimate mood"
)
DRUM_STYLE = (
"instrumental {instrument} lead melody, steady acoustic drum kit, "
"kick and snare, closed hi-hat, dry studio recording"
)
def suggest_prompts(instrument: str) -> tuple[str, str, str]:
name = INSTRUMENTS[instrument][1]
return tuple(template.format(instrument=name)
for template in (SOLO_STYLE, DRUM_STYLE, ARRANGEMENT_STYLE))
def run(audio: str | None, instrument: str, solo_style: str, drum_style: str,
arrangement_style: str, seed: int, include_yue: bool, save_recording: bool,
progress: gr.Progress = gr.Progress(track_tqdm=False)):
try:
styles = {"yue_solo": solo_style, "yue_drums": drum_style,
"yue_arrangement": arrangement_style}
for result in generate_all(audio, instrument, styles, int(seed), include_yue,
progress, save_recording=save_recording):
yield result
if result[-1]["complete"] and "recording_archive" in result[-1]["errors"]:
gr.Warning("Запись не сохранилась в приватном архиве; см. детали запуска.")
except Exception as error:
raise gr.Error(str(error)) from error
CSS = """
.gradio-container {max-width: 1000px !important; margin: auto !important;}
#hero {padding: 20px 4px 10px 4px;}
#hero h1 {font-size: clamp(2.5rem, 6vw, 4.5rem); letter-spacing: -.045em; margin: 0;}
#hero p {font-size: 1.08rem; max-width: 720px; line-height: 1.55; color: #566179;}
.note {border: 1px solid #d9e0ed; border-radius: 16px; padding: 14px 18px;
background: linear-gradient(120deg,#f5f7ff,#f1fbfc); color: #3e4b64;}
"""
with gr.Blocks(title="Hum · напев в инструмент", css=CSS, theme=gr.themes.Soft()) as demo:
gr.HTML("""<div id='hero'><h1>Hum <span style='color:#6474db'>♪</span></h1>
<p>Напойте фразу в микрофон или загрузите короткую запись. Один запуск
создаст все варианты: сэмплерные инструменты с исходным временем и три
эксперимента YuE2. Первые результаты появятся до окончания YuE2.</p></div>""")
with gr.Row():
with gr.Column(scale=4):
audio = gr.Audio(label="Ваш напев", sources=["microphone", "upload"],
type="filepath", format=None)
save_recording = gr.Checkbox(
label="Сохранить исходную запись в приватный архив владельца Space",
value=False)
gr.Markdown("Если включить сохранение, исходный файл с микрофона или загрузки "
"останется в приватном архиве Hugging Face после перезапуска Space. "
"Без галочки исходник остаётся лишь во временном хранилище Space "
"до очистки или перезапуска.")
instrument = gr.Dropdown(list(INSTRUMENTS), value="Флейта", label="Инструмент")
include_yue = gr.Checkbox(label="Запустить YuE2 · три генерации (включено по умолчанию)",
value=True)
with gr.Accordion("Настройки YuE2", open=False):
defaults = suggest_prompts("Флейта")
solo_style = gr.Textbox(label="Соло · style", lines=2, value=defaults[0])
drum_style = gr.Textbox(label="Мелодия + барабаны · style", lines=2,
value=defaults[1])
arrangement_style = gr.Textbox(label="Композиция · style", lines=2,
value=defaults[2])
seed = gr.Number(label="Seed", value=4096, precision=0)
go = gr.Button("Создать все варианты", variant="primary", size="lg")
gr.HTML("""<div class='note'><b>Текущая цель:</b> один инструмент и
приблизительно исходное время. Электрогитара и бас используют
записанные сэмплы; регистр баса выбирается автоматически. Обработанные версии
добавляют усиление и лёгкий эффект, но не новые ноты. Барабаны
привязаны к долям SheetSage2. YuE2 может изменить
длительность, добавить человеческие звуки или другие инструменты;
отсутствие вокала не гарантируется. Это публичный Space: записи
обрабатываются на сервере Hugging Face.</div>""")
with gr.Column(scale=6):
with gr.Row():
with gr.Column():
instrument_only = gr.Audio(label="Инструмент · исходный ритм",
interactive=False)
instrument_drums = gr.Audio(label="Инструмент + синтезаторные барабаны",
interactive=False)
contour = gr.Audio(label="Непрерывная высота · synth",
interactive=False)
guitar_clean = gr.Audio(label="Электрогитара · чистая",
interactive=False)
guitar_amp = gr.Audio(label="Электрогитара · усилитель и эффекты",
interactive=False)
bass_clean = gr.Audio(label="Бас · чистый",
interactive=False)
bass_amp = gr.Audio(label="Бас · тёплый усилитель",
interactive=False)
with gr.Column():
yue_solo = gr.Audio(label="YuE2 · соло", interactive=False)
yue_drums = gr.Audio(label="YuE2 · мелодия + барабаны",
interactive=False)
yue_arrangement = gr.Audio(label="YuE2 · композиция",
interactive=False)
with gr.Row():
midi = gr.File(label="Мелодия · MIDI")
drum_midi = gr.File(label="Барабаны · MIDI")
beat_lab = gr.File(label="Доли · LAB")
abc = gr.File(label="Мелодия для YuE2 · ABC")
details = gr.JSON(label="Детали запуска")
instrument.change(suggest_prompts, inputs=instrument,
outputs=[solo_style, drum_style, arrangement_style])
go.click(run, inputs=[audio, instrument, solo_style, drum_style,
arrangement_style, seed, include_yue, save_recording],
outputs=[instrument_only, instrument_drums, contour,
guitar_clean, guitar_amp, bass_clean, bass_amp,
yue_solo, yue_drums, yue_arrangement,
midi, drum_midi, beat_lab, abc, details], show_progress="full")
if __name__ == "__main__":
demo.queue(max_size=8, default_concurrency_limit=1)
demo.launch(server_name="0.0.0.0", server_port=7860, show_error=True)
|