class SpleeterPredictor(MusicDemixingPredictor): """ Predictor based on Spleeter separator instance. """ def prediction_setup(self) -> None: self.audio = FFMPEGProcessAudioAdapter() self.separator = Separator("spleeter:4stems") # NOTE: call manually internal to ensure model is # not lazy loaded. self.separator._get_prediction_generator() def prediction( self, mixture_file_path: str, bass_file_path: str, drums_file_path: str, other_file_path: str, vocals_file_path: str, ) -> None: y, _ = self.audio.load(mixture_file_path) prediction = self.separator.separate(y) instruments = { "bass": bass_file_path, "drums": drums_file_path, "other": other_file_path, "vocals": vocals_file_path, } for instrument, path in instruments.items(): self.audio.save(path, prediction[instrument], 44100) print("%s: prediction completed." % mixture_file_path)
def seperatechannels(filename): separator = Separator("spleeter:2stems") folder_name = "audio-channels" # create a directory to store the seperated audio channels if not os.path.isdir(folder_name): os.mkdir(folder_name) separator.separate_to_file(filename, folder_name)
def split(): settings = open_settings() splitter = Separator('spleeter:5stems') splitter.separate_to_file( 'data/input/new_song' + settings['file_extension'], 'data/output/new_song' + settings['file_extension']) return render_template('home.html')
def separate_drum_track(filepath): fs, data = wavfile.read(filepath) data = data / 32767.0 output_path = './temp/drums_track.wav' #mono to stereo if data[0].size == 1: data = [[i, i] for i in data] data = np.array(data) separator = Separator('spleeter:4stems') results = separator.separate(data) result_track = results['drums'] #stereo to mono if result_track[0].size == 2: result_track = result_track.sum(axis=1) / 2 result_track = result_track * 32767 result_track = np.asarray(result_track, dtype=np.int16) wavfile.write(output_path, fs, result_track) return os.path.abspath(output_path)
def ssp(file_path, sr, cache, out_dir): separator = Separator('spleeter:5stems', multiprocess=False) audio_loader = get_default_audio_adapter() file_path = os.path.join(out_dir, file_path) waveform, _ = audio_loader.load(file_path, sample_rate=sr) prediction = separator.separate(waveform) file_name = os.path.split(file_path)[-1].split( f'.{filetype.guess(file_path).extension}')[0] cache_dir = get_save_dir(out_dir, ['ssp', file_name]) cache_paths = [ os.path.join(cache_dir, f'{path}.wav') for path in ['track', 'perc', 'bass', 'harm'] ] paths_exist = check_files_exist(cache_paths) if cache and paths_exist: ssp_audios = map(lambda cache_path: librosa.load(cache_path, sr)[0], cache_paths) else: audio = waveform[:, 0] perc = prediction['drums'][:, 0] bass = prediction['bass'][:, 0] harm = prediction['piano'][:, 0] + prediction[ 'vocals'][:, 0] + prediction['other'][:, 0] ssp_audios = [audio, perc, bass, harm] if cache and not paths_exist: map( lambda index: save_audio(cache_paths[index], ssp_audios[index], sr ), range(len(ssp_audios))) return ssp_audios
def fileButtonClicked(self): global t strFilter = "음악 파일 (*.mp3)"; fname = QFileDialog.getOpenFileName(self,filter=strFilter) if fname[0] == "": return a = os.path.split(fname[0])[1] songname = os.path.splitext(a)[0] #p1.join() t=0 if (os.path.exists("C:/pyKaraoke/"+songname+"/accompaniment.wav")): loaded = "C:/pyKaraoke/"+songname+"/accompaniment.wav" else: sep = Separator('spleeter:2stems') # spleeter:2stems 보컬/반주 # spleeter:4stems 목소리 피아노 베이스 드럼 sep.separate_to_file(fname[0], "C:/pyKaraoke/") loaded = "C:/pyKaraoke/"+songname+"/accompaniment.wav" p1 = threading.Thread(target=echo, args="") p1.daemon = True p1.start() self.lyricbox.clear() self.lyricbox.setAlignment(Qt.AlignCenter) self.lyricbox.append(getLyrics(songname)) url = QUrl.fromLocalFile(loaded) self.player.setMedia(QMediaContent(url))
def _vocal_separation(wav_list, out_folder): wavs = OrderedDict({os.path.basename(wav): wav for wav in wav_list}) if os.path.exists(out_folder): # There are already some separated audio. sep_wavs = set(os.listdir(out_folder)) diff_wavs = set(wavs.keys()) - sep_wavs logger.debug("Audio to be separated: %s", diff_wavs) # Check the difference of the separated audio and the received audio list. done_wavs = set(wavs.keys()) - diff_wavs wavs_copy = wavs.copy() for dwav in done_wavs: del wavs_copy[dwav] wav_list = list(wavs_copy.values()) out_list = [jpath(out_folder, wav) for wav in wavs] if len(wav_list) > 0: separator = Separator('spleeter:2stems') separator._params["stft_backend"] = "librosa" # pylint: disable=protected-access for idx, wav_path in enumerate(wav_list, 1): logger.info("Separation Progress: %d/%d - %s", idx, len(wav_list), wav_path) separator.separate_to_file(wav_path, out_folder) # The separated tracks are stored in sub-folders. # Move the vocal track to the desired folder and rename them. fname, _ = os.path.splitext(os.path.basename(wav_path)) sep_folder = jpath(out_folder, fname) vocal_track = jpath(sep_folder, "vocals.wav") shutil.move(vocal_track, jpath(out_folder, fname + ".wav")) shutil.rmtree(sep_folder) return out_list
def extract_file( self, file_path: str, output_path: str = None, print_progress: bool = True, automatic_cleanup: bool = False, ): output_path = self.__get_output_path(output_path) if print_progress: print("Extracting ", colored('"' + file_path + '"', important_color), " now...", sep="") separator = Separator(self.stems_type) separator.separate_to_file(file_path, output_path, codec=self.codec) self.last_file = file_path self.last_folder = output_path if print_progress: print(colored('"' + file_path + '"', important_color), " was extracted using stems_type: ", colored('"' + self.stems_type + '"'), " You can find it in path:", colored('"' + output_path + '"', important_color), sep="") if automatic_cleanup: self.reset_default_tmp()
def process(url): os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3' from spleeter.separator import Separator import logging logging.basicConfig(filename='spleeter.log', level=logging.INFO) tmpfile = tempfile.mktemp(suffix=".m4a", dir="tmp") try: sys.stdout = open("log.txt", "w") sys.stderr = open("err.txt", "w") ydl_opts = {"outtmpl": tmpfile, "format": "m4a", "max_downloads": 1} print(tmpfile) fname = None with youtube_dl.YoutubeDL(ydl_opts) as ydl: ydl.download([url]) info = ydl.get_info_extractor("Youtube").extract(url) fname = clean_path(info["title"]) # os.makedirs(info["title"]) os.rename(tmpfile, fname + ".m4a") tmpfile = fname + ".m4a" separator = Separator("spleeter:2stems-16kHz") separator.separate_to_file(tmpfile, "output", codec="mp3", bitrate="196k") finally: if os.path.exists(tmpfile): os.unlink(tmpfile)
def fetch_separate_and_upload(input_s3_url, output_s3_url, s3=None): if s3 is None: s3 = boto3.resource("s3") with NamedTemporaryFile() as input_file, TemporaryDirectory( ) as output_path: input_object = s3.Object(**parse_s3_url(input_s3_url)._asdict()) input_object.download_file(input_file.name) audio_adapter = get_audio_adapter(None) separator = Separator(SPLEETER_CONFIGURATION, MWF=USE_MULTICHANNEL_WIENER_FILTERING) separator.separate_to_file(input_file.name, output_path, audio_adapter=audio_adapter, offset=AUDIO_START_OFFSET, duration=MAX_AUDIO_DURATION, codec=OUTPUT_CODEC, bitrate=OUTPUT_BITRATE, filename_format=OUTPUT_FILENAME_FORMAT, synchronous=True) logging.info(f'Uploading output to: {output_s3_url}') output_object = s3.Object(**parse_s3_url(output_s3_url)._asdict()) output_filename = os.path.join(output_path, f'accompaniment.{OUTPUT_CODEC}') output_object.upload_file(output_filename)
def separate_vocal(): # Using embedded configuration. separator = Separator('spleeter:2stems') from spleeter.audio.adapter import AudioAdapter separator.separate_to_file('temp.mp3', 'audio_output') return
def spleeter(aud, instrument): separator = Separator('spleeter:2stems') try: shutil.rmtree("output") except FileNotFoundError: pass separator.separate_to_file(aud.name, "output/", filename_format="audio_example/{instrument}.wav") return f"./output/audio_example/{instrument}.wav", f"./output/audio_example/{instrument}.wav"
def separa(number, wave): separator = Separator(f"spleeter:{number}stems") audio_file = wave destination = 'files/separate' separator.separate_to_file(audio_file, destination) #split.separa(2,"files/It dont mean i think_ master.mp3")
def separate(filename, model='spleeter:2stems'): separator = Separator(model) separator.separate_to_file(f'{settings.MEDIA_ROOT}{filename}', settings.MEDIA_TMP, synchronous=True) outname, _ = os.path.splitext(filename) zipfolder(f'{settings.MEDIA_DOWNLOAD}{outname}', outname) return outname
def test_filename_conflict(): """ Test error handling with static pattern. """ separator = Separator(TEST_CONFIGURATIONS[0][0]) with TemporaryDirectory() as directory: with pytest.raises(SpleeterError): separator.separate_to_file(TEST_AUDIO_DESCRIPTOR, directory, filename_format='I wanna be your lover')
def __init__(self, model_path_1, model_path_2): self.spleeter = Separator('spleeter:2stems', model_path_1) # 基于频域进行音轨分离,分离人声的话一般只需要2轨,accompaniment.wav 提取的背景/伴奏; vocals.wav是提取的人声 self.spleeter._get_predictor() self.ina_speech_segmenter = Segmenter(detect_gender=False, model_dir=model_path_2) ###### logging.info("init done")
def test_filename_conflict(test_file, configuration): """ Test error handling with static pattern. """ separator = Separator(configuration, multiprocess=False) with TemporaryDirectory() as directory: with pytest.raises(SpleeterError): separator.separate_to_file(test_file, directory, filename_format='I wanna be your lover')
def execute(args): try: logger.info('音声分離処理開始: {0}', args.audio_file, decoration=MLogger.DECORATION_BOX) if not os.path.exists(args.audio_file): logger.error("指定された音声ファイルパスが存在しません。\n{0}", args.audio_file, decoration=MLogger.DECORATION_BOX) return False, None # 親パス(指定がなければ動画のある場所。Colabはローカルで作成するので指定あり想定) base_path = str(pathlib.Path(args.audio_file).parent ) if not args.parent_dir else args.parent_dir if len(args.parent_dir) > 0: process_audio_dir = base_path else: process_audio_dir = os.path.join( base_path, "{0}_{1:%Y%m%d_%H%M%S}".format( os.path.basename(args.audio_file).replace('.', '_'), datetime.datetime.now())) # 既存は削除 if os.path.exists(process_audio_dir): shutil.rmtree(process_audio_dir) # フォルダ生成 os.makedirs(process_audio_dir) audio_adapter = AudioAdapter.default() waveform, sample_rate = audio_adapter.load(args.audio_file) # 音声と曲に分離 separator = Separator('spleeter:2stems') # Perform the separation : prediction = separator.separate(waveform) # 音声データ vocals = prediction['vocals'] vocals_wav_path = f"{process_audio_dir}/vocals.wav" # 一旦wavとして保存 audio_adapter.save(vocals_wav_path, vocals, sample_rate, "wav") logger.info('音声分離処理終了: {0}', process_audio_dir, decoration=MLogger.DECORATION_BOX) return True, process_audio_dir except Exception as e: logger.critical("音声分離で予期せぬエラーが発生しました。", e, decoration=MLogger.DECORATION_BOX) return False, None
def test_separate_to_file(configuration, instruments, backend): """ Test file based separation. """ separator = Separator(configuration, stft_backend=backend) with TemporaryDirectory() as directory: separator.separate_to_file(TEST_AUDIO_DESCRIPTOR, directory) for instrument in instruments: assert exists( join(directory, '{}/{}.wav'.format(TEST_AUDIO_BASENAME, instrument)))
def separate_audio(): output_dir_path.mkdir(parents=True, exist_ok=True) # Using embedded configuration. separator = Separator('spleeter:2stems', multiprocess=False) separator.separate_to_file( str(input_path), output_dir_path, filename_format='{instrument}.{codec}' )
def isolateAudio(tempFile: str, outDir: Path) -> Tuple[np.ndarray, np.ndarray]: separator = Separator('spleeter:4stems', stft_backend='librosa') separator.separate_to_file(tempFile, outDir, filename_format='{instrument}.{codec}') vocals, _ = librosa.load(outDir / 'vocals.wav', sampleRate, mono=True) drums, _ = librosa.load(outDir / 'drums.wav', sampleRate, mono=True) return (vocals, drums)
def splitter(path): '''takes a file name from youtube.py and separates into 5 stems: vocals, drums, bass, piano, and accompaniment''' separator = Separator('spleeter:5stems') audio_loader = get_default_audio_adapter() waveform, rate = audio_loader.load(path, sample_rate=None) prediction = separator.separate(waveform) # tools.clear_wavs() return prediction, rate
def split_song(songfile: Path, song_dir: Path) -> Tuple[str, str]: """Run spleeter to split song into instrumental and vocal tracks""" from spleeter.separator import Separator separator = Separator("spleeter:2stems") separator.separate_to_file(str(songfile), str(song_dir), filename_format="{instrument}.{codec}") return str(song_dir.joinpath("accompaniment.wav")), str( song_dir.joinpath("vocals.wav"))
def split_song(songfile: Path) -> Tuple[Path, Path]: """ Run spleeter to split song into instrumental and vocal tracks """ from spleeter.separator import Separator song_dir = songfile.resolve().with_suffix("") print(song_dir) separator = Separator("spleeter:2stems") separator.separate_to_file(str(songfile), str(song_dir)) return song_dir.joinpath("accompaniment.wav"), song_dir.joinpath( "vocals.wav")
def run_spleeter(audio_file, model='spleeter:5stems'): print('\nPerforming source separation using', model) destination = os.path.splitext(audio_file)[0] if not os.path.exists(destination): separator = Separator(model) separator.separate_to_file(audio_descriptor=audio_file, destination=destination) return destination
def stem_separation(file_path): folder_name = os.path.splitext(os.path.basename(file_path))[0] print(folder_name) separator = Separator("spleeter:4stems") separator.separate_to_file(file_path, stems_folder) bass_path = stems_folder + "/" + folder_name + "/bass.wav" drums_path = stems_folder + "/" + folder_name + "/drums.wav" other_path = stems_folder + "/" + folder_name + "/other.wav" vocals_path = stems_folder + "/" + folder_name + "/vocals.wav" return [bass_path, drums_path, other_path, vocals_path]
class SpleeterSeparator: """Performs source separation using Spleeter API.""" def __init__(self, cpu_separation: bool, bitrate=256): """Default constructor. :param config: Separator config, defaults to None """ self.audio_bitrate = f'{bitrate}k' self.audio_format = 'mp3' self.sample_rate = 44100 self.spleeter_stem = 'config/4stems-16kHz.json' self.separator = Separator(self.spleeter_stem, stft_backend=STFTBackend.LIBROSA if cpu_separation else STFTBackend.TENSORFLOW, multiprocess=False) self.audio_adapter = AudioAdapter.default() def create_static_mix(self, parts, input_path, output_path): """Creates a static mix by performing source separation and adding the parts to be kept into a single track. :param parts: List of parts to keep ('vocals', 'drums', 'bass', 'other') :param input_path: Path to source file :param output_path: Path to output file :raises e: FFMPEG error """ waveform, _ = self.audio_adapter.load(input_path, sample_rate=self.sample_rate) prediction = self.separator.separate(waveform) out = np.zeros_like(prediction['vocals']) part_count = 0 # Add up parts that were requested for key in prediction: if parts[key]: out += prediction[key] part_count += 1 self.audio_adapter.save(output_path, out, self.sample_rate, self.audio_format, self.audio_bitrate) def separate_into_parts(self, input_path, output_path): """Creates a dynamic mix :param input_path: Input path :param output_path: Output path """ self.separator.separate_to_file(input_path, output_path, self.audio_adapter, codec='mp3', duration=None, bitrate=self.audio_bitrate, filename_format='{instrument}.{codec}', synchronous=False) self.separator.join(600)
def startRun(self, file, stems, stemOptions, updateStatus, saveOutput): if not file: updateStatus('No file given to spleeter', True) return self.cleanStorage() stemNo = stems.split(' ')[0] try: updateStatus('Loading Spleeter library') from spleeter.separator import Separator updateStatus('Creating Spleeter instance') separator = Separator(f'spleeter:{stemNo}stems') updateStatus('Starting file separation...') separator.separate_to_file(str(file).strip(), destination=config['STOREDIR'], filename_format='{filename}/{filename}_{instrument}.{codec}') except SpleeterError as e: updateStatus(str(e), True) return except: updateStatus(sys.exc_info()[0], True) return if stemNo == '2': os.rename(f"{config['STOREDIR']}/{file.stem}/{file.stem}_accompaniment.wav", f"{config['STOREDIR']}/{file.stem}/{file.stem}_other.wav") if len(stemOptions[1]): try: self.buildPartialTracks(file, stemOptions[1], updateStatus) except BuildTrackError as e: updateStatus(f'Building tracks failed - {str(e)}') return except FileNotFoundError as e: updateStatus(str(e)) return except: updateStatus(sys.exc_info()[0], True) return try: updateStatus('Removing extra files') self.removeExtraFiles(file, stemOptions) updateStatus('Zipping') make_archive(f"{config['STOREDIR']}/{file.stem}", 'zip', f"{config['STOREDIR']}/{file.stem}") rmtree(f"{config['STOREDIR']}/{file.stem}") except: updateStatus(sys.exc_info()[0], True) return updateStatus('DONE') savePath = saveOutput() if not savePath: updateStatus('Canceled') else: os.replace(f"{config['STOREDIR']}/{file.stem}.zip", savePath)
def split(input_file, sample_rate=44100, model="2stems"): if model.lower() not in ["2stems", "4stems", "5stems"]: print(f"Invalid model: '{model}'. Using '2stems' model instead.") model = "2stems" separator = Separator(f"spleeter:{model}") audio_loader = AudioAdapter.default() waveform, _ = audio_loader.load(input_file.name, sample_rate=sample_rate) # prediction output is a dictionary whose keys contain instrument/stem names # and values the associated waveforms prediction = separator.separate(waveform, "_") return (prediction)
def test_separate_to_file(test_file, configuration, backend): """ Test file based separation. """ tf.reset_default_graph() instruments = MODEL_TO_INST[configuration] separator = Separator(configuration, stft_backend=backend) name = splitext(basename(test_file))[0] with TemporaryDirectory() as directory: separator.separate_to_file(test_file, directory) for instrument in instruments: assert exists(join(directory, '{}/{}.wav'.format(name, instrument)))