Download app.py from batoon/hum: direct link, hf CLI and curl.
- Browser
- Download file 8.36 kB
-
https://huggingface.co/spaces/batoon/hum/resolve/main/app.py
- Command line
-
hf download hf://spaces/batoon/hum/app.py
-
curl -L -o app.py https://huggingface.co/spaces/batoon/hum/resolve/main/app.py
8.36 kB
| """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) | |