From 057e7280917c9951616a42474aa58e69e080ad81 Mon Sep 17 00:00:00 2001 From: Steve Calcott Date: Tue, 15 Sep 2026 11:55:08 +0000 Subject: [PATCH] Add speech enhancement as a pipeline step in the voice editor Real reference clips are often cheap-mic/phone-call quality. Adds AuK's dedicated Speech Enhancement task (denoise+dereverb, or a telephone-effect-specific variant) as a new dropdown, applied first in the edit chain - before emotion/pitch/speed/custom - since character edits on noisy source audio just carry the noise through. Found useful while iterating on real character voices for a sibling project (the-service-station) using this exact tool. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01Y1oQ4h4WE4R9KRvMQLr5Ey --- webui/app.py | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/webui/app.py b/webui/app.py index 922a59d..c95345e 100644 --- a/webui/app.py +++ b/webui/app.py @@ -151,11 +151,35 @@ def _history_label(history: list) -> str: return f"Edit history: {len(history) - 1} edit(s) applied on top of the original reference." -def apply_edit(current_ref: str, history: list, emotion: str, pitch: str, speed: str, custom_instruction: str): +ENHANCE_INSTRUCTIONS = { + "none": None, + "General (denoise + dereverb)": ( + "Preserve all speakers, remove noise and reverberation, and output " + "clean speech of the same length." + ), + "Telephone/call recording": ( + "Repair the telephone effect and restore natural, clear speech." + ), +} + + +def apply_edit( + current_ref: str, + history: list, + enhance: str, + emotion: str, + pitch: str, + speed: str, + custom_instruction: str, +): if not current_ref: raise gr.Error("Set a voice reference first (upload, strip with Demucs, or use a previous edit).") instructions = [] + # Enhancement goes first when picked - clean the recording up before any + # character/accent editing, not after (garbage in, garbage timbre-edited). + if enhance and ENHANCE_INSTRUCTIONS.get(enhance): + instructions.append(ENHANCE_INSTRUCTIONS[enhance]) if emotion and emotion != "none": instructions.append(f"Change the emotion to {emotion}.") if pitch and pitch != "none": @@ -167,7 +191,7 @@ def apply_edit(current_ref: str, history: list, emotion: str, pitch: str, speed: instructions.append(custom_instruction.strip()) if not instructions: - raise gr.Error("Pick at least one edit (emotion / pitch / speed / custom instruction).") + raise gr.Error("Pick at least one edit (enhance / emotion / pitch / speed / custom instruction).") _free_comfyui_memory() ref = current_ref @@ -270,6 +294,10 @@ with gr.Blocks(title="Audio-demo pipeline studio") as demo: gr.Markdown("## 2. Voice editor (AuK)") current_ref_audio = gr.Audio(label="Current reference", type="filepath", interactive=False) history_label = gr.Markdown("No reference set yet.") + enhance_dd = gr.Dropdown( + list(ENHANCE_INSTRUCTIONS.keys()), value="none", + label="Enhance (denoise/dereverb/restore) - runs first, before character edits", + ) emotion_dd = gr.Dropdown(["none"] + EMOTIONS, value="none", label="Emotion") pitch_dd = gr.Dropdown(["none"] + PITCH_OPTIONS, value="none", label="Pitch (semitones)") speed_dd = gr.Dropdown(["none"] + SPEED_OPTIONS, value="none", label="Speed") @@ -309,7 +337,7 @@ with gr.Blocks(title="Audio-demo pipeline studio") as demo: ) apply_btn.click( apply_edit, - inputs=[current_ref_audio, history_state, emotion_dd, pitch_dd, speed_dd, custom_instruction], + inputs=[current_ref_audio, history_state, enhance_dd, emotion_dd, pitch_dd, speed_dd, custom_instruction], outputs=[current_ref_audio, history_state, history_label], ) undo_btn.click(