[
  {
    "path": "AI_Song_Cover_SOVITS.ipynb",
    "content": "{\n  \"nbformat\": 4,\n  \"nbformat_minor\": 0,\n  \"metadata\": {\n    \"colab\": {\n      \"provenance\": [],\n      \"include_colab_link\": true\n    },\n    \"kernelspec\": {\n      \"name\": \"python3\",\n      \"display_name\": \"Python 3\"\n    },\n    \"language_info\": {\n      \"name\": \"python\"\n    },\n    \"accelerator\": \"GPU\",\n    \"gpuClass\": \"standard\"\n  },\n  \"cells\": [\n    {\n      \"cell_type\": \"markdown\",\n      \"metadata\": {\n        \"id\": \"view-in-github\",\n        \"colab_type\": \"text\"\n      },\n      \"source\": [\n        \"<a href=\\\"https://colab.research.google.com/github/ardha27/AI-Song-Cover-SOVITS/blob/main/AI_Song_Cover_SOVITS.ipynb\\\" target=\\\"_parent\\\"><img src=\\\"https://colab.research.google.com/assets/colab-badge.svg\\\" alt=\\\"Open In Colab\\\"/></a>\"\n      ]\n    },\n    {\n      \"cell_type\": \"code\",\n      \"source\": [\n        \"#@title 0. Check GPU\\n\",\n        \"!nvidia-smi\"\n      ],\n      \"metadata\": {\n        \"id\": \"J5ES3aCa503T\"\n      },\n      \"execution_count\": null,\n      \"outputs\": []\n    },\n    {\n      \"cell_type\": \"code\",\n      \"source\": [\n        \"#@title Mount Google Drive\\n\",\n        \"from google.colab import drive\\n\",\n        \"drive.mount('/content/drive')\"\n      ],\n      \"metadata\": {\n        \"id\": \"DM9Y_tjiA2Yf\"\n      },\n      \"execution_count\": null,\n      \"outputs\": []\n    },\n    {\n      \"cell_type\": \"code\",\n      \"source\": [\n        \"#@title 1. Install Library for Youtube WAV Download\\n\",\n        \"!pip install yt_dlp\\n\",\n        \"!pip install ffmpeg\\n\",\n        \"!mkdir youtubeaudio\\n\"\n      ],\n      \"metadata\": {\n        \"id\": \"td-Hhq5n6SFj\"\n      },\n      \"execution_count\": null,\n      \"outputs\": []\n    },\n    {\n      \"cell_type\": \"code\",\n      \"execution_count\": null,\n      \"metadata\": {\n        \"cellView\": \"form\",\n        \"id\": \"doHo0Gzb5ePk\"\n      },\n      \"outputs\": [],\n      \"source\": [\n        \"#@title Download Youtube WAV\\n\",\n        \"from __future__ import unicode_literals\\n\",\n        \"import yt_dlp\\n\",\n        \"import ffmpeg\\n\",\n        \"import sys\\n\",\n        \"\\n\",\n        \"ydl_opts = {\\n\",\n        \"    'format': 'bestaudio/best',\\n\",\n        \"#    'outtmpl': 'output.%(ext)s',\\n\",\n        \"    'postprocessors': [{\\n\",\n        \"        'key': 'FFmpegExtractAudio',\\n\",\n        \"        'preferredcodec': 'wav',\\n\",\n        \"    }],\\n\",\n        \"    \\\"outtmpl\\\": 'youtubeaudio/audio',  # this is where you can edit how you'd like the filenames to be formatted\\n\",\n        \"}\\n\",\n        \"def download_from_url(url):\\n\",\n        \"    ydl.download([url])\\n\",\n        \"    # stream = ffmpeg.input('output.m4a')\\n\",\n        \"    # stream = ffmpeg.output(stream, 'output.wav')\\n\",\n        \"\\n\",\n        \"\\n\",\n        \"with yt_dlp.YoutubeDL(ydl_opts) as ydl:\\n\",\n        \"      url = \\\"https://www.youtube.com/watch?v=cQGfLDnmWS8&pp=ygULYXNtYWxpYnJhc2k%3D\\\" #@param {type:\\\"string\\\"}\\n\",\n        \"      download_from_url(url)\\n\",\n        \"\\n\",\n        \"\\n\",\n        \"\\n\"\n      ]\n    },\n    {\n      \"cell_type\": \"code\",\n      \"source\": [\n        \"#@title 2. Install Demucs for Separating Audio\\n\",\n        \"!python3 -m pip install -U demucs\"\n      ],\n      \"metadata\": {\n        \"id\": \"-RGvSkYv9_aL\"\n      },\n      \"execution_count\": null,\n      \"outputs\": []\n    },\n    {\n      \"cell_type\": \"code\",\n      \"source\": [\n        \"#@title Separate Vocal and Instrument/Noise using Demucs\\n\",\n        \"import subprocess\\n\",\n        \"AUDIO_INPUT = \\\"/content/youtubeaudio/audio.wav\\\" #@param {type:\\\"string\\\"}\\n\",\n        \"\\n\",\n        \"command = f\\\"demucs --two-stems=vocals {AUDIO_INPUT}\\\"\\n\",\n        \"result = subprocess.run(command.split(), stdout=subprocess.PIPE)\\n\",\n        \"print(result.stdout.decode())\"\n      ],\n      \"metadata\": {\n        \"id\": \"cZidoluC-EZ-\"\n      },\n      \"execution_count\": null,\n      \"outputs\": []\n    },\n    {\n      \"cell_type\": \"code\",\n      \"source\": [\n        \"#@title 3. Split The Audio into Smaller Duration Before Training\\n\",\n        \"#@markdown don't put space on speaker name\\n\",\n        \"SPEAKER_NAME = \\\"Hutao\\\" #@param {type:\\\"string\\\"}\\n\",\n        \"!mkdir -p dataset_raw/{SPEAKER_NAME}\"\n      ],\n      \"metadata\": {\n        \"id\": \"texSOl1mEaNL\"\n      },\n      \"execution_count\": null,\n      \"outputs\": []\n    },\n    {\n      \"cell_type\": \"code\",\n      \"source\": [\n        \"\\n\",\n        \"from scipy.io import wavfile\\n\",\n        \"import os\\n\",\n        \"import numpy as np\\n\",\n        \"import argparse\\n\",\n        \"from tqdm import tqdm\\n\",\n        \"import json\\n\",\n        \"\\n\",\n        \"from datetime import datetime, timedelta\\n\",\n        \"\\n\",\n        \"# Utility functions\\n\",\n        \"\\n\",\n        \"def GetTime(video_seconds):\\n\",\n        \"\\n\",\n        \"    if (video_seconds < 0) :\\n\",\n        \"        return 00\\n\",\n        \"\\n\",\n        \"    else:\\n\",\n        \"        sec = timedelta(seconds=float(video_seconds))\\n\",\n        \"        d = datetime(1,1,1) + sec\\n\",\n        \"\\n\",\n        \"        instant = str(d.hour).zfill(2) + ':' + str(d.minute).zfill(2) + ':' + str(d.second).zfill(2) + str('.001')\\n\",\n        \"\\n\",\n        \"        return instant\\n\",\n        \"\\n\",\n        \"def GetTotalTime(video_seconds):\\n\",\n        \"\\n\",\n        \"    sec = timedelta(seconds=float(video_seconds))\\n\",\n        \"    d = datetime(1,1,1) + sec\\n\",\n        \"    delta = str(d.hour) + ':' + str(d.minute) + \\\":\\\" + str(d.second)\\n\",\n        \"\\n\",\n        \"    return delta\\n\",\n        \"\\n\",\n        \"def windows(signal, window_size, step_size):\\n\",\n        \"    if type(window_size) is not int:\\n\",\n        \"        raise AttributeError(\\\"Window size must be an integer.\\\")\\n\",\n        \"    if type(step_size) is not int:\\n\",\n        \"        raise AttributeError(\\\"Step size must be an integer.\\\")\\n\",\n        \"    for i_start in range(0, len(signal), step_size):\\n\",\n        \"        i_end = i_start + window_size\\n\",\n        \"        if i_end >= len(signal):\\n\",\n        \"            break\\n\",\n        \"        yield signal[i_start:i_end]\\n\",\n        \"\\n\",\n        \"def energy(samples):\\n\",\n        \"    return np.sum(np.power(samples, 2.)) / float(len(samples))\\n\",\n        \"\\n\",\n        \"def rising_edges(binary_signal):\\n\",\n        \"    previous_value = 0\\n\",\n        \"    index = 0\\n\",\n        \"    for x in binary_signal:\\n\",\n        \"        if x and not previous_value:\\n\",\n        \"            yield index\\n\",\n        \"        previous_value = x\\n\",\n        \"        index += 1\\n\",\n        \"\\n\",\n        \"'''\\n\",\n        \"Last Acceptable Values\\n\",\n        \"\\n\",\n        \"min_silence_length = 0.3\\n\",\n        \"silence_threshold = 1e-3\\n\",\n        \"step_duration = 0.03/10\\n\",\n        \"\\n\",\n        \"'''\\n\",\n        \"# Change the arguments and the input file here\\n\",\n        \"input_file = \\\"/content/separated/htdemucs/audio/vocals.wav\\\" #@param {type:\\\"string\\\"}\\n\",\n        \"output_dir = f\\\"/content/dataset_raw/{SPEAKER_NAME}\\\"\\n\",\n        \"min_silence_length = 0.6  # The minimum length of silence at which a split may occur [seconds]. Defaults to 3 seconds.\\n\",\n        \"silence_threshold = 1e-4  # The energy level (between 0.0 and 1.0) below which the signal is regarded as silent.\\n\",\n        \"step_duration = 0.03/10   # The amount of time to step forward in the input file after calculating energy. Smaller value = slower, but more accurate silence detection. Larger value = faster, but might miss some split opportunities. Defaults to (min-silence-length / 10.).\\n\",\n        \"\\n\",\n        \"\\n\",\n        \"input_filename = input_file\\n\",\n        \"window_duration = min_silence_length\\n\",\n        \"if step_duration is None:\\n\",\n        \"    step_duration = window_duration / 10.\\n\",\n        \"else:\\n\",\n        \"    step_duration = step_duration\\n\",\n        \"\\n\",\n        \"output_filename_prefix = os.path.splitext(os.path.basename(input_filename))[0]\\n\",\n        \"dry_run = False\\n\",\n        \"\\n\",\n        \"print(\\\"Splitting {} where energy is below {}% for longer than {}s.\\\".format(\\n\",\n        \"    input_filename,\\n\",\n        \"    silence_threshold * 100.,\\n\",\n        \"    window_duration\\n\",\n        \"    )\\n\",\n        \")\\n\",\n        \"\\n\",\n        \"# Read and split the file\\n\",\n        \"\\n\",\n        \"sample_rate, samples = input_data=wavfile.read(filename=input_filename, mmap=True)\\n\",\n        \"\\n\",\n        \"max_amplitude = np.iinfo(samples.dtype).max\\n\",\n        \"print(max_amplitude)\\n\",\n        \"\\n\",\n        \"max_energy = energy([max_amplitude])\\n\",\n        \"print(max_energy)\\n\",\n        \"\\n\",\n        \"window_size = int(window_duration * sample_rate)\\n\",\n        \"step_size = int(step_duration * sample_rate)\\n\",\n        \"\\n\",\n        \"signal_windows = windows(\\n\",\n        \"    signal=samples,\\n\",\n        \"    window_size=window_size,\\n\",\n        \"    step_size=step_size\\n\",\n        \")\\n\",\n        \"\\n\",\n        \"window_energy = (energy(w) / max_energy for w in tqdm(\\n\",\n        \"    signal_windows,\\n\",\n        \"    total=int(len(samples) / float(step_size))\\n\",\n        \"))\\n\",\n        \"\\n\",\n        \"window_silence = (e > silence_threshold for e in window_energy)\\n\",\n        \"\\n\",\n        \"cut_times = (r * step_duration for r in rising_edges(window_silence))\\n\",\n        \"\\n\",\n        \"# This is the step that takes long, since we force the generators to run.\\n\",\n        \"print(\\\"Finding silences...\\\")\\n\",\n        \"cut_samples = [int(t * sample_rate) for t in cut_times]\\n\",\n        \"cut_samples.append(-1)\\n\",\n        \"\\n\",\n        \"cut_ranges = [(i, cut_samples[i], cut_samples[i+1]) for i in range(len(cut_samples) - 1)]\\n\",\n        \"\\n\",\n        \"video_sub = {str(i) : [str(GetTime(((cut_samples[i])/sample_rate))),\\n\",\n        \"                       str(GetTime(((cut_samples[i+1])/sample_rate)))]\\n\",\n        \"             for i in range(len(cut_samples) - 1)}\\n\",\n        \"\\n\",\n        \"for i, start, stop in tqdm(cut_ranges):\\n\",\n        \"    output_file_path = \\\"{}_{:03d}.wav\\\".format(\\n\",\n        \"        os.path.join(output_dir, output_filename_prefix),\\n\",\n        \"        i\\n\",\n        \"    )\\n\",\n        \"    if not dry_run:\\n\",\n        \"        print(\\\"Writing file {}\\\".format(output_file_path))\\n\",\n        \"        wavfile.write(\\n\",\n        \"            filename=output_file_path,\\n\",\n        \"            rate=sample_rate,\\n\",\n        \"            data=samples[start:stop]\\n\",\n        \"        )\\n\",\n        \"    else:\\n\",\n        \"        print(\\\"Not writing file {}\\\".format(output_file_path))\\n\",\n        \"\\n\",\n        \"with open (output_dir+'\\\\\\\\'+output_filename_prefix+'.json', 'w') as output:\\n\",\n        \"    json.dump(video_sub, output)\"\n      ],\n      \"metadata\": {\n        \"id\": \"taNJV4l-_ZZt\"\n      },\n      \"execution_count\": null,\n      \"outputs\": []\n    },\n    {\n      \"cell_type\": \"code\",\n      \"source\": [\n        \"#@title 4. Install dependencies for Training\\n\",\n        \"#@markdown makesure there are no \\\"so-vits-svc-fork\\\" folder on your Drive before you run this\\n\",\n        \"!pip install pyworld==0.3.2\\n\",\n        \"!python -m pip install -U pip wheel\\n\",\n        \"%pip install -U ipython\\n\",\n        \"%pip install -U so-vits-svc-fork\\n\",\n        \"!mkdir drive/MyDrive/so-vits-svc-fork\"\n      ],\n      \"metadata\": {\n        \"id\": \"RWk6EKflAvAS\"\n      },\n      \"execution_count\": null,\n      \"outputs\": []\n    },\n    {\n      \"cell_type\": \"code\",\n      \"source\": [\n        \"#@title Automatic preprocessing\\n\",\n        \"!svc pre-resample\"\n      ],\n      \"metadata\": {\n        \"id\": \"sD6Rmv7SD24X\"\n      },\n      \"execution_count\": null,\n      \"outputs\": []\n    },\n    {\n      \"cell_type\": \"code\",\n      \"source\": [\n        \"!svc pre-config\"\n      ],\n      \"metadata\": {\n        \"id\": \"IiM26DmFD5Of\"\n      },\n      \"execution_count\": null,\n      \"outputs\": []\n    },\n    {\n      \"cell_type\": \"code\",\n      \"source\": [\n        \"#@title Copy configs file\\n\",\n        \"!cp configs/44k/config.json drive/MyDrive/so-vits-svc-fork\"\n      ],\n      \"metadata\": {\n        \"id\": \"S-2xib_3D7Oy\"\n      },\n      \"execution_count\": null,\n      \"outputs\": []\n    },\n    {\n      \"cell_type\": \"code\",\n      \"source\": [\n        \"F0_METHOD = \\\"dio\\\" #@param [\\\"crepe\\\", \\\"crepe-tiny\\\", \\\"parselmouth\\\", \\\"dio\\\", \\\"harvest\\\"]\\n\",\n        \"!svc pre-hubert -fm {F0_METHOD}\"\n      ],\n      \"metadata\": {\n        \"id\": \"odKQPmXiD8gz\"\n      },\n      \"execution_count\": null,\n      \"outputs\": []\n    },\n    {\n      \"cell_type\": \"code\",\n      \"source\": [\n        \"#@title Train\\n\",\n        \"%load_ext tensorboard\\n\",\n        \"%tensorboard --logdir drive/MyDrive/so-vits-svc-fork/logs/44k\\n\",\n        \"!svc train --model-path drive/MyDrive/so-vits-svc-fork/logs/44k\"\n      ],\n      \"metadata\": {\n        \"id\": \"C1NukdvBEBNm\"\n      },\n      \"execution_count\": null,\n      \"outputs\": []\n    },\n    {\n      \"cell_type\": \"code\",\n      \"source\": [\n        \"#@title 5. Inference\\n\",\n        \"#@markdown remove \\\".wav\\\" on AUDIO. if you facing \\\"SVC Command not Found\\\", install step 4 depedencies first. Don't put space of folder/file name\\n\",\n        \"from IPython.display import Audio\\n\",\n        \"\\n\",\n        \"AUDIO = \\\"/content/separated/htdemucs/audio/vocals\\\" #@param {type:\\\"string\\\"}\\n\",\n        \"MODEL = \\\"/content/drive/MyDrive/so-vits-svc-fork/logs/44k/G_178.pth\\\" #@param {type:\\\"string\\\"}\\n\",\n        \"CONFIG = \\\"/content/drive/MyDrive/so-vits-svc-fork/logs/44k/config.json\\\" #@param {type:\\\"string\\\"}\\n\",\n        \"#@markdown Change According to Your Voice Tone. 12 = 1 Octave | -12 = -1 Octave\\n\",\n        \"PITCH = 0 #@param {type:\\\"integer\\\"}\\n\",\n        \"\\n\",\n        \"!svc infer {AUDIO}.wav -c {CONFIG} -m {MODEL} -na -t {PITCH}\\n\",\n        \"# Try comment this line below if you got Runtime Error\\n\",\n        \"try:\\n\",\n        \"  display(Audio(f\\\"{AUDIO}.out.wav\\\", autoplay=True))\\n\",\n        \"except Exception as e:  print(\\\"Error:\\\", str(e))\\n\"\n      ],\n      \"metadata\": {\n        \"id\": \"dLDnmZ9pH0mG\"\n      },\n      \"execution_count\": null,\n      \"outputs\": []\n    },\n    {\n      \"cell_type\": \"code\",\n      \"source\": [\n        \"#@title 5.1 Inference Using Pretrained Model\"\n      ],\n      \"metadata\": {\n        \"id\": \"pHwuY3NH73n7\"\n      },\n      \"execution_count\": null,\n      \"outputs\": []\n    },\n    {\n      \"cell_type\": \"code\",\n      \"source\": [\n        \"#@title Credit - https://huggingface.co/spaces/zomehwh/sovits-models (Diganti dengan model Alice karena Model Hololive di Private oleh yang punya)\\n\",\n        \"!mkdir so-vits-test\\n\",\n        \"!wget -N \\\"https://huggingface.co/spaces/zomehwh/sovits-models/resolve/main/models/alice/alice.pth\\\" -P so-vits-test/\\n\",\n        \"!wget -N \\\"https://huggingface.co/spaces/zomehwh/sovits-models/resolve/main/models/alice/config.json\\\" -P so-vits-test/\"\n      ],\n      \"metadata\": {\n        \"id\": \"MAEujsmx7-U8\"\n      },\n      \"execution_count\": null,\n      \"outputs\": []\n    },\n    {\n      \"cell_type\": \"code\",\n      \"source\": [\n        \"#@title 5.3 Combine Vocal and Instrument (Song Cover)\\n\",\n        \"!pip install pydub\\n\",\n        \"from pydub import AudioSegment\\n\",\n        \"\\n\",\n        \"VOCAL = \\\"/content/separated/htdemucs/audio/vocals.out.wav\\\" #@param {type:\\\"string\\\"}\\n\",\n        \"INSTRUMENT = \\\"/content/separated/htdemucs/audio/no_vocals.wav\\\" #@param {type:\\\"string\\\"}\\n\",\n        \"\\n\",\n        \"sound1 = AudioSegment.from_file(VOCAL)\\n\",\n        \"sound2 = AudioSegment.from_file(INSTRUMENT)\\n\",\n        \"\\n\",\n        \"combined = sound1.overlay(sound2)\\n\",\n        \"\\n\",\n        \"combined.export(\\\"/content/FinalCover.wav\\\", format='wav')\\n\",\n        \"try:\\n\",\n        \"  display(Audio(f\\\"/content/FinalCover.wav\\\", autoplay=True))\\n\",\n        \"except Exception as e:  print(\\\"Error:\\\", str(e))\\n\"\n      ],\n      \"metadata\": {\n        \"id\": \"w781LsPh_2Xf\"\n      },\n      \"execution_count\": null,\n      \"outputs\": []\n    },\n    {\n      \"cell_type\": \"code\",\n      \"source\": [\n        \"#@title 6. Additional : Audio Recording\\n\",\n        \"!pip install ffmpeg-python\"\n      ],\n      \"metadata\": {\n        \"id\": \"In4WzV9iMVp4\"\n      },\n      \"execution_count\": null,\n      \"outputs\": []\n    },\n    {\n      \"cell_type\": \"code\",\n      \"source\": [\n        \"\\\"\\\"\\\"\\n\",\n        \"To write this piece of code I took inspiration/code from a lot of places.\\n\",\n        \"It was late night, so I'm not sure how much I created or just copied o.O\\n\",\n        \"Here are some of the possible references:\\n\",\n        \"https://blog.addpipe.com/recording-audio-in-the-browser-using-pure-html5-and-minimal-javascript/\\n\",\n        \"https://stackoverflow.com/a/18650249\\n\",\n        \"https://hacks.mozilla.org/2014/06/easy-audio-capture-with-the-mediarecorder-api/\\n\",\n        \"https://air.ghost.io/recording-to-an-audio-file-using-html5-and-js/\\n\",\n        \"https://stackoverflow.com/a/49019356\\n\",\n        \"\\\"\\\"\\\"\\n\",\n        \"from IPython.display import HTML, Audio\\n\",\n        \"from google.colab.output import eval_js\\n\",\n        \"from base64 import b64decode\\n\",\n        \"import numpy as np\\n\",\n        \"from scipy.io.wavfile import read as wav_read\\n\",\n        \"import io\\n\",\n        \"import ffmpeg\\n\",\n        \"\\n\",\n        \"AUDIO_HTML = \\\"\\\"\\\"\\n\",\n        \"<script>\\n\",\n        \"var my_div = document.createElement(\\\"DIV\\\");\\n\",\n        \"var my_p = document.createElement(\\\"P\\\");\\n\",\n        \"var my_btn = document.createElement(\\\"BUTTON\\\");\\n\",\n        \"var t = document.createTextNode(\\\"Press to start recording\\\");\\n\",\n        \"\\n\",\n        \"my_btn.appendChild(t);\\n\",\n        \"//my_p.appendChild(my_btn);\\n\",\n        \"my_div.appendChild(my_btn);\\n\",\n        \"document.body.appendChild(my_div);\\n\",\n        \"\\n\",\n        \"var base64data = 0;\\n\",\n        \"var reader;\\n\",\n        \"var recorder, gumStream;\\n\",\n        \"var recordButton = my_btn;\\n\",\n        \"\\n\",\n        \"var handleSuccess = function(stream) {\\n\",\n        \"  gumStream = stream;\\n\",\n        \"  var options = {\\n\",\n        \"    //bitsPerSecond: 8000, //chrome seems to ignore, always 48k\\n\",\n        \"    mimeType : 'audio/webm;codecs=opus'\\n\",\n        \"    //mimeType : 'audio/webm;codecs=pcm'\\n\",\n        \"  };\\n\",\n        \"  //recorder = new MediaRecorder(stream, options);\\n\",\n        \"  recorder = new MediaRecorder(stream);\\n\",\n        \"  recorder.ondataavailable = function(e) {\\n\",\n        \"    var url = URL.createObjectURL(e.data);\\n\",\n        \"    var preview = document.createElement('audio');\\n\",\n        \"    preview.controls = true;\\n\",\n        \"    preview.src = url;\\n\",\n        \"    document.body.appendChild(preview);\\n\",\n        \"\\n\",\n        \"    reader = new FileReader();\\n\",\n        \"    reader.readAsDataURL(e.data);\\n\",\n        \"    reader.onloadend = function() {\\n\",\n        \"      base64data = reader.result;\\n\",\n        \"      //console.log(\\\"Inside FileReader:\\\" + base64data);\\n\",\n        \"    }\\n\",\n        \"  };\\n\",\n        \"  recorder.start();\\n\",\n        \"  };\\n\",\n        \"\\n\",\n        \"recordButton.innerText = \\\"Recording... press to stop\\\";\\n\",\n        \"\\n\",\n        \"navigator.mediaDevices.getUserMedia({audio: true}).then(handleSuccess);\\n\",\n        \"\\n\",\n        \"\\n\",\n        \"function toggleRecording() {\\n\",\n        \"  if (recorder && recorder.state == \\\"recording\\\") {\\n\",\n        \"      recorder.stop();\\n\",\n        \"      gumStream.getAudioTracks()[0].stop();\\n\",\n        \"      recordButton.innerText = \\\"Saving the recording... pls wait!\\\"\\n\",\n        \"  }\\n\",\n        \"}\\n\",\n        \"\\n\",\n        \"// https://stackoverflow.com/a/951057\\n\",\n        \"function sleep(ms) {\\n\",\n        \"  return new Promise(resolve => setTimeout(resolve, ms));\\n\",\n        \"}\\n\",\n        \"\\n\",\n        \"var data = new Promise(resolve=>{\\n\",\n        \"//recordButton.addEventListener(\\\"click\\\", toggleRecording);\\n\",\n        \"recordButton.onclick = ()=>{\\n\",\n        \"toggleRecording()\\n\",\n        \"\\n\",\n        \"sleep(2000).then(() => {\\n\",\n        \"  // wait 2000ms for the data to be available...\\n\",\n        \"  // ideally this should use something like await...\\n\",\n        \"  //console.log(\\\"Inside data:\\\" + base64data)\\n\",\n        \"  resolve(base64data.toString())\\n\",\n        \"\\n\",\n        \"});\\n\",\n        \"\\n\",\n        \"}\\n\",\n        \"});\\n\",\n        \"\\n\",\n        \"</script>\\n\",\n        \"\\\"\\\"\\\"\\n\",\n        \"\\n\",\n        \"def get_audio():\\n\",\n        \"  display(HTML(AUDIO_HTML))\\n\",\n        \"  data = eval_js(\\\"data\\\")\\n\",\n        \"  binary = b64decode(data.split(',')[1])\\n\",\n        \"\\n\",\n        \"  process = (ffmpeg\\n\",\n        \"    .input('pipe:0')\\n\",\n        \"    .output('pipe:1', format='wav')\\n\",\n        \"    .run_async(pipe_stdin=True, pipe_stdout=True, pipe_stderr=True, quiet=True, overwrite_output=True)\\n\",\n        \"  )\\n\",\n        \"  output, err = process.communicate(input=binary)\\n\",\n        \"\\n\",\n        \"  riff_chunk_size = len(output) - 8\\n\",\n        \"  # Break up the chunk size into four bytes, held in b.\\n\",\n        \"  q = riff_chunk_size\\n\",\n        \"  b = []\\n\",\n        \"  for i in range(4):\\n\",\n        \"      q, r = divmod(q, 256)\\n\",\n        \"      b.append(r)\\n\",\n        \"\\n\",\n        \"  # Replace bytes 4:8 in proc.stdout with the actual size of the RIFF chunk.\\n\",\n        \"  riff = output[:4] + bytes(b) + output[8:]\\n\",\n        \"\\n\",\n        \"  sr, audio = wav_read(io.BytesIO(riff))\\n\",\n        \"\\n\",\n        \"  return audio, sr\"\n      ],\n      \"metadata\": {\n        \"id\": \"0pFo47QTMMX8\"\n      },\n      \"execution_count\": null,\n      \"outputs\": []\n    },\n    {\n      \"cell_type\": \"code\",\n      \"source\": [\n        \"audio, sr = get_audio()\"\n      ],\n      \"metadata\": {\n        \"id\": \"hqcCW1h-NUB4\"\n      },\n      \"execution_count\": null,\n      \"outputs\": []\n    },\n    {\n      \"cell_type\": \"code\",\n      \"source\": [\n        \"from scipy.io import wavfile\\n\",\n        \"wavfile.write(\\\"my_audio.wav\\\", sr, audio)\"\n      ],\n      \"metadata\": {\n        \"id\": \"IakSo65tOPme\"\n      },\n      \"execution_count\": null,\n      \"outputs\": []\n    }\n  ]\n}"
  },
  {
    "path": "FUNDING.yml",
    "content": "ko_fi: ardhach\n"
  },
  {
    "path": "README.md",
    "content": "# AI-Song-Cover-SOVITS\nAll in One Version : Youtube WAV Download, Separating Vocal, Splitting Audio, Training, and Inference Using Google Colab.\n## Leave A Star if This Repo Was Helpful\n[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/R6R7AH1FA)\n<a href=\"https://trakteer.id/ardha27\">\n    <img src=\"https://cdn.trakteer.id/images/embed/trbtn-red-1.png\" alt=\"Trakteer\" height=\"35\">\n</a>\n\n\n### Tutorial (Indonesian)\nhttps://youtu.be/v5MwAqQTc6Q\n\n### Google Colab\n[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ardha27/AI-Song-Cover-SOVITS/blob/main/AI_Song_Cover_SOVITS.ipynb)\n"
  }
]