Last active
January 22, 2022 16:41
-
-
Save tandy-1000/1a9550249b0929979d37e9ecc680c4b3 to your computer and use it in GitHub Desktop.
demucser.nim
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import std/[os, osproc, logging, algorithm] | |
const | |
LOGFILE = "demucser.log" | |
FFMPEG_CMD = "/usr/bin/ffmpeg" | |
SOX_CMD = "/usr/bin/sox" | |
SEGMENT_TIME = 5 | |
SEGMENT_FOLDER = "segments" | |
DEMUCS = "/usr/bin/python3.9" | |
DEMUCS_FOLDER = "separated" | |
DEMUCS_MODEL = "mdx_q" | |
DEMUCS_FILES = SEGMENT_FOLDER & "/" & DEMUCS_FOLDER & "/" & DEMUCS_MODEL | |
var fileLog = newFileLogger(LOGFILE) | |
proc segmentFile(path: string, outFolder: string = SEGMENT_FOLDER, ffmpegCmd: string = FFMPEG_CMD, segmentTime: int = SEGMENT_TIME) = | |
discard os.existsOrCreateDir(outFolder) | |
let | |
outFile = outFolder & '/' & "out%05d" & os.splitFile(path).ext | |
args = ["-i", path, "-f", "segment", "-segment_time", $segmentTime, "-c", "copy", outFile] | |
output = osproc.execProcess(ffmpegCmd, args = args, options = {poStdErrToStdOut}) | |
fileLog.log(lvlInfo, output) | |
proc demucsFile(file: string, demucsCmd: string = DEMUCS, demucsModel: string = DEMUCS_MODEL) = | |
let | |
args = ["-m", "demucs", "-d", "cpu", "-n", demucsModel, file] | |
output = osproc.execProcess(demucsCmd, args = args, options = {poStdErrToStdOut}) | |
fileLog.log(lvlInfo, output) | |
proc demucsSegments(folder: string = SEGMENT_FOLDER) = | |
os.setCurrentDir folder | |
for file in os.walkFiles("*"): | |
echo file | |
demucsFile file | |
os.setCurrentDir os.getAppDir() | |
proc getSourceSegments(source: string, folder: string = DEMUCS_FILES): seq[string] = | |
var files: seq[string] | |
for subFolder in os.walkDir(folder): | |
for file in os.walkDir(subFolder.path): | |
let | |
path = file.path | |
split = os.splitFile path | |
if split.name == source: | |
files.add path | |
result = sorted(files) | |
proc concatSegments(soxCmd: string = SOX_CMD) = | |
let sources = ["bass", "drums", "other", "vocals"] | |
for source in sources: | |
let | |
segments = getSourceSegments(source) | |
fileName = source & ".wav" | |
args = segments & @[fileName] | |
output = osproc.execProcess(soxCmd, args = args, options = {poStdErrToStdOut}) | |
fileLog.log(lvlInfo, output) | |
when isMainModule: | |
let path = "~/Downloads/Nobue's Sea/08 Ai No Shizuku.flac" | |
segmentFile(path) | |
demucsSegments() | |
concatSegments() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
A script that uses ffmpeg and sox to run demucs in chunks. Allows machines with less RAM to run demucs on full songs.