rvc_tab.py 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. import os
  2. import gradio as gr
  3. import glob
  4. from pathlib import Path
  5. from huggingface_hub import hf_hub_download
  6. from tts_webui.history_tab.open_folder import open_folder
  7. from tts_webui.utils.get_path_from_root import get_path_from_root
  8. from tts_webui.tortoise.gr_reload_button import gr_reload_button, gr_open_button_simple
  9. from tts_webui.rvc_tab.get_and_load_hubert import download_rmvpe
  10. from tts_webui.utils.randomize_seed import randomize_seed_ui
  11. from tts_webui.utils.manage_model_state import manage_model_state
  12. from tts_webui.utils.list_dir_models import unload_model_button
  13. from tts_webui.decorators.gradio_dict_decorator import dictionarize
  14. from tts_webui.decorators.decorator_apply_torch_seed import decorator_apply_torch_seed
  15. from tts_webui.decorators.decorator_log_generation import decorator_log_generation
  16. from tts_webui.decorators.decorator_save_metadata import decorator_save_metadata
  17. from tts_webui.decorators.decorator_save_wav import decorator_save_wav
  18. from tts_webui.decorators.decorator_add_base_filename import decorator_add_base_filename
  19. from tts_webui.decorators.decorator_add_date import decorator_add_date
  20. from tts_webui.decorators.decorator_add_model_type import decorator_add_model_type
  21. from tts_webui.decorators.log_function_time import log_function_time
  22. from tts_webui.extensions_loader.decorator_extensions import (
  23. decorator_extension_outer,
  24. decorator_extension_inner,
  25. )
  26. hubert_path = ""
  27. def get_hubert_path():
  28. global hubert_path
  29. if hubert_path != "":
  30. return hubert_path
  31. else:
  32. hubert_path = hf_hub_download(
  33. repo_id="lj1995/VoiceConversionWebUI", filename="hubert_base.pt"
  34. )
  35. return hubert_path
  36. @manage_model_state("rvc")
  37. def get_vc(model_path):
  38. from rvc.modules.vc.modules import VC
  39. vc = VC()
  40. vc.get_vc(model_path)
  41. return vc
  42. def decorator_rvc_use_model_name_as_text(fn):
  43. def wrapper(*args, **kwargs):
  44. kwargs["text"] = kwargs["model_path"]
  45. return fn(*args, **kwargs)
  46. return wrapper
  47. # add f0_file
  48. @decorator_extension_outer
  49. @decorator_rvc_use_model_name_as_text
  50. @decorator_apply_torch_seed
  51. @decorator_save_metadata
  52. @decorator_save_wav
  53. @decorator_add_model_type("rvc")
  54. @decorator_add_base_filename
  55. @decorator_add_date
  56. @decorator_log_generation
  57. @decorator_extension_inner
  58. @log_function_time
  59. def run_rvc(
  60. pitch_up_key: str,
  61. original_audio_path: str,
  62. index_path: str,
  63. pitch_collection_method: str,
  64. model_path: str,
  65. index_rate: float,
  66. filter_radius: int,
  67. resample_sr: int,
  68. rms_mix_rate: float,
  69. protect: float,
  70. **kwargs,
  71. ):
  72. vc = get_vc(model_path + ".pth")
  73. if pitch_collection_method == "rmvpe":
  74. download_rmvpe()
  75. tgt_sr, audio_opt, times, _ = vc.vc_inference(
  76. sid=1,
  77. input_audio_path=Path(original_audio_path),
  78. f0_up_key=int(pitch_up_key),
  79. f0_method=pitch_collection_method,
  80. f0_file=None,
  81. index_file=Path(index_path + ".index"),
  82. index_rate=index_rate,
  83. filter_radius=filter_radius,
  84. resample_sr=resample_sr,
  85. rms_mix_rate=rms_mix_rate,
  86. protect=protect,
  87. hubert_path=get_hubert_path(),
  88. # hubert_path="data/models/hubert/hubert_base.pt",
  89. )
  90. return {"audio_out": (tgt_sr, audio_opt)}
  91. RVC_LOCAL_MODELS_DIR = get_path_from_root("data", "models", "rvc", "checkpoints")
  92. def remove_path_base(path: str, pos: int = 0):
  93. return os.path.join(*path.split(os.path.sep)[pos:])
  94. def get_list(type: str):
  95. try:
  96. return [
  97. remove_path_base(x, 4).replace(f".{type}", "")
  98. for x in glob.glob(
  99. os.path.join("data", "models", "rvc", "checkpoints", "**", f"*.{type}")
  100. )
  101. if x != ".gitkeep"
  102. ]
  103. except FileNotFoundError as e:
  104. print(e)
  105. return []
  106. def get_rvc_model_list():
  107. return get_list("pth")
  108. def get_rvc_index_list():
  109. return get_list("index")
  110. def rvc_ui_model_or_index_path_ui(label: str):
  111. get_list_fn = get_rvc_model_list if label == "Model" else get_rvc_index_list
  112. with gr.Column():
  113. gr.Markdown(f"{label}")
  114. with gr.Row():
  115. file_path_dropdown = gr.Dropdown(
  116. label=label,
  117. choices=get_list_fn(), # type: ignore
  118. show_label=False,
  119. container=False,
  120. )
  121. gr_open_button_simple(
  122. RVC_LOCAL_MODELS_DIR, api_name=f"rvc_{label.lower()}_open"
  123. )
  124. gr_reload_button().click(
  125. fn=lambda: gr.Dropdown(choices=get_list_fn()),
  126. outputs=[file_path_dropdown],
  127. api_name=f"rvc_{label.lower()}_reload",
  128. )
  129. return file_path_dropdown
  130. def get_rvc_local_path(path: str, file_type: str):
  131. return os.path.join(RVC_LOCAL_MODELS_DIR, f"{path}.{file_type}")
  132. def rvc_ui():
  133. with gr.Row(equal_height=False):
  134. with gr.Column():
  135. with gr.Row():
  136. with gr.Column():
  137. model_path = rvc_ui_model_or_index_path_ui("Model")
  138. with gr.Column():
  139. index_path = rvc_ui_model_or_index_path_ui("Index")
  140. unload_model_button("rvc")
  141. with gr.Row():
  142. pitch_up_key = gr.Textbox(label="Semitone shift", value="0")
  143. pitch_collection_method = gr.Radio(
  144. ["harvest", "pm", "crepe", "rmvpe", "fcpe"],
  145. label="Pitch Collection Method",
  146. value="harvest",
  147. )
  148. index_rate = gr.Slider(
  149. minimum=0.0,
  150. maximum=1.0,
  151. step=0.01,
  152. value=0.66,
  153. label="Search Feature Ratio (accent strength)",
  154. )
  155. filter_radius = gr.Slider(
  156. minimum=0,
  157. maximum=10,
  158. step=1,
  159. value=3,
  160. label="Filter Radius (Pitch median filtering)",
  161. )
  162. with gr.Row():
  163. resample_sr = gr.Slider(
  164. minimum=0,
  165. maximum=48000,
  166. step=1,
  167. value=0,
  168. label="Resample to:",
  169. )
  170. rms_mix_rate = gr.Slider(
  171. minimum=0.0,
  172. maximum=1.0,
  173. step=0.01,
  174. value=1,
  175. label="Voice Envelope Normalizaiton (volume)",
  176. )
  177. protect = gr.Slider(
  178. minimum=0.0,
  179. maximum=0.5,
  180. step=0.01,
  181. value=0.33,
  182. label="Protect Breath Sounds",
  183. )
  184. with gr.Column():
  185. original_audio_path = gr.Audio(label="Original Audio", type="filepath")
  186. button = gr.Button(value="Convert", variant="primary")
  187. audio_out = gr.Audio(label="result", interactive=False)
  188. open_folder_button = gr.Button(
  189. value="Open outputs folder", variant="secondary"
  190. )
  191. open_folder_button.click(lambda: open_folder("outputs-rvc"))
  192. inputs_dict = {
  193. pitch_up_key: "pitch_up_key",
  194. original_audio_path: "original_audio_path",
  195. index_path: "index_path",
  196. pitch_collection_method: "pitch_collection_method",
  197. model_path: "model_path",
  198. index_rate: "index_rate",
  199. filter_radius: "filter_radius",
  200. resample_sr: "resample_sr",
  201. rms_mix_rate: "rms_mix_rate",
  202. protect: "protect",
  203. }
  204. outputs_dict = {
  205. "audio_out": audio_out,
  206. "metadata": gr.JSON(label="Metadata", visible=False),
  207. "folder_root": gr.Textbox(label="Folder root", visible=False),
  208. }
  209. button.click(
  210. **dictionarize(
  211. fn=run_rvc,
  212. inputs=inputs_dict,
  213. outputs=outputs_dict,
  214. ),
  215. api_name="rvc",
  216. )
  217. return original_audio_path
  218. def rvc_conversion_tab():
  219. with gr.Tab("RVC", id="rvc_tab"):
  220. rvc_ui()
  221. if __name__ == "__main__":
  222. if "demo" in locals():
  223. demo.close() # type: ignore
  224. with gr.Blocks(analytics_enabled=False) as demo:
  225. rvc_conversion_tab()
  226. demo.launch(
  227. server_port=7770,
  228. )