Ultimate Vocal Remover in Pro Tools
This script uses a python package called audio-separator (https://pypi.org/project/audio-separator/) that can use UVR via the command line. Thanks to @Kitch and @Chris_Shaw for helping me figure out the interleaved section!
sf.ui.proTools.appActivateMainWindow();
// Set Pro Tools session to interleaved
sf.app.proTools.setSessionInterleavedState({interleavedState:true});
// Consolidate the selected clip in Pro Tools
sf.ui.proTools.menuClick({ menuPath: ['Edit', 'Consolidate Clip'], });
// Wait for Modals
sf.ui.proTools.waitForNoModals();
// Invalidate PT API
sf.app.proTools.invalidate();
// Get the path of the selected file in Pro Tools
var fullPath = sf.app.proTools.getFileLocation({
fileFilters: ['SelectedClipsTimeline'],
}).fileLocations[0].path;
// Set Pro Tools session to interleaved state to false
sf.app.proTools.setSessionInterleavedState({interleavedState:false});
// Get the directory of the selected file
var directoryPath = fullPath.substring(0, fullPath.lastIndexOf('/'));
// Compile File Name
var fileName = fullPath.substring(fullPath.lastIndexOf('/') + 1, fullPath.length - 4); // Assumes the file has a 3-character extension
//Path To Processed file
var pathToAudioFiles = `${directoryPath}/${fileName}_(Vocals)_UVR-MDX-NET-Inst_HQ_4.wav`;
// Command line
sf.system.exec({
commandLine: `PATH=/opt/homebrew/bin:$PATH /opt/homebrew/bin/audio-separator "${fullPath}" --model_filename "UVR-MDX-NET-Inst_HQ_4.onnx" --output_dir "${directoryPath}" --output_format=WAV`
});
//Copy the file to the clipboard
sf.file.copyToClipboard({ path: pathToAudioFiles });
sf.ui.proTools.spotFileFromClipboard();
My next step is to make this into a template and add all of the models.
Kitch Membery @Kitch2024-09-11 22:41:16.648ZAwesome @Brandon_Jiaconia!
It would be great to see this transformed into a package and shared on the SoundFlow Store after you have converted it into a Command Template.
Great hangin' with you and the crew in the Zoom session this morning!
- DIn reply toBrandon_Jiaconia⬆:AK @DJAK
Hey @Brandon_Jiaconia Can you let me know if this script still works and how exactly does it work? I use UVR daily so this would be a huge help. I tried your script but all it seems to do is consolidate the selected clip. Is there something I need to install or edit in the script? Also, how does it know if you want to make it an acapella or instrumental? Thanks!
- BBrandon Jiaconia @Brandon_Jiaconia
Hey - Yes this still works. I use it often to extract a voice over or music from a clip in Pro Tools. The current script is set up to make an instrumental and vocal of the selected file in Pro Tools. It is a workaround of a workaround, so the setup is a little complicated.
To start you need to install audio-separator on your computer. There are instructions on their site
https://pypi.org/project/audio-separator/.
For me this is done with a terminal command like 'pip install audio-separator'. Once it finishes, confirm in terminal with 'which audio-separator'. It will return a path like "/opt/homebrew/Caskroom/miniforge/base/bin/audio-separator" You will need this path in your script - Here is the updated script I use, you'll need to change a few things specific to where audio-separator gets installed on your computer:sf.ui.proTools.appActivateMainWindow(); //Selection const selection = sf.ui.proTools.selectionGet(); const timecodeIn = `${selection.selectionStart}`; // Set Pro Tools session to interleaved sf.app.proTools.setSessionInterleavedState({ interleavedState: true }); // Consolidate the selected clip in Pro Tools sf.ui.proTools.menuClick({ menuPath: ['Edit', 'Consolidate Clip'] }); sf.ui.proTools.waitForNoModals(); sf.app.proTools.invalidate(); // Get the path of the selected file in Pro Tools var fullPath = sf.app.proTools.getFileLocation({ fileFilters: ['SelectedClipsTimeline'], }).fileLocations[0].path; // Build paths var directoryPath = fullPath.substring(0, fullPath.lastIndexOf('/')); var fileName = fullPath.substring(fullPath.lastIndexOf('/') + 1, fullPath.length - 4); fileName = fileName.replace(/\.L|\.R$/, ''); // Disable interleaved again sf.app.proTools.setSessionInterleavedState({ interleavedState: false }); // Output files expected by UVR naming var vocalFile = `${directoryPath}/${fileName}_(Vocals)_UVR-MDX-NET-Inst_HQ_4.wav`; var instrumentalFile = `${directoryPath}/${fileName}_(Instrumental)_UVR-MDX-NET-Inst_HQ_4.wav`; // command line sf.system.exec({ commandLine: `PATH="/opt/homebrew/bin:/opt/homebrew/sbin:$PATH"; \ /opt/homebrew/Caskroom/miniforge/base/bin/audio-separator \ "${fullPath}" \ --model_filename UVR-MDX-NET-Inst_HQ_4.onnx \ --output_dir "${directoryPath}" \ --output_format WAV` }); //Destination Tracks sf.app.proTools.selectTracksByName({ trackNames: ["Dial 7"], }); // Copy the file to the clipboard sf.file.copyToClipboard({ path: vocalFile }); sf.ui.proTools.spotFileFromClipboard(); sf.ui.proTools.waitForNoModals(); sf.app.proTools.selectTracksByName({ trackNames: ["Music_10"], }); // Copy the file to the clipboard sf.file.copyToClipboard({ path: instrumentalFile }); sf.ui.proTools.spotFileFromClipboard(); sf.ui.proTools.waitForNoModals();Now in this section you need to change the script to work with your install location:
// command line sf.system.exec({ commandLine: `PATH="/opt/homebrew/bin:/opt/homebrew/sbin:$PATH"; \ /opt/homebrew/Caskroom/miniforge/base/bin/audio-separator \ "${fullPath}" \ --model_filename UVR-MDX-NET-Inst_HQ_4.onnx \ --output_dir "${directoryPath}" \ --output_format WAV` });You need to swap my install path "/opt/homebrew/Caskroom/miniforge/base/bin/audio-separator " with the install location that was returned when you entered 'which audio-separator' in terminal.
I have this setup up to work with my template, so you will need to change the names of these destination tracks to something that works in your session, in my case here the tracks are named Dial 7 and Music_10, these both need to be stereo tracks!
//Destination Tracks sf.app.proTools.selectTracksByName({ trackNames: ["Dial 7"], }); // Copy the file to the clipboard sf.file.copyToClipboard({ path: vocalFile }); sf.ui.proTools.spotFileFromClipboard(); sf.ui.proTools.waitForNoModals(); sf.app.proTools.selectTracksByName({ trackNames: ["Music_10"], });
- DIn reply toBrandon_Jiaconia⬆:AK @DJAK
Thanks for the break down. I'm not able to download audio separator for some reason. maybe it's my Mac OSX version or M1 processor or something. This is what i'm getting when trying to install:
djak@DJ-AKs-MacBook-Pro ~ % pip install audio-separator
DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. pip 21.0 will drop support for Python 2.7 in January 2021. More details about Python 2 support in pip can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support pip 21.0 will remove support for this functionality.
ERROR: Could not find a version that satisfies the requirement audio-separator (from versions: none)
ERROR: No matching distribution found for audio-separator
djak@DJ-AKs-MacBook-Pro ~ % pip install "audio-separator[cpu]"
DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. pip 21.0 will drop support for Python 2.7 in January 2021. More details about Python 2 support in pip can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support pip 21.0 will remove support for this functionality.
ERROR: Could not find a version that satisfies the requirement audio-separator[cpu] (from versions: none)
ERROR: No matching distribution found for audio-separator[cpu]
djak@DJ-AKs-MacBook-Pro ~ % pip install audio-separator
DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. pip 21.0 will drop support for Python 2.7 in January 2021. More details about Python 2 support in pip can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support pip 21.0 will remove support for this functionality.
ERROR: Could not find a version that satisfies the requirement audio-separator (from versions: none)
ERROR: No matching distribution found for audio-separator
djak@DJ-AKs-MacBook-Pro ~ %tried both: pip install "audio-separator[cpu]" and pip install audio-separator
I have the latest python installed as well 3.14
Did I need to install anything else? I'm using Terminal.
- BBrandon Jiaconia @Brandon_Jiaconia
Try directly using the updated python version in your terminal command
python3 -m pip install "audio-separator[cpu]"
or
pip3 install "audio-separator[cpu]"When I first set this up I was using an M1, so should be all good
- DIn reply toBrandon_Jiaconia⬆:AK @DJAK
Was able to get Terminal to use python3 instead of the built in version but now stuck at this error:
Additionally, some packages in these conflicts have no matching distributions available for your environment:
onnxruntime
onnxruntime-siliconTo fix this you could try to:
- loosen the range of package versions you've specified
- remove package versions to allow pip to attempt to solve the dependency conflict
ERROR: ResolutionImpossible: for help visit https://pip.pypa.io/en/latest/topics/dependency-resolution/#dealing-with-dependency-conflicts
I'm guessing this is preventing audio separator from installing, because when I enter "'which audio-separator'" I get this: zsh: command not found: which audio-separator
Would you be able to do a youtube or post on the forum (if its allowed) where you create a guide or show how to get everything setup? If you have the time of course.
But using UVR with pro-tools will be a huge game-changer for alot of us. Currently, I use a soundflow script to create a copy of the clip to my desktop. Then I open UVR, drag the file in, select vocals or instrumental and process it. Then I drag the processed file back into pro-tools and continue working.
- BBrandon Jiaconia @Brandon_Jiaconia
The problem is I'm not a python or terminal expert at all ! So I dont know if a video would actually be very helpful or accurate for everybody. I have set this up on a few computers, and it's always a little specific to that computer and python setup. On some I've had to create a virtual environment and install python/audio-sep fresh in that location. On others it was much easier by following the terminal steps I outlined above. I can look at expanding the script to include all the models and making this more user friendly
That said I think whats going on in your case is a mismatch between a newer version of python and an older version of onnxruntime, but again I'm not a python expert !Yes, looking further, It seems the onnxruntime doesn't work past python V3.9 and I'm on the latest 3.14.
I installed 3.9 and attempted the reinstall via Terminal and this version threw tons of red errors lol. I will stop now before I mess something up in my system and not be able to work 😂
- BBrandon Jiaconia @Brandon_Jiaconia
Here is a reformatted script that incorporates all the MDX models.
// Path To Audio Separator const separatorPath = "/Users/bj018/audio-sep-env/bin/audio-separator"; // MDX model list var modelFiles = [ "UVR-MDX-NET-Inst_HQ_1.onnx", "UVR-MDX-NET-Inst_HQ_2.onnx", "UVR-MDX-NET-Inst_HQ_3.onnx", "UVR-MDX-NET-Inst_HQ_4.onnx", "UVR-MDX-NET-Inst_HQ_5.onnx", "UVR_MDXNET_Main.onnx", "UVR-MDX-NET-Inst_Main.onnx", "UVR_MDXNET_1_9703.onnx", "UVR_MDXNET_2_9682.onnx", "UVR_MDXNET_3_9662.onnx", "UVR-MDX-NET-Inst_1.onnx", "UVR-MDX-NET-Inst_2.onnx", "UVR-MDX-NET-Inst_3.onnx", "UVR_MDXNET_KARA.onnx", "UVR_MDXNET_KARA_2.onnx", "UVR_MDXNET_9482.onnx", "UVR-MDX-NET-Voc_FT.onnx", "Kim_Vocal_1.onnx", "Kim_Vocal_2.onnx", "Kim_Inst.onnx", "Reverb_HQ_By_FoxJoy.onnx", "UVR-MDX-NET_Crowd_HQ_1.onnx", "kuielab_a_vocals.onnx", "kuielab_a_other.onnx", "kuielab_a_bass.onnx", "kuielab_a_drums.onnx", "kuielab_b_vocals.onnx", "kuielab_b_other.onnx", "kuielab_b_bass.onnx", "kuielab_b_drums.onnx", "UVR-MDX-NET_Main_340.onnx", "UVR-MDX-NET_Main_390.onnx", "UVR-MDX-NET_Main_406.onnx", "UVR-MDX-NET_Main_427.onnx", "UVR-MDX-NET_Main_438.onnx", "UVR-MDX-NET_Inst_82_beta.onnx", "UVR-MDX-NET_Inst_90_beta.onnx", "UVR-MDX-NET_Inst_187_beta.onnx", "UVR-MDX-NET-Inst_full_292.onnx" ]; // Custom stem names for certain models const stemOverrides = { "Reverb_HQ_By_FoxJoy": ["(No Reverb)", "(Reverb)"], "UVR-MDX-NET_Crowd_HQ_1": ["(No Crowd)", "(Crowd)"], "kuielab_a_other": ["(No Other)", "(Other)"], "kuielab_a_bass": ["(No Bass)", "(Bass)"], "kuielab_a_drums": ["(No Drums)", "(Drums)"], "kuielab_b_other": ["(No Other)", "(Other)"], "kuielab_b_bass": ["(No Bass)", "(Bass)"], "kuielab_b_drums": ["(No Drums)", "(Drums)"] }; // pop up[ search var modelChoice = sf.interaction.popupSearch({ title: "Choose MDX Model", items: modelFiles.map(filename => ({ name: filename.replace(/\.onnx$/, ''), value: filename })) }).item; // Model Variables var selectedModelWithExt = modelChoice.value; var modelNameNoExt = modelChoice.name; //Get the selections in & out points. const selection = sf.ui.proTools.selectionGet(); // Set Pro Tools session to interleaved sf.app.proTools.setSessionInterleavedState({ interleavedState: true }); // Consolidate the target clip in Pro Tools sf.ui.proTools.menuClick({ menuPath: ['Edit', 'Consolidate Clip'] }); sf.ui.proTools.waitForNoModals(); // Invalidate PT API sf.app.proTools.invalidate(); // Get the path of the target file in Pro Tools var fullPath = sf.app.proTools.getFileLocation({ fileFilters: ['SelectedClipsTimeline'], }).fileLocations[0].path; // Set Pro Tools session to interleaved state to false sf.app.proTools.setSessionInterleavedState({ interleavedState: false }); // Get the directory of the target file var directoryPath = fullPath.substring(0, fullPath.lastIndexOf('/')); // Compile File Name without .L or .R suffix var fileName = fullPath.substring(fullPath.lastIndexOf('/') + 1, fullPath.length - 4); // Assumes the file has a 3-character extension fileName = fileName.replace(/\.L|\.R$/, ''); // Remove .L or .R from the filename // Processed files const [stem1, stem2] = stemOverrides[modelNameNoExt] || ["(Vocals)", "(Instrumental)"]; var vocalFile = `${directoryPath}/${fileName}_${stem1}_${modelNameNoExt}.wav`; var instrumentalFile = `${directoryPath}/${fileName}_${stem2}_${modelNameNoExt}.wav`; //command line sf.system.exec({ commandLine: `${separatorPath} "${fullPath}" --model_filename "${selectedModelWithExt}" --output_dir "${directoryPath}" --output_format=WAV` }); sf.app.proTools.importAudio({ sourcePaths: [vocalFile, instrumentalFile], audioFileHandling: "ConvertAudio", location: "Selection", destination: "NewTrack" });Once you get audio-separator installed you only need to swap out the path to it at the top of the script
// Path To Audio Separator const separatorPath = "/Users/bj018/audio-sep-env/bin/audio-separator";Looking on my work computer today, it looks like I had to also make new virtual environment when I set this one up awhile back.