Last active
October 24, 2023 20:36
-
-
Save ericdfields/c0c0d3b57a7d32e5f2a03d3b5f2ed701 to your computer and use it in GitHub Desktop.
A python script to take a bunch of session stems and mix them down for quick reference listening
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
# | |
# For when you have a cigar box of SD cards that get dumped onto an external hard drive | |
# https://chat.openai.com/share/7090a9c0-2618-445e-a706-a232cf1d1a29 | |
# | |
import argparse | |
from pydub import AudioSegment | |
from pydub.effects import normalize, compress_dynamic_range | |
import os | |
from multiprocessing import Pool | |
# Define the root directory where your audio stems are located | |
root_directory = "/Volumes/HD1-B/2023" | |
# Function to mix down stems in a folder and apply mastering effects | |
def mix_and_master_stems_in_folder(folder_path): | |
# Create an empty AudioSegment to hold the mix | |
mix = AudioSegment.silent(duration=0) | |
# Iterate through files in the folder | |
for file_name in os.listdir(folder_path): | |
# Check if the file has a ".wav" extension (case-insensitive) | |
if file_name.lower().endswith(".wav"): | |
# Load the stem audio file | |
stem = AudioSegment.from_wav(os.path.join(folder_path, file_name)) | |
# Mix it with the existing mix | |
mix = mix + stem | |
# Apply mastering effects | |
mix = normalize(mix) # Normalize the audio | |
mix = compress_dynamic_range(mix, threshold=-20.0, ratio=2.0) # Apply compression (adjust threshold and ratio as needed) | |
return mix | |
# Function to check if a file already exists and remove it if needed | |
def check_and_remove_if_exists(file_path, remove_preexisting): | |
if os.path.exists(file_path): | |
if remove_preexisting: | |
os.remove(file_path) | |
else: | |
print(f"Skipping '{file_path}' as requested.") | |
return False | |
return True | |
def process_session(datestamped_folder, remove_preexisting, skip_preexisting, destination_path): | |
folder_path = os.path.join(root_directory, datestamped_folder) | |
if os.path.isdir(folder_path): | |
if skip_preexisting: | |
# If skipping preexisting, check if the files already exist and skip the processing | |
wav_output_path = os.path.join(destination_path, f"{datestamped_folder}-mixed.wav") | |
mp3_output_path = os.path.join(destination_path, f"{datestamped_folder}-mixed.mp3") | |
if os.path.exists(wav_output_path) and os.path.exists(mp3_output_path): | |
print(f"Skipping '{datestamped_folder}' as requested.") | |
return | |
# Mix and master the stems for each session | |
session_mix = mix_and_master_stems_in_folder(folder_path) | |
# Create the output file paths with the datestamp in the destination folder | |
wav_output_path = os.path.join(destination_path, f"{datestamped_folder}-mixed.wav") | |
mp3_output_path = os.path.join(destination_path, f"{datestamped_folder}-mixed.mp3") | |
# If the files already exist, check and remove or skip based on the arguments | |
if remove_preexisting: | |
check_and_remove_if_exists(wav_output_path, True) | |
check_and_remove_if_exists(mp3_output_path, True) | |
# Export the mixed and mastered session as WAV and MP3 files | |
session_mix.export(wav_output_path, format="wav") | |
session_mix.export(mp3_output_path, format="mp3") | |
print(f"Mixed and mastered {datestamped_folder} and saved as {wav_output_path} and {mp3_output_path}") | |
def main(): | |
# Create an argument parser | |
parser = argparse.ArgumentParser(description="Mix and master audio stems") | |
# Add a flag to remove preexisting files | |
parser.add_argument("--remove-preexisting", action="store_true", help="Remove preexisting mixed audio files if they exist") | |
# Add a flag to skip preexisting files | |
parser.add_argument("--skip-preexisting", action="store_true", help="Skip processing of preexisting mixed audio files") | |
# Add an optional parameter for a specific folder name | |
parser.add_argument("--folder-name", type=str, help="Process a specific folder by name") | |
# Add an optional parameter for the destination path | |
parser.add_argument("--destination-path", type=str, help="Specify the destination path for exported files") | |
# Add an option to specify the number of processes | |
parser.add_argument("--num-processes", type=int, default=4, help="Number of processes to use for parallel processing (default: 4)") | |
args = parser.parse_args() | |
# Get the list of datestamped folders | |
datestamped_folders = [folder for folder in os.listdir(root_directory) if os.path.isdir(os.path.join(root_directory, folder))] | |
# If a specific folder name is provided, process only that folder | |
if args.folder_name: | |
if args.folder_name in datestamped_folders: | |
datestamped_folders = [args.folder_name] | |
else: | |
print(f"Folder '{args.folder_name}' not found in the root directory.") | |
return | |
# Process each session in parallel with the specified number of processes | |
with Pool(processes=args.num_processes) as pool: | |
# Pass the destination path to the process_session function | |
pool.starmap(process_session, [(folder, args.remove_preexisting, args.skip_preexisting, args.destination_path) for folder in datestamped_folders]) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Audio Mixing and Mastering Script
This Python script allows you to mix and master audio stems, providing a convenient way to combine multiple audio tracks and apply mastering effects. It supports processing audio sessions stored in date-stamped folders and provides options for managing preexisting mixed audio files and specifying a destination path for the exported files.
Prerequisites
Before running this script, make sure you have the following:
Usage
Running the Script
To use the script, follow these steps:
Clone or download this repository to your local machine.
Open a terminal or command prompt.
Navigate to the directory containing the script using the
cd
command.Run the script with the desired options. Here are the available command-line options:
--remove-preexisting
: Remove preexisting mixed audio files if they exist.--skip-preexisting
: Skip processing of preexisting mixed audio files.--folder-name
: Process a specific folder by name.--destination-path
: Specify the destination path for exported files.--num-processes
: Number of processes to use for parallel processing (default: 4).Example usage:
Input Audio
The script expects audio stems to be organized within date-stamped folders, typically within a root directory. For example:
Output
The script will mix and master the audio stems, and the resulting mixed audio files will be saved in the specified
destination-path
or the same folder as the original stems.Example Command
Notes
Make sure to configure the script by setting the
root_directory
variable in the script to the root directory containing your audio stems.You can adjust the mastering effects in the script to suit your preferences.
This script uses the pydub library for audio processing.
License
This script is provided under the MIT License. See LICENSE for details.
You can replace placeholders like
/path/to/export
with actual file paths or adjust the content to fit your specific script and use case.