ultimate-rvc / src /frontend /tabs /multi_step_generation.py
Blane187's picture
Upload folder using huggingface_hub
c8be32d verified
"""
This module contains the code for the "Multi-step generation" tab.
"""
from typings.extra import TransferUpdateArgs
from functools import partial
import gradio as gr
from backend.generate_song_cover import (
convert_vocals,
dereverb_vocals,
mix_song_cover,
pitch_shift_background,
postprocess_vocals,
retrieve_song,
separate_main_vocals,
separate_vocals,
)
from frontend.common import (
PROGRESS_BAR,
EventArgs,
exception_harness,
setup_consecutive_event_listeners_with_toggled_interactivity,
show_hop_slider,
toggle_visible_component,
update_cached_input_songs,
update_output_audio,
update_song_cover_name,
update_value,
)
def _update_audio(
num_components: int, output_indices: list[int], file_path: str
) -> gr.Audio | tuple[gr.Audio, ...]:
"""
Update the value of a subset of `Audio` components to the given audio file path.
Parameters
----------
num_components : int
The total number of `Audio` components under consideration.
output_indices : list[int]
Indices of `Audio` components to update the value for.
file_path : str
Path pointing to an audio track to update the indexed `Audio` components with.
Returns
-------
gr.Audio | tuple[gr.Audio, ...]
Each `Audio` component under consideration
with indexed components updated to the given audio file path.
"""
update_args: list[TransferUpdateArgs] = [{} for _ in range(num_components)]
for index in output_indices:
update_args[index]["value"] = file_path
if num_components == 1:
return gr.Audio(**update_args[0])
return tuple(gr.Audio(**update_arg) for update_arg in update_args)
def render(
generate_buttons: list[gr.Button],
song_dir_dropdowns: list[gr.Dropdown],
cached_input_songs_dropdown_1click: gr.Dropdown,
cached_input_songs_dropdown_multi: gr.Dropdown,
rvc_model: gr.Dropdown,
intermediate_audio_to_delete: gr.Dropdown,
output_audio_to_remove: gr.Dropdown,
) -> None:
"""
Render "Multi-step generation" tab.
Parameters
----------
generate_buttons : list[gr.Button]
Buttons used for audio generation in the
"One-click generation" tab and the "Multi-step generation" tab.
song_dir_dropdowns : list[gr.Dropdown]
Dropdowns for selecting song directories in the
"Multi-step generation" tab.
cached_input_songs_dropdown_1click : gr.Dropdown
Dropdown for selecting cached input songs in the
"One-click generation" tab.
cached_input_songs_dropdown_multi : gr.Dropdown
Dropdown for selecting cached input songs in the
"Multi-step generation" tab.
rvc_model : gr.Dropdown
Dropdown for selecting voice models in the
"Multi-step generation" tab.
intermediate_audio_to_delete : gr.Dropdown
Dropdown for selecting intermediate audio files to delete in the
"Delete audio" tab.
output_audio_to_remove : gr.Dropdown
Dropdown for selecting output audio files to delete in the
"Delete audio" tab.
"""
with gr.Tab("Multi-step generation"):
(
retrieve_song_btn,
separate_vocals_btn,
separate_main_vocals_btn,
dereverb_vocals_btn,
convert_vocals_btn,
postprocess_vocals_btn,
pitch_shift_background_btn,
mix_btn,
_,
) = generate_buttons
(
separate_vocals_dir,
separate_main_vocals_dir,
dereverb_vocals_dir,
convert_vocals_dir,
postprocess_vocals_dir,
pitch_shift_background_dir,
mix_dir,
) = song_dir_dropdowns
current_song_dir = gr.State(None)
(
original_track_output,
vocals_track_output,
instrumentals_track_output,
main_vocals_track_output,
backup_vocals_track_output,
dereverbed_vocals_track_output,
reverb_track_output,
converted_vocals_track_output,
postprocessed_vocals_track_output,
shifted_instrumentals_track_output,
shifted_backup_vocals_track_output,
song_cover_track,
) = [
gr.Audio(label=label, type="filepath", interactive=False, render=False)
for label in [
"Input song",
"Vocals",
"Instrumentals",
"Main vocals",
"Backup vocals",
"De-reverbed vocals",
"Reverb",
"Converted vocals",
"Post-processed vocals",
"Pitch-shifted instrumentals",
"Pitch-shifted backup vocals",
"Song cover",
]
]
input_tracks = [
gr.Audio(label=label, type="filepath", render=False)
for label in [
"Input song",
"Vocals",
"Vocals",
"Vocals",
"Vocals",
"Instrumentals",
"Backup vocals",
"Main vocals",
"Instrumentals",
"Backup vocals",
]
]
(
original_track_input,
vocals_track_input,
main_vocals_track_input,
dereverbed_vocals_track_input,
converted_vocals_track_input,
instrumentals_track_input,
backup_vocals_track_input,
postprocessed_vocals_track_input,
shifted_instrumentals_track_input,
shifted_backup_vocals_track_input,
) = input_tracks
transfer_defaults = [
["Step 1: input song"],
["Step 2: vocals"],
["Step 6: instrumentals"],
["Step 3: vocals"],
["Step 6: backup vocals"],
["Step 4: vocals"],
[],
["Step 5: vocals"],
["Step 7: main vocals"],
["Step 7: instrumentals"],
["Step 7: backup vocals"],
[],
]
(
original_track_transfer_default,
vocals_track_transfer_default,
instrumentals_track_transfer_default,
main_vocals_track_transfer_default,
backup_vocals_track_transfer_default,
dereverbed_vocals_track_transfer_default,
reverb_track_transfer_default,
converted_vocals_track_transfer_default,
postprocessed_vocals_track_transfer_default,
shifted_instrumentals_track_transfer_default,
shifted_backup_vocals_track_transfer_default,
song_cover_track_transfer_default,
) = transfer_defaults
transfer_output_track_dropdowns = [
gr.Dropdown(
[
"Step 1: input song",
"Step 2: vocals",
"Step 3: vocals",
"Step 4: vocals",
"Step 5: vocals",
"Step 6: instrumentals",
"Step 6: backup vocals",
"Step 7: main vocals",
"Step 7: instrumentals",
"Step 7: backup vocals",
],
label="Transfer to",
info=(
"Select the input track(s) to transfer the output track to once"
" generation completes."
),
render=False,
type="index",
multiselect=True,
value=value,
)
for value in transfer_defaults
]
(
original_track_transfer_dropdown,
vocals_track_transfer_dropdown,
instrumentals_track_transfer_dropdown,
main_vocals_track_transfer_dropdown,
backup_vocals_track_transfer_dropdown,
dereverbed_vocals_track_transfer_dropdown,
reverb_track_transfer_dropdown,
converted_vocals_track_transfer_dropdown,
postprocessed_vocals_track_transfer_dropdown,
shifted_instrumentals_track_transfer_dropdown,
shifted_backup_vocals_track_transfer_dropdown,
song_cover_track_transfer_dropdown,
) = transfer_output_track_dropdowns
clear_btns = [gr.Button(value="Reset settings", render=False) for _ in range(8)]
(
retrieve_song_clear_btn,
separate_vocals_clear_btn,
separate_main_vocals_clear_btn,
dereverb_vocals_clear_btn,
convert_vocals_clear_btn,
postprocess_vocals_clear_btn,
pitch_shift_background_clear_btn,
mix_clear_btn,
) = clear_btns
with gr.Accordion("Step 0: song retrieval", open=True):
gr.Markdown("")
gr.Markdown("**Inputs**")
with gr.Row():
with gr.Column():
song_input_type_dropdown = gr.Dropdown(
[
"YouTube link/local path",
"Local file/microphone",
"Cached song",
],
value="YouTube link/local path",
label="Song input type",
type="index",
)
with gr.Column():
song_input = gr.Textbox(
label="Song input",
info=(
"Link to a song on YouTube or the full path of a local"
" audio file."
),
)
local_file = gr.Audio(
label="Song input", type="filepath", visible=False
)
cached_input_songs_dropdown_multi.render()
song_input_type_dropdown.input(
partial(toggle_visible_component, 3),
inputs=song_input_type_dropdown,
outputs=[song_input, local_file, cached_input_songs_dropdown_multi],
show_progress="hidden",
)
local_file.change(
update_value,
inputs=local_file,
outputs=song_input,
show_progress="hidden",
)
cached_input_songs_dropdown_multi.input(
update_value,
inputs=cached_input_songs_dropdown_multi,
outputs=song_input,
show_progress="hidden",
)
gr.Markdown("**Outputs**")
original_track_output.render()
original_track_transfer_dropdown.render()
retrieve_song_clear_btn.render()
retrieve_song_clear_btn.click(
lambda: gr.Dropdown(value=original_track_transfer_default),
outputs=[original_track_transfer_dropdown],
show_progress="hidden",
)
retrieve_song_btn.render()
retrieve_song_event_args_list = [
EventArgs(
partial(
exception_harness(retrieve_song), progress_bar=PROGRESS_BAR
),
inputs=[song_input],
outputs=[original_track_output, current_song_dir],
),
EventArgs(
partial(
update_cached_input_songs,
len(song_dir_dropdowns) + 2,
value_indices=range(len(song_dir_dropdowns) + 1),
),
inputs=[current_song_dir],
outputs=(
song_dir_dropdowns
+ [
cached_input_songs_dropdown_multi,
cached_input_songs_dropdown_1click,
]
),
name="then",
show_progress="hidden",
),
EventArgs(
partial(update_cached_input_songs, 1, [], [0]),
outputs=[intermediate_audio_to_delete],
name="then",
show_progress="hidden",
),
EventArgs(
partial(_update_audio, len(input_tracks)),
inputs=[original_track_transfer_dropdown, original_track_output],
outputs=input_tracks,
name="then",
show_progress="hidden",
),
]
setup_consecutive_event_listeners_with_toggled_interactivity(
retrieve_song_btn,
retrieve_song_event_args_list,
generate_buttons,
)
with gr.Accordion("Step 1: vocals/instrumentals separation", open=False):
gr.Markdown("")
gr.Markdown("**Inputs**")
original_track_input.render()
separate_vocals_dir.render()
gr.Markdown("**Outputs**")
with gr.Row():
with gr.Column():
vocals_track_output.render()
vocals_track_transfer_dropdown.render()
with gr.Column():
instrumentals_track_output.render()
instrumentals_track_transfer_dropdown.render()
separate_vocals_clear_btn.render()
separate_vocals_clear_btn.click(
lambda: tuple(
gr.Dropdown(value=value)
for value in [
vocals_track_transfer_default,
instrumentals_track_transfer_default,
]
),
outputs=[
vocals_track_transfer_dropdown,
instrumentals_track_transfer_dropdown,
],
show_progress="hidden",
)
separate_vocals_btn.render()
separate_vocals_event_args_list = [
EventArgs(
partial(
exception_harness(separate_vocals), progress_bar=PROGRESS_BAR
),
inputs=[original_track_input, separate_vocals_dir],
outputs=[vocals_track_output, instrumentals_track_output],
)
] + [
EventArgs(
partial(_update_audio, len(input_tracks)),
inputs=[transfer_dropdown, output_track],
outputs=input_tracks,
name="then",
show_progress="hidden",
)
for transfer_dropdown, output_track in zip(
[
vocals_track_transfer_dropdown,
instrumentals_track_transfer_dropdown,
],
[vocals_track_output, instrumentals_track_output],
)
]
setup_consecutive_event_listeners_with_toggled_interactivity(
separate_vocals_btn,
separate_vocals_event_args_list,
generate_buttons,
)
with gr.Accordion("Step 2: main vocals/ backup vocals separation", open=False):
gr.Markdown("")
gr.Markdown("**Inputs**")
vocals_track_input.render()
separate_main_vocals_dir.render()
gr.Markdown("**Outputs**")
with gr.Row():
with gr.Column():
main_vocals_track_output.render()
main_vocals_track_transfer_dropdown.render()
with gr.Column():
backup_vocals_track_output.render()
backup_vocals_track_transfer_dropdown.render()
separate_main_vocals_clear_btn.render()
separate_main_vocals_clear_btn.click(
lambda: tuple(
gr.Dropdown(value=value)
for value in [
main_vocals_track_transfer_default,
backup_vocals_track_transfer_default,
]
),
outputs=[
main_vocals_track_transfer_dropdown,
backup_vocals_track_transfer_dropdown,
],
show_progress="hidden",
)
separate_main_vocals_btn.render()
separate_main_vocals_event_args_list = [
EventArgs(
partial(
exception_harness(separate_main_vocals),
progress_bar=PROGRESS_BAR,
),
inputs=[vocals_track_input, separate_main_vocals_dir],
outputs=[main_vocals_track_output, backup_vocals_track_output],
)
] + [
EventArgs(
partial(_update_audio, len(input_tracks)),
inputs=[transfer_dropdown, output_track],
outputs=input_tracks,
name="then",
show_progress="hidden",
)
for transfer_dropdown, output_track in zip(
[
main_vocals_track_transfer_dropdown,
backup_vocals_track_transfer_dropdown,
],
[main_vocals_track_output, backup_vocals_track_output],
)
]
setup_consecutive_event_listeners_with_toggled_interactivity(
separate_main_vocals_btn,
separate_main_vocals_event_args_list,
generate_buttons,
)
with gr.Accordion("Step 3: vocal cleanup", open=False):
gr.Markdown("")
gr.Markdown("**Inputs**")
main_vocals_track_input.render()
dereverb_vocals_dir.render()
gr.Markdown("**Outputs**")
with gr.Row():
with gr.Column():
dereverbed_vocals_track_output.render()
dereverbed_vocals_track_transfer_dropdown.render()
with gr.Column():
reverb_track_output.render()
reverb_track_transfer_dropdown.render()
dereverb_vocals_clear_btn.render()
dereverb_vocals_clear_btn.click(
lambda: tuple(
gr.Dropdown(value=value)
for value in [
dereverbed_vocals_track_transfer_default,
reverb_track_transfer_default,
]
),
outputs=[
dereverbed_vocals_track_transfer_dropdown,
reverb_track_transfer_dropdown,
],
show_progress="hidden",
)
dereverb_vocals_btn.render()
dereverb_vocals_event_args_list = [
EventArgs(
partial(
exception_harness(dereverb_vocals), progress_bar=PROGRESS_BAR
),
inputs=[main_vocals_track_input, dereverb_vocals_dir],
outputs=[dereverbed_vocals_track_output, reverb_track_output],
)
] + [
EventArgs(
partial(_update_audio, len(input_tracks)),
inputs=[transfer_dropdown, output_track],
outputs=input_tracks,
name="then",
show_progress="hidden",
)
for transfer_dropdown, output_track in zip(
[
dereverbed_vocals_track_transfer_dropdown,
reverb_track_transfer_dropdown,
],
[dereverbed_vocals_track_output, reverb_track_output],
)
]
setup_consecutive_event_listeners_with_toggled_interactivity(
dereverb_vocals_btn, dereverb_vocals_event_args_list, generate_buttons
)
with gr.Accordion("Step 4: vocal conversion", open=False):
gr.Markdown("")
gr.Markdown("**Inputs**")
dereverbed_vocals_track_input.render()
convert_vocals_dir.render()
with gr.Row():
rvc_model.render()
pitch_change_octaves = gr.Slider(
-3,
3,
value=0,
step=1,
label="Pitch shift (octaves)",
info=(
"Shift pitch of converted vocals by number of octaves."
" Generally, use 1 for male-to-female conversions and -1 for"
" vice-versa."
),
)
pitch_change_semitones = gr.Slider(
-12,
12,
value=0,
step=1,
label="Pitch shift (semi-tones)",
info=(
"Shift pitch of converted vocals by number of semi-tones."
" Altering this slightly reduces sound quality."
),
)
with gr.Row():
index_rate = gr.Slider(
0,
1,
value=0.5,
label="Index rate",
info=(
"Controls how much of the accent in the voice model to keep in"
" the converted vocals"
),
)
filter_radius = gr.Slider(
0,
7,
value=3,
step=1,
label="Filter radius",
info=(
"If >=3: apply median filtering to the harvested pitch results."
" Can reduce breathiness"
),
)
rms_mix_rate = gr.Slider(
0,
1,
value=0.25,
label="RMS mix rate",
info=(
"Control how much to mimic the loudness (0) of the input vocals"
" or a fixed loudness (1)"
),
)
protect = gr.Slider(
0,
0.5,
value=0.33,
label="Protect rate",
info=(
"Protect voiceless consonants and breath sounds. Set to 0.5 to"
" disable."
),
)
with gr.Column():
f0_method = gr.Dropdown(
["rmvpe", "mangio-crepe"],
value="rmvpe",
label="Pitch detection algorithm",
info=(
"Best option is rmvpe (clarity in vocals), then"
" mangio-crepe (smoother vocals)"
),
)
crepe_hop_length = gr.Slider(
32,
320,
value=128,
step=1,
visible=False,
label="Crepe hop length",
info=(
"Lower values leads to longer conversions and higher risk"
" of voice cracks, but better pitch accuracy."
),
)
f0_method.change(
show_hop_slider,
inputs=f0_method,
outputs=crepe_hop_length,
show_progress="hidden",
)
gr.Markdown("**Outputs**")
converted_vocals_track_output.render()
converted_vocals_track_transfer_dropdown.render()
convert_vocals_clear_btn.render()
convert_vocals_clear_btn.click(
lambda: [
0,
0,
0.5,
3,
0.25,
0.33,
"rmvpe",
128,
gr.Dropdown(value=converted_vocals_track_transfer_default),
],
outputs=[
pitch_change_octaves,
pitch_change_semitones,
index_rate,
filter_radius,
rms_mix_rate,
protect,
f0_method,
crepe_hop_length,
converted_vocals_track_transfer_dropdown,
],
show_progress="hidden",
)
convert_vocals_btn.render()
convert_vocals_event_args_list = [
EventArgs(
partial(
exception_harness(convert_vocals), progress_bar=PROGRESS_BAR
),
inputs=[
dereverbed_vocals_track_input,
convert_vocals_dir,
rvc_model,
pitch_change_octaves,
pitch_change_semitones,
index_rate,
filter_radius,
rms_mix_rate,
protect,
f0_method,
crepe_hop_length,
],
outputs=[converted_vocals_track_output],
),
EventArgs(
partial(_update_audio, len(input_tracks)),
inputs=[
converted_vocals_track_transfer_dropdown,
converted_vocals_track_output,
],
outputs=input_tracks,
name="then",
show_progress="hidden",
),
]
setup_consecutive_event_listeners_with_toggled_interactivity(
convert_vocals_btn, convert_vocals_event_args_list, generate_buttons
)
with gr.Accordion("Step 5: post-processing of vocals", open=False):
gr.Markdown("")
gr.Markdown("**Inputs**")
converted_vocals_track_input.render()
postprocess_vocals_dir.render()
with gr.Row():
reverb_rm_size = gr.Slider(
0,
1,
value=0.15,
label="Room size",
info="The larger the room, the longer the reverb time",
)
reverb_wet = gr.Slider(
0,
1,
value=0.2,
label="Wetness level",
info="Loudness level of converted vocals with reverb",
)
reverb_dry = gr.Slider(
0,
1,
value=0.8,
label="Dryness level",
info="Loudness level of converted vocals without reverb",
)
reverb_damping = gr.Slider(
0,
1,
value=0.7,
label="Damping level",
info="Absorption of high frequencies in the reverb",
)
gr.Markdown("**Outputs**")
postprocessed_vocals_track_output.render()
postprocessed_vocals_track_transfer_dropdown.render()
postprocess_vocals_clear_btn.render()
postprocess_vocals_clear_btn.click(
lambda: [
0.15,
0.2,
0.8,
0.7,
gr.Dropdown(value=postprocessed_vocals_track_transfer_default),
],
outputs=[
reverb_rm_size,
reverb_wet,
reverb_dry,
reverb_damping,
postprocessed_vocals_track_transfer_dropdown,
],
show_progress="hidden",
)
postprocess_vocals_btn.render()
postprocess_vocals_event_args_list = [
EventArgs(
partial(
exception_harness(postprocess_vocals),
progress_bar=PROGRESS_BAR,
),
inputs=[
converted_vocals_track_input,
postprocess_vocals_dir,
reverb_rm_size,
reverb_wet,
reverb_dry,
reverb_damping,
],
outputs=[postprocessed_vocals_track_output],
),
EventArgs(
partial(_update_audio, len(input_tracks)),
inputs=[
postprocessed_vocals_track_transfer_dropdown,
postprocessed_vocals_track_output,
],
outputs=input_tracks,
name="then",
show_progress="hidden",
),
]
setup_consecutive_event_listeners_with_toggled_interactivity(
postprocess_vocals_btn,
postprocess_vocals_event_args_list,
generate_buttons,
)
with gr.Accordion("Step 6: pitch shift of background tracks", open=False):
gr.Markdown("")
gr.Markdown("**Inputs**")
with gr.Row():
instrumentals_track_input.render()
backup_vocals_track_input.render()
pitch_shift_background_dir.render()
pitch_change_semitones_background = gr.Slider(
-12,
12,
value=0,
step=1,
label="Pitch shift",
info=(
"Shift pitch of instrumentals and backup vocals. Measured in"
" semi-tones."
),
)
gr.Markdown("**Outputs**")
with gr.Row():
with gr.Column():
shifted_instrumentals_track_output.render()
shifted_instrumentals_track_transfer_dropdown.render()
with gr.Column():
shifted_backup_vocals_track_output.render()
shifted_backup_vocals_track_transfer_dropdown.render()
pitch_shift_background_clear_btn.render()
pitch_shift_background_clear_btn.click(
lambda: [
0,
gr.Dropdown(value=shifted_instrumentals_track_transfer_default),
gr.Dropdown(value=shifted_backup_vocals_track_transfer_default),
],
outputs=[
pitch_change_semitones_background,
shifted_instrumentals_track_transfer_dropdown,
shifted_backup_vocals_track_transfer_dropdown,
],
show_progress="hidden",
)
pitch_shift_background_btn.render()
pitch_shift_background_event_args_list = [
EventArgs(
partial(
exception_harness(pitch_shift_background),
progress_bar=PROGRESS_BAR,
),
inputs=[
instrumentals_track_input,
backup_vocals_track_input,
pitch_shift_background_dir,
pitch_change_semitones_background,
],
outputs=[
shifted_instrumentals_track_output,
shifted_backup_vocals_track_output,
],
)
] + [
EventArgs(
partial(_update_audio, len(input_tracks)),
inputs=[dropdown, output_track],
outputs=input_tracks,
name="then",
show_progress="hidden",
)
for dropdown, output_track in zip(
[
shifted_instrumentals_track_transfer_dropdown,
shifted_backup_vocals_track_transfer_dropdown,
],
[
shifted_instrumentals_track_output,
shifted_backup_vocals_track_output,
],
)
]
setup_consecutive_event_listeners_with_toggled_interactivity(
pitch_shift_background_btn,
pitch_shift_background_event_args_list,
generate_buttons,
)
with gr.Accordion("Step 7: song mixing", open=False):
gr.Markdown("")
gr.Markdown("**Inputs**")
with gr.Row():
postprocessed_vocals_track_input.render()
shifted_instrumentals_track_input.render()
shifted_backup_vocals_track_input.render()
mix_dir.render()
with gr.Row():
main_gain = gr.Slider(-20, 20, value=0, step=1, label="Main vocals")
inst_gain = gr.Slider(-20, 20, value=0, step=1, label="Instrumentals")
backup_gain = gr.Slider(-20, 20, value=0, step=1, label="Backup vocals")
with gr.Row():
output_name = gr.Textbox(
label="Output file name",
placeholder="Ultimate RVC song cover",
)
output_sr = gr.Dropdown(
choices=[16000, 44100, 48000, 96000, 192000],
value=44100,
label="Output sample rate",
)
output_format = gr.Dropdown(
["mp3", "wav", "flac", "aac", "m4a", "ogg"],
value="mp3",
label="Output file format",
)
postprocessed_vocals_track_input.change(
update_song_cover_name,
inputs=[postprocessed_vocals_track_input, mix_dir],
outputs=output_name,
show_progress="hidden",
)
mix_dir.change(
update_song_cover_name,
inputs=[postprocessed_vocals_track_input, mix_dir],
outputs=output_name,
show_progress="hidden",
)
gr.Markdown("**Outputs**")
song_cover_track.render()
song_cover_track_transfer_dropdown.render()
mix_clear_btn.render()
mix_clear_btn.click(
lambda: [
0,
0,
0,
44100,
"mp3",
gr.Dropdown(value=song_cover_track_transfer_default),
],
outputs=[
main_gain,
inst_gain,
backup_gain,
output_sr,
output_format,
song_cover_track_transfer_dropdown,
],
show_progress="hidden",
)
mix_btn.render()
mix_btn_event_args_list = [
EventArgs(
partial(
exception_harness(mix_song_cover), progress_bar=PROGRESS_BAR
),
inputs=[
postprocessed_vocals_track_input,
shifted_instrumentals_track_input,
shifted_backup_vocals_track_input,
mix_dir,
main_gain,
inst_gain,
backup_gain,
output_sr,
output_format,
output_name,
],
outputs=[song_cover_track],
),
EventArgs(
partial(update_output_audio, 1, [], [0]),
outputs=[output_audio_to_remove],
name="then",
show_progress="hidden",
),
EventArgs(
partial(_update_audio, len(input_tracks)),
inputs=[song_cover_track_transfer_dropdown, song_cover_track],
outputs=input_tracks,
name="then",
show_progress="hidden",
),
]
setup_consecutive_event_listeners_with_toggled_interactivity(
mix_btn, mix_btn_event_args_list, generate_buttons
)