RVC Pitch on API

adds RVC pitch to the API and generate screen.
Still need to update TGWUI, SillyTavern Extensions along with documentation.
This commit is contained in:
erew123 authored and GitHub committed 2024-06-17 11:42:54 +01:00
1 parent 6f4bec7ab2
commit 84312bb6b4
2 files changed
+66 -87

No files matched your search

+23 -7
View File
@@ -1436,7 +1436,7 @@ if gradio_enabled == True:
###############################
# Sends voice2rvc request off #
###############################
def voice2rvc(audio, rvc_voice):
def voice2rvc(audio, rvc_voice, rvc_pitch, rvc_f0method):
# Save the uploaded or recorded audio to a file
input_tts_path = this_dir / "outputs" / "voice2rvcInput.wav"
if rvc_voice == "Disabled":
@@ -1464,7 +1464,9 @@ if gradio_enabled == True:
response = requests.post(url, data={
"input_tts_path": str(input_tts_path),
"output_rvc_path": str(output_rvc_path),
"pth_name": rvc_voice
"pth_name": rvc_voice,
"pitch": rvc_pitch,
"method": str(rvc_f0method),
})
if response.status_code == 200:
@@ -1615,7 +1617,7 @@ if gradio_enabled == True:
save_config_data()
return "RVC settings updated successfully!"
def generate_tts(gen_text, gen_char, rvcgen_char, gen_narr, rvcgen_narr, gen_narren, gen_textni, gen_repetition, gen_lang, gen_filter, gen_speed, gen_pitch, gen_autopl, gen_autoplvol, gen_filen, gen_temperature, gen_filetime, gen_stream, gen_stopcurrentgen):
def generate_tts(gen_text, gen_char, rvcgen_char, rvcgen_char_pitch, gen_narr, rvcgen_narr, rvcgen_narr_pitch, gen_narren, gen_textni, gen_repetition, gen_lang, gen_filter, gen_speed, gen_pitch, gen_autopl, gen_autoplvol, gen_filen, gen_temperature, gen_filetime, gen_stream, gen_stopcurrentgen):
if running_on_google_colab:
api_url = f"{tunnel_url_1}/api/tts-generate"
else:
@@ -1639,9 +1641,11 @@ if gradio_enabled == True:
"text_filtering": gen_filter,
"character_voice_gen": gen_char,
"rvccharacter_voice_gen": rvcgen_char,
"rvccharacter_pitch": rvcgen_char_pitch,
"narrator_enabled": str(gen_narren).lower(),
"narrator_voice_gen": gen_narr,
"rvcnarrator_voice_gen": rvcgen_narr,
"rvcnarrator_pitch": rvcgen_narr_pitch,
"text_not_inside": gen_textni,
"language": gen_lang,
"output_file_name": gen_filen,
@@ -1755,6 +1759,15 @@ if gradio_enabled == True:
if rvcat_narrator_voice_gr not in rvcat_available_voices_gr:
rvcat_narrator_voice_gr = rvcat_available_voices_gr[0] if rvcat_available_voices_gr else ""
rvcgen_narr = gr.Dropdown(choices=rvcat_available_voices_gr, label="RVC Narrator Voice", value=rvcat_narrator_voice_gr, allow_custom_value=True,)
with gr.Group():
with gr.Row():
rvcat_default_pitch_gr = gr.Slider(minimum=-24, maximum=24, step=1, label="RVC Character Pitch", info="Corrects the Character input TTS pitch to match the desired RVC voice output pitch.", value=params["rvc_settings"].get("pitch", 0), interactive=True, visible=False)
rvcat_narrator_pitch_gr = gr.Slider(minimum=-24, maximum=24, step=1, label="RVC Narrator Pitch", info="Corrects the Narrator input TTS pitch to match the desired RVC voice output pitch.", value=params["rvc_settings"].get("pitch", 0), interactive=True, visible=False)
def update_visibility(char_voice, narr_voice):
is_visible = char_voice != "Disabled" or narr_voice != "Disabled"
return gr.update(visible=is_visible), gr.update(visible=is_visible)
rvcgen_char.change(fn=update_visibility, inputs=[rvcgen_char, rvcgen_narr], outputs=[rvcat_default_pitch_gr, rvcat_narrator_pitch_gr])
rvcgen_narr.change(fn=update_visibility, inputs=[rvcgen_char, rvcgen_narr], outputs=[rvcat_default_pitch_gr, rvcat_narrator_pitch_gr])
with gr.Accordion("Advanced Engine/Model Settings", open=False):
with gr.Row():
@@ -1816,7 +1829,7 @@ if gradio_enabled == True:
}""", show_api=False)
refresh_button.click(at_update_dropdowns, None, [gen_stream, gen_char, rvcgen_char, gen_narr, rvcgen_narr, gen_speed, gen_pitch, gen_temperature, gen_repetition, gen_lang, model_choices_gr, engine_choices])
stop_button.click(stop_generate_tts, inputs=[], outputs=[output_message])
submit_button.click(generate_tts, inputs=[gen_text, gen_char, rvcgen_char, gen_narr, rvcgen_narr, gen_narren, gen_textni, gen_repetition, gen_lang, gen_filter, gen_speed, gen_pitch, gen_autopl, gen_autoplvol, gen_filen, gen_temperature, gen_filetime, gen_stream, gen_stopcurrentgen], outputs=[output_audio, output_message])
submit_button.click(generate_tts, inputs=[gen_text, gen_char, rvcgen_char, rvcat_default_pitch_gr, gen_narr, rvcgen_narr, rvcat_narrator_pitch_gr, gen_narren, gen_textni, gen_repetition, gen_lang, gen_filter, gen_speed, gen_pitch, gen_autopl, gen_autoplvol, gen_filen, gen_temperature, gen_filetime, gen_stream, gen_stopcurrentgen], outputs=[output_audio, output_message])
with gr.Tab("Generate Help"):
help_content = alltalk_generation_help()
@@ -1827,11 +1840,14 @@ if gradio_enabled == True:
with gr.Row():
audio_input = gr.Audio(sources=["microphone", "upload"], type="numpy", label="Record audio or Upload a spoken audio file")
with gr.Row():
rvc_voices_dropdown = gr.Dropdown(choices=at_settings["rvcvoices"], label="Select RVC Voice to generate as", value=at_settings["rvcvoices"][0])
submit_button = gr.Button("Submit to RVC")
rvc_voices_dropdown = gr.Dropdown(choices=at_settings["rvcvoices"], label="Select RVC Voice to generate as", value=at_settings["rvcvoices"][0], scale=1)
rvc_pitch_slider = gr.Slider(minimum=-24, maximum=24, step=1, label="RVC Pitch", info="Depending on the pitch of your input audio, you will need to adjust this accordingly to change the pitch for the output voice. The higher the value, the higher the pitch.", value=0, interactive=True, scale=2)
with gr.Row():
rvc_f0method = gr.Radio(label="Pitch Extraction Algorithm", info="Select the algorithm to be used for extracting the pitch (F0) during audio conversion. The default algorithm is rmvpe, which is generally recommended for most cases due to its balance of accuracy and performance.", choices=["crepe", "crepe-tiny", "dio", "fcpe", "harvest", "hybrid[rmvpe+fcpe]", "pm", "rmvpe"], value=params["rvc_settings"].get("f0method", "rmvpe"), interactive=True, scale=1)
submit_button = gr.Button("Submit to RVC", scale=0)
audio_output = gr.Audio(label="Converted Audio")
submit_button.click(fn=voice2rvc, inputs=[audio_input, rvc_voices_dropdown], outputs=audio_output)
submit_button.click(fn=voice2rvc, inputs=[audio_input, rvc_voices_dropdown, rvc_pitch_slider, rvc_f0method], outputs=audio_output)
with gr.Tab("TTS Generator"):
gr.Markdown("""With the TTS Generator you can create incredibly long audio e.g. entire books. Yet to be migrated into Gradio""")
+43 -80
View File
@@ -451,7 +451,7 @@ async def deepspeed(request: Request, new_deepspeed_value: bool):
# API Endpoint - /api/voice2rvc #
#################################
@app.post("/api/voice2rvc")
async def voice2rvc(input_tts_path: str = Form(...), output_rvc_path: str = Form(...), pth_name: str = Form(...)):
async def voice2rvc(input_tts_path: str = Form(...), output_rvc_path: str = Form(...), pth_name: str = Form(...), pitch: str = Form(...), method: str = Form(...)):
try:
# Handle "Disabled" case
if pth_name.lower() in ["disabled", "disable"]:
@@ -468,7 +468,7 @@ async def voice2rvc(input_tts_path: str = Form(...), output_rvc_path: str = Form
if not pth_path.is_file():
raise HTTPException(status_code=400, detail=f"Model file {pth_path} does not exist.")
# Run the RVC conversion
result_path = run_voice2rvc(input_tts_path, output_rvc_path, pth_path)
result_path = run_voice2rvc(input_tts_path, output_rvc_path, pth_path, pitch, method)
if result_path:
return {"status": "success", "output_path": str(result_path)}
else:
@@ -478,80 +478,16 @@ async def voice2rvc(input_tts_path: str = Form(...), output_rvc_path: str = Form
raise HTTPException(status_code=500, detail=str(e))
# Define the run_rvc function
def run_voice2rvc(input_tts_path, output_rvc_path, pth_path):
def run_voice2rvc(input_tts_path, output_rvc_path, pth_path, pitch, method):
print(f"[{branding}GEN] \033[94mVoice2RVC Convert: Started\033[0m")
generate_start_time = time.time()
f0up_key = rvc_settings["pitch"]
f0up_key = pitch
filter_radius = rvc_settings["filter_radius"]
index_rate = rvc_settings["index_rate"]
rms_mix_rate = rvc_settings["rms_mix_rate"]
protect = rvc_settings["protect"]
hop_length = rvc_settings["hop_length"]
f0method = rvc_settings["f0method"]
split_audio = rvc_settings["split_audio"]
f0autotune = rvc_settings["autotune"]
embedder_model = rvc_settings["embedder_model"]
training_data_size = rvc_settings["training_data_size"]
# Convert path variables to strings
input_tts_path = str(input_tts_path)
pth_path = str(pth_path)
# Check if the model file exists
if not os.path.isfile(pth_path):
print(f"Model file {pth_path} does not exist. Exiting.")
return
# Get the directory of the model file
model_dir = os.path.dirname(pth_path)
# Find all .index files in the model directory
index_files = [file for file in os.listdir(model_dir) if file.endswith(".index")]
if len(index_files) == 1:
index_path = str(os.path.join(model_dir, index_files[0]))
else:
index_path = ""
# Call the infer_pipeline function
infer_pipeline(f0up_key, filter_radius, index_rate, rms_mix_rate, protect, hop_length, f0method,
input_tts_path, output_rvc_path, pth_path, index_path, split_audio, f0autotune, embedder_model, training_data_size, debug_rvc)
generate_end_time = time.time()
generate_elapsed_time = generate_end_time - generate_start_time
print(f"[{branding}GEN] \033[94mVoice2RVC Convert: \033[91m{generate_elapsed_time:.2f} seconds.\033[0m")
return output_rvc_path
#################################
# API Endpoint - /api/voice2rvc #
#################################
@app.post("/api/voice2rvc")
async def voice2rvc(input_tts_path: str = Form(...), output_rvc_path: str = Form(...), pth_name: str = Form(...)):
try:
input_tts_path = Path(input_tts_path)
output_rvc_path = Path(output_rvc_path)
# Check if input file exists
if not input_tts_path.is_file():
raise HTTPException(status_code=400, detail=f"Input file {input_tts_path} does not exist.")
# Define the model path based on the selected model name
pth_path = this_dir / "models" / "rvc_voices" / pth_name
# Check if model file exists
if not pth_path.is_file():
raise HTTPException(status_code=400, detail=f"Model file {pth_path} does not exist.")
# Run the RVC conversion
result_path = run_voice2rvc(input_tts_path, output_rvc_path, pth_path)
if result_path:
return {"status": "success", "output_path": str(result_path)}
else:
raise HTTPException(status_code=500, detail="RVC conversion failed.")
except Exception as e:
print(f"Error during Voice2RVC conversion: {e}")
raise HTTPException(status_code=500, detail=str(e))
# Define the run_rvc function
def run_voice2rvc(input_tts_path, output_rvc_path, pth_path):
print(f"[{branding}GEN] \033[94mVoice2RVC Convert: Started\033[0m")
generate_start_time = time.time()
f0up_key = rvc_settings["pitch"]
filter_radius = rvc_settings["filter_radius"]
index_rate = rvc_settings["index_rate"]
rms_mix_rate = rvc_settings["rms_mix_rate"]
protect = rvc_settings["protect"]
hop_length = rvc_settings["hop_length"]
f0method = rvc_settings["f0method"]
f0method = method
split_audio = rvc_settings["split_audio"]
f0autotune = rvc_settings["autotune"]
embedder_model = rvc_settings["embedder_model"]
@@ -1050,9 +986,9 @@ def combine(output_file_timestamp, output_file_name, audio_files, target_sample_
##################################
# Central RVC Generation request #
##################################
def run_rvc(input_tts_path, pth_path, infer_pipeline):
def run_rvc(input_tts_path, pth_path, pitch, infer_pipeline):
generate_start_time = time.time()
f0up_key = rvc_settings["pitch"]
f0up_key = pitch
filter_radius = rvc_settings["filter_radius"]
index_rate = rvc_settings["index_rate"]
rms_mix_rate = rvc_settings["rms_mix_rate"]
@@ -1131,13 +1067,13 @@ def run_rvc(input_tts_path, pth_path, infer_pipeline):
####################################################################
# /api/tts-generate Generation API Endpoint Narration RVC handling #
####################################################################
def process_rvc_narrator(part_type, voice_gen, default_model_file, output_file, infer_pipeline):
def process_rvc_narrator(part_type, voice_gen, pitch, default_model_file, output_file, infer_pipeline):
if voice_gen.lower() in ["disabled", "disable"]:
return
else:
voice_gen_path = this_dir / "models" / "rvc_voices" / voice_gen
pth_path = voice_gen_path if voice_gen else default_model_file
run_rvc(output_file, pth_path, infer_pipeline)
run_rvc(output_file, pth_path, pitch, infer_pipeline)
#############################################################
# /api/tts-generate Generation API Endpoint JSON validation #
@@ -1147,9 +1083,11 @@ class JSONInput(BaseModel):
text_filtering: str = Field(..., pattern="^(none|standard|html)$", description="text_filtering needs to be 'none', 'standard' or 'html'.")
character_voice_gen: str = Field(..., pattern=r'^[\(\)a-zA-Z0-9\_\-./\s]+$', description="character_voice_gen needs to be the name of a valid voice for the loaded TTS engine.")
rvccharacter_voice_gen: str = Field(..., description="rvccharacter_voice_gen needs to be the name of a valid pth file in the 'folder\\file.pth' format or the word 'Disabled'.")
rvccharacter_pitch: str = Field(..., description="RVC Character pitch needs to be a number between -24 and 24")
narrator_enabled: str = Field(..., pattern="^(true|false|silent)$", description="narrator_enabled needs to be 'true', 'false' or 'silent'.")
narrator_voice_gen: str = Field(..., pattern=r'^[\(\)a-zA-Z0-9\_\-./\s]+$', description="character_voice_gen needs to be the name of a valid voice for the loaded TTS engine.")
rvcnarrator_voice_gen: str = Field(..., description="rvcnarrator_voice_gen needs to be the name of a valid pth file in the 'folder\\file.pth' format or the word 'Disabled'.")
rvcnarrator_voice_gen: str = Field(..., description="rvcnarrator_voice_gen needs to be the name of a valid pth file in the 'folder\\file.pth' format or the word 'Disabled'.")
rvcnarrator_pitch: str = Field(..., description="RVC Narrator pitch needs to be a number between -24 and 24")
text_not_inside: str = Field(..., pattern="^(character|narrator|silent)$", description="text_not_inside needs to be 'character', 'narrator' or 'silent'.")
language: str = Field(..., pattern="^(ar|zh-cn|cs|nl|en|fr|de|hu|hi|it|ja|ko|pl|pt|ru|es|tr)$", description="language needs to be one of the following: ar, zh-cn, cs, nl, en, fr, de, hu, hi, it, ja, ko, pl, pt, ru, es, tr.")
output_file_name: str = Field(..., pattern="^[a-zA-Z0-9_]+$", description="output_file_name needs to be the name without any special characters or file extension, e.g., 'filename'.")
@@ -1175,13 +1113,22 @@ class JSONInput(BaseModel):
raise ValueError("rvccharacter_voice_gen needs to be the name of a valid pth file in the 'folder\\file.pth' format or 'Disabled'.")
return v
def validate_rvccharacter_voice_gen(cls, v):
def validate_rvnarrator_voice_gen(cls, v):
if v.lower() == "disabled":
return v
pattern = re.compile(r'^.*\.(pth)$')
if not pattern.match(v):
raise ValueError("rvcnarrator_voice_gen needs to be the name of a valid pth file in the 'folder\\file.pth' format or 'Disabled'.")
return v
def validate_pitches(cls, value):
try:
num_value = float(value)
except ValueError:
raise ValueError("Pitch must be a number or a string representing a number.")
if not -24 <= num_value <= 24:
raise ValueError("Pitch needs to be a number between -24 and 24.")
return value
def validate_json_input(json_input_data):
try:
@@ -1228,10 +1175,14 @@ def get_character_voice_gen():
return model_engine.def_character_voice
def get_rvccharacter_voice_gen():
return rvc_settings["rvc_char_model_file"]
def get_rvccharacter_pitch():
return rvc_settings["pitch"]
def get_narrator_voice_gen():
return model_engine.def_narrator_voice
def get_rvcnarrator_voice_gen():
return rvc_settings["rvc_narr_model_file"]
def get_rvcnarrator_pitch():
return rvc_settings["pitch"]
#############################################
# /api/tts-generate Generation API Endpoint #
@@ -1242,9 +1193,11 @@ async def apifunction_generate_tts_standard(
text_filtering: str = Form(None),
character_voice_gen: str = Form(None),
rvccharacter_voice_gen: str = Form(None),
rvccharacter_pitch: str = Form(None),
narrator_enabled: str = Form(None),
narrator_voice_gen: str = Form(None),
rvcnarrator_voice_gen: str = Form(None),
rvcnarrator_pitch: str = Form(None),
text_not_inside: str = Form(None),
language: str = Form(None),
output_file_name: str = Form(None),
@@ -1259,9 +1212,11 @@ async def apifunction_generate_tts_standard(
_text_filtering: str = Depends(get_api_text_filtering),
_character_voice_gen: str = Depends(get_character_voice_gen),
_rvccharacter_voice_gen: str = Depends(get_rvccharacter_voice_gen),
_rvccharacter_pitch: str = Depends(get_rvccharacter_pitch),
_narrator_enabled: str = Depends(get_api_narrator_enabled),
_narrator_voice_gen: str = Depends(get_narrator_voice_gen),
_rvcnarrator_voice_gen: str = Depends(get_rvcnarrator_voice_gen),
_rvcnarrator_pitch: str = Depends(get_rvcnarrator_pitch),
_text_not_inside: str = Depends(get_api_text_not_inside),
_language: str = Depends(get_api_language),
_output_file_name: str = Depends(get_api_output_file_name),
@@ -1288,9 +1243,11 @@ async def apifunction_generate_tts_standard(
f"[{branding}Debug] text_filtering : {text_filtering}",
f"[{branding}Debug] character_voice_gen : {character_voice_gen}",
f"[{branding}Debug] rvccharacter_voice_gen : {rvccharacter_voice_gen}",
f"[{branding}Debug] rvccharacter_pitch : {rvccharacter_pitch}",
f"[{branding}Debug] narrator_enabled : {narrator_enabled}",
f"[{branding}Debug] narrator_voice_gen : {narrator_voice_gen}",
f"[{branding}Debug] rvcnarrator_voice_gen : {rvcnarrator_voice_gen}",
f"[{branding}Debug] rvcnarrator_pitch : {rvcnarrator_pitch}",
f"[{branding}Debug] text_not_inside : {text_not_inside}",
f"[{branding}Debug] language : {language}",
f"[{branding}Debug] output_file_name : {output_file_name}",
@@ -1308,9 +1265,11 @@ async def apifunction_generate_tts_standard(
text_filtering = text_filtering or _text_filtering
character_voice_gen = character_voice_gen or _character_voice_gen
rvccharacter_voice_gen = rvccharacter_voice_gen or _rvccharacter_voice_gen
rvccharacter_pitch = rvccharacter_pitch or _rvccharacter_pitch
narrator_enabled = narrator_enabled or _narrator_enabled # NEED TO COME BACK AND LOOK AT THIS!!!
narrator_voice_gen = narrator_voice_gen or _narrator_voice_gen
rvcnarrator_voice_gen = rvcnarrator_voice_gen or _rvcnarrator_voice_gen
rvcnarrator_pitch = rvcnarrator_pitch or _rvcnarrator_pitch
text_not_inside = text_not_inside or _text_not_inside
language = language or _language
output_file_name = output_file_name or _output_file_name
@@ -1327,9 +1286,11 @@ async def apifunction_generate_tts_standard(
"text_filtering": text_filtering,
"character_voice_gen": character_voice_gen,
"rvccharacter_voice_gen": rvccharacter_voice_gen,
"rvccharacter_pitch": rvccharacter_pitch,
"narrator_enabled": narrator_enabled,
"narrator_voice_gen": narrator_voice_gen,
"rvcnarrator_voice_gen": rvcnarrator_voice_gen,
"rvcnarrator_pitch": rvcnarrator_pitch,
"text_not_inside": text_not_inside,
"language": language,
"output_file_name": output_file_name,
@@ -1363,9 +1324,11 @@ async def apifunction_generate_tts_standard(
f"[{branding}Debug] text_filtering : {text_filtering}",
f"[{branding}Debug] character_voice_gen : {character_voice_gen}",
f"[{branding}Debug] rvccharacter_voice_gen : {rvccharacter_voice_gen}",
f"[{branding}Debug] rvccharacter_pitch : {rvccharacter_pitch}",
f"[{branding}Debug] narrator_enabled : {narrator_enabled}",
f"[{branding}Debug] narrator_voice_gen : {narrator_voice_gen}",
f"[{branding}Debug] rvcnarrator_voice_gen : {rvcnarrator_voice_gen}",
f"[{branding}Debug] rvcnarrator_pitch : {rvcnarrator_pitch}",
f"[{branding}Debug] text_not_inside : {text_not_inside}",
f"[{branding}Debug] language : {language}",
f"[{branding}Debug] output_file_name : {output_file_name}",
@@ -1425,14 +1388,14 @@ async def apifunction_generate_tts_standard(
audio_path = output_file_str
if rvc_settings["rvc_enabled"]:
if part_type == 'character':
process_rvc_narrator(part_type, rvccharacter_voice_gen, rvc_settings["rvc_char_model_file"], output_file, infer_pipeline)
process_rvc_narrator(part_type, rvccharacter_voice_gen, rvccharacter_pitch, rvc_settings["rvc_char_model_file"], output_file, infer_pipeline)
elif part_type == 'narrator':
process_rvc_narrator(part_type, rvcnarrator_voice_gen, rvc_settings["rvc_narr_model_file"], output_file, infer_pipeline)
process_rvc_narrator(part_type, rvcnarrator_voice_gen, rvcnarrator_pitch, rvc_settings["rvc_narr_model_file"], output_file, infer_pipeline)
else:
if text_not_inside == 'character':
process_rvc_narrator('character', rvccharacter_voice_gen, rvc_settings["rvc_char_model_file"], output_file, infer_pipeline)
process_rvc_narrator('character', rvccharacter_voice_gen, rvccharacter_pitch, rvc_settings["rvc_char_model_file"], output_file, infer_pipeline)
elif text_not_inside == 'narrator':
process_rvc_narrator('narrator', rvcnarrator_voice_gen, rvc_settings["rvc_narr_model_file"], output_file, infer_pipeline)
process_rvc_narrator('narrator', rvcnarrator_voice_gen, rvcnarrator_pitch, rvc_settings["rvc_narr_model_file"], output_file, infer_pipeline)
print(f"[{branding}Debug] Appending audio path to list") if debug_tts else None
audio_files_all_paragraphs.append(audio_path)
# Combine audio files across paragraphs
@@ -1520,7 +1483,7 @@ async def apifunction_generate_tts_standard(
print(f"[{branding}Debug] send to rvc") if debug_tts else None
rvccharacter_voice_gen = this_dir / "models" / "rvc_voices" / rvccharacter_voice_gen
pth_path = rvccharacter_voice_gen if rvccharacter_voice_gen else rvc_settings["rvc_char_model_file"]
run_rvc(output_file_path, pth_path, infer_pipeline)
run_rvc(output_file_path, pth_path, rvccharacter_pitch, infer_pipeline)
# Transcode audio if necessary
model_audio_format = str(model_engine.audio_format).lower()
output_audio_format = str(params["transcode_audio_format"]).lower()