But your tool still needs to calculate what overall level boost gets you to a peak of -3 dBFS
That's been handled (although I haven't changed it from -1 to -3 yet - the highlighted part of final masters going to -1 has me leaning towards not being that far off with my first value)
Here's the python script that handles the multichannel portion - been splitting these processes out to separate scripts for the multi and stereo, since the final tool may need to call on stereo only discs, or I might have a disc that I want to skip the stereo portion of when converting.
Not sure if this is of use to anyone - but thought it may be fun to share a sample of the types of things I have AI writing for me. Will share more when I have a finished process.
import os
import subprocess
import re
import sys
# Configuration
base_output = r"M:\Staging\SACDout"
ffmpeg_path = r"C:\Program Files\FFmpeg\bin\ffmpeg.exe"
sox_path = r"C:\Program Files (x86)\sox-14-4-2\sox.exe"
multi_dir = os.path.join(base_output, "Multichannel")
# Check directory
if not os.path.isdir(multi_dir):
print(f"Error: Multichannel directory not found in {base_output}")
sys.exit(1)
def get_peak_level(dsf_file):
cmd = f'"{ffmpeg_path}" -i "{dsf_file}" -f f32le -ar 88200 - | "{sox_path}" -t raw -r 88200 -e float -b 32 - -n stats'
print(f"Running: {cmd}")
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
if result.returncode != 0:
print(f"Failed for {dsf_file}: {result.stderr}")
return None
output = result.stderr
# Parse single max peak for all channels
peak_match = re.search(r"Pk lev dB\s+(-?\d+\.\d+)", output)
if peak_match:
return [float(peak_match.group(1))]
print(f"No peak levels found for {dsf_file}: {output}")
return None
def analyze_peaks_multichannel():
print(f"\nAnalyzing Multichannel files in {multi_dir}:")
all_peaks = []
for file in os.listdir(multi_dir):
if file.endswith(".dsf"):
dsf_path = os.path.join(multi_dir, file)
peaks = get_peak_level(dsf_path)
if peaks:
print(f" {file}: Max Peak {peaks[0]} dBFS")
all_peaks.extend(peaks)
if not all_peaks:
print("No valid peaks found in Multichannel directory.")
return 0.0
max_peak = max(all_peaks)
gain = round(-1 - max_peak, 1) # Target -1 dBFS with 1 dB buffer
print(f"Multichannel Max Peak: {max_peak} dBFS, Suggested Gain: {gain} dB")
return gain
if __name__ == "__main__":
gain = analyze_peaks_multichannel()
print(f"\nMultichannel peak analysis complete! Returning gain: {gain}")