@Echo OFF
SETLOCAL EnableDelayedExpansion
SETLOCAL ENABLEEXTENSIONS
TITLE Devinyl
:: Description: Vinyl Magic: vinyl subsonic filter, equipment corrections, and more
:: Usage: devinyl.cmd input-filename.wav (speedup factor)
:: (or no file name to process "input.wav"
:: output file name will have -processed.wav at end)
:: Author: Harby - stevehoffman.tv forums
:: Free for non-commercial hobbyist use
:: commercial azimuth use and future features (turntable setups, restoration..) TBD
:: ---- SETTINGS BELOW MUST BE CUSTOMIZED to your wants and needs ----
:SETTINGS
:: Adjust signal imbalance of phono pre and ADC electric path, dB. Negative: turn up left side
:: (this...if you can't send a low-level test signal into phono-in, mono it with y cables, and adjust your knobbies)
SET inchannelbalance=0.20
:: Signature/Profile-based noise reduction? (yes/no) 1st pass, for electrical noise/hum
:: (Must put 2+ seconds of "electric" silence at the start of file)
SET usenoisereduction=no
:: Noise reduction amount (of 0 to 1); heavy-handed even at 0.1, increase at your own peril:
SET NRstrength=0.9
SET NRseconds=2
:: Signature/Profile-based noise reduction? (yes/no) - 2st pass, mid-side, for vinyl noise
:: Must put more "surface noise" silence at the start of file -- after first silence segment
SET midsideNR=no
SET NR2strength=0.5
:: Seconds is the total number of seconds added AFTER the first segment of electric noise
SET NR2seconds=2
:: Magical cartridge azimuth correction in degrees (0 to disable and skip)
:: (use negative degrees if electrical alignment is twisted counter-clockwise looking from front)
SET azimuthsettingindegrees=0.9
:: Crosstalk specification of cartridge in minus dB, eg -29, or as discovered from analysis
:: (More crosstalk correction can also be used as a widening effect)
:: (disabled at 0 or positive numbers)
SET crosstalkdb=-32.0
:: If cartrige crosstalk is inverted/out-of-phase and actually over-widens the stereo? (yes/no)
SET iscrosstalkinverted=yes
:: If one calibrated channel still quieter after azimuth & crosstalk correction (total dB change). Negative: turn up left side
:: (this would be your cartridge's electrical channel imbalance)
SET channelbalance=-0.19
:: Subsonic resonance cutoff frequency, Hz (extremely sharp cut below, little effect above)
:: (0 to disable and skip)
SET sub=22
:: use 10th order Butterworth filter instead of even sharper sinc function?
SET butterworth=no
:: frequency of milder side-channel vertical rumble reduction
SET sidesub=70
:: Speed correction for reduced-speed disc transfers (using your normal RIAA preamp)
:: Set to 1.35 for 45 played at 33, etc (1.0 to skip)
:: Command line option will override
SET speedup=1.00
REM speedup=1.23496
:: the speedup performs resampling at 192kHz+; if you don't want your new high-resolution, set lower:
:: (use standard sample rates like 44.1 48 88.2 96 192)
SET speedupdownsample=96
SET usemidsideprocessing=yes
:: (if not set to yes, all mid-side magic including noise reduction is skipped)
:: Side-channel bass correction, in positive dB; 5 will restore width from a 150Hz 1st order highpass used in mastering
SET sidebassboostdb=1.3
:: Adjust output file to peak level, set to -dB. A positive integer to disable
SET normalizeto=2
:: Internal settings; set verbose to 3 to see all sox output, but will disable future clip detection
SET verbose=2
SET buffer=131072
SET progressbar=yes
SET processinggainreduction=6
SET disablecleanuptempfiles=no
:: This function instead takes a SHORT audio input file (like a test LP channel separation track) and
:: repeatedly steps it through a range of azimuth corrections, so you can analyze compiled output
SET forceazimuthanalysis=yes
:: Center position (degrees)
SET center=0
:: Width on each side of center (degrees) (if negative, stepping goes from + to - (cw to CCW), maybe confusing)
SET fromcenter=5
:: (if number of steps below is even, you don't get center point)
SET steps=41
:: similar, but doesn't do trigonometry, just an internal table from -5 to 5 degrees
:: this version is not filtered for automated analysis
SET forcereferencesteps=no
:SETTINGSDONE
:: PROGRAM STARTS HERE
IF /i "%forceazimuthanalysis%"=="yes" GOTO :findazimuth
IF /i "%~1"=="findazimuth" GOTO :findazimuth
IF /i "%2"=="findazimuth" GOTO :findazimuth %1
IF /i "%forcereferencesteps%"=="yes" GOTO :referencesteps
IF /i "%~1"=="referencesteps" GOTO :referencesteps
IF /i "%2"=="referencesteps" GOTO :referencesteps %1
CALL :setup %1 %2 %3 %4 %5
IF NOT %ERRORLEVEL%==0 (echo ..quitting due to setup function subroutine errors & CALL :cleanup & EXIT /B 1)
CALL :makeinput
IF NOT %ERRORLEVEL%==0 (echo ..quitting due to makeinput subroutine errors & CALL :cleanup & EXIT /B 1)
CALL :balancechannels %inchannelbalance%
IF NOT %ERRORLEVEL%==0 (echo ..quitting due to channel balance subroutine errors & CALL :cleanup & EXIT /B 1)
IF /I "%usenoisereduction%"=="yes" (CALL :noisereduction %NRstrength%) ELSE (ECHO STATUS: Skipping noise reduction)
IF NOT %ERRORLEVEL%==0 (echo ..quitting due to noisereduction errors & CALL :cleanup & EXIT /B 1)
CALL :azimuthcorrection %azimuthsettingindegrees%
IF NOT %ERRORLEVEL%==0 (echo ..quitting due to azimuthcorrection subroutine errors & CALL :cleanup & EXIT /B 1)
CALL :crosstalk %iscrosstalkinverted% %crosstalkdb%
IF NOT %ERRORLEVEL%==0 (echo ..quitting due to crosstalk errors & CALL :cleanup & EXIT /B 1)
CALL :balancechannels %channelbalance%
IF NOT %ERRORLEVEL%==0 (echo ..quitting due to channel balance subroutine errors & CALL :cleanup & EXIT /B 1)
CALL :subsonic %sub%
IF NOT %ERRORLEVEL%==0 (echo ..quitting due to makeinput subroutine errors & CALL :cleanup & EXIT /B 1)
CALL :speedup %speedup%
IF NOT %ERRORLEVEL%==0 (echo ..quitting due to speedup errors & CALL :cleanup & EXIT /B 1)
IF /I "%usemidsideprocessing%"=="yes" (CALL :midside) ELSE (ECHO STATUS: Skipping all mid-side processing)
IF NOT %ERRORLEVEL%==0 (echo ..quitting due to midside function errors & CALL :cleanup & EXIT /B 1)
IF /I "%usemidsideprocessing%"=="yes" (CALL :midchannel)
IF NOT %ERRORLEVEL%==0 (echo ..quitting due to midchannel errors & CALL :cleanup & EXIT /B 1)
IF /I "%usemidsideprocessing%"=="yes" (CALL :sidechannel)
IF NOT %ERRORLEVEL%==0 (echo ..quitting due to sidechannel errors & CALL :cleanup & EXIT /B 1)
IF /I "%usemidsideprocessing%"=="yes" (CALL :unmidside)
IF NOT %ERRORLEVEL%==0 (echo ..quitting due to unmidside errors & CALL :cleanup & EXIT /B 1)
CALL :makeoutput %outfile%
IF NOT %ERRORLEVEL%==0 (echo ..quitting due to makeoutput errors & CALL :cleanup & EXIT /B 1)
PAUSE
CALL :cleanup
IF NOT %ERRORLEVEL%==0 (echo ..cleanup function had an error & EXIT /B 1)
EXIT /B 0
==== SUBROUTINES ====
:setup
:: TODO: search path and also install location for sox, set full location (and replace every call with variable)
sox --version >NUL 2>NUL
IF %ERRORLEVEL%==9009 (CALL :nosox)
sox --version >NUL 2>NUL
IF NOT %ERRORLEVEL%==0 (ECHO === SOX.EXE problem! SOX.EXE IS STILL MISSING OR ERRORS OUT & exit /b %ERRORLEVEL%)
rem echo parameters f1 2: %~f1 %2
rem echo parameters per1: %1
IF '%1'=='' GOTO :defaultfile
:: use full input file paths and temp directory
SET inpath=%~dp1
SET filebase=%~n1
SET fileext=%~x1
SET tempdir=%temp%\
SET outfile="%inpath%%filebase%-processed.wav"
GOTO :donesettingfiles
:defaultfile
:: default to no paths and default file name
SET inpath=
SET filebase=devinyl
SET fileext=.wav
SET tempdir=%temp%\
SET outfile="output-devinyl.wav"
:donesettingfiles
rem ECHO inpath---%inpath%
rem ECHO filebase---%filebase%
rem ECHO fileext---%fileext%
rem ECHO outfile---%outfile%
SET infile="%inpath%%filebase%%fileext%"
IF '%1'=='' SET infile="input.wav"
rem ECHO --- infile: %infile%
IF NOT "%2"=="" (SET speedup=%2)
IF NOT EXIST %infile% (GOTO :nofile & EXIT /B 1)
IF EXIST %outfile% DEL %outfile% & IF EXIST %outfile% (set DELERROR=1 & GOTO :cantdel)
set temp1file="%tempdir%%filebase%-temp1.wav"
IF EXIST %temp1file% DEL %temp1file% & IF EXIST %temp1file% (set DELERROR=1 & GOTO :cantdel)
set temp2file="%tempdir%%filebase%-temp2.wav"
IF EXIST %temp2file% DEL %temp2file% & IF EXIST %temp2file% (set DELERROR=1 & GOTO :cantdel)
set midfile="%tempdir%%filebase%-midtemp.wav"
IF EXIST %midfile% DEL %midfile% & IF EXIST %midfile% (set DELERROR=1 & GOTO :cantdel)
set sidefile="%tempdir%%filebase%-sidetemp.wav"
IF EXIST %sidefile% DEL %sidefile% & IF EXIST %sidefile% (set DELERROR=1 & GOTO :cantdel)
set noiseprofile="%tempdir%%filebase%-noiseprofile.wav"
IF EXIST %noiseprofile% DEL %noiseprofile% & IF EXIST %noiseprofile% (set DELERROR=1 & GOTO :cantdel)
IF "%DELERROR%"=="1" (EXIT /B 1)
call :subsetup
IF NOT %ERRORLEVEL%==0 (ECHO ERROR returned by subsetup & exit /b 1)
:setupdone
EXIT /B 0
:subsetup
:: subroutines need these, along with a temp1file input/output file defined
IF EXIST %tempdir%Math.vbs DEL %tempdir%Math.vbs >NUL
echo Wscript.echo Round(eval(WScript.Arguments(0)),15) >%tempdir%Math.vbs
echo WScript.Quit 2 >>%tempdir%Math.vbs
echo ' quit 2 shouldn't be reached if there is an error above it >>%tempdir%Math.vbs
set Result=ERROR
Call:Math round((%sub%), 0)
IF %Result%==ERROR (ECHO ERROR: Math function call in setup & EXIT /B 1)
set sub=%Result%
Call:Math round((%sidesub%), 0)
IF %Result%==ERROR (ECHO ERROR: Math function call in setup & EXIT /B 1)
set sidesub=%Result%
Call:Math round((%sidebassboostdb%), 4)
IF %Result%==ERROR (ECHO ERROR: Math function call in setup & EXIT /B 1)
set sidebassboostdb=%Result%
Call:Math round((%crosstalkdb%), 4)
IF %Result%==ERROR (ECHO ERROR: Math function call in setup & EXIT /B 1)
set crosstalkdb=%Result%
Call:Math round((%channelbalance%), 4)
IF %Result%==ERROR (ECHO ERROR: Math function call in setup & EXIT /B 1)
set channelbalance=%Result%
Call:Math round((%speedup%), 8)
IF %Result%==ERROR (ECHO ERROR: Math function call in setup & EXIT /B 1)
set speedup=%Result%
Call:Math round((%normalizeto%), 4)
IF %Result%==ERROR (ECHO ERROR: Math function call in setup & EXIT /B 1)
set normalizeto=%Result%
IF /I "%progressbar%"=="yes" SET progress=-S
:butterworth 10th order
SET ch1q=0.5062 & SET ch2q=0.5612 & SET ch3q=0.7071 & SET ch4q=1.1013 & SET ch5q=3.1970
SET ch1f=%sub% & SET ch2f=%sub% & SET ch3f=%sub% & SET ch4f=%sub% & SET ch5f=%sub%
:subsetupdone
EXIT /B 0
:makeinput
ECHO === Start: processing input ======================
:: MUST CALL THIS FUNCTION FIRST TO READ INPUT FILENAME to first temp file
sox --multi-threaded --buffer=%buffer% -V1 %progress% %infile% -b 32 %temp1file% ^
gain -%processinggainreduction% ^
pad 2 2
:makeinputdone
IF NOT EXIST %temp1file% (ECHO fail creating work from input file & EXIT /B 1)
EXIT /B 0
:subsonic
IF NOT "%1"=="" SET sub=%1
IF "%ch1q%"=="" call :subsetup
IF "%2"=="" SET butterworth=no
IF %sub% EQU 0 GOTO :subsonicdone
ECHO === Stage start: subsonic resonance filter ======================
IF /I "%butterworth%"=="no" (
sox --multi-threaded --buffer=%buffer% -V%verbose% %progress% %temp1file% %temp2file% ^
sinc -L %sub% -n 32767 ^
reverse ^
sinc -L %sub% -n 32767 ^
reverse
IF !%ERRORLEVEL%! NEQ 0 (ECHO ERROR: Sox: subsonic filter %sub% Hz & EXIT /B 1)
) ELSE (
:: sox command for 10th order
sox --multi-threaded --buffer=%buffer% -V%verbose% %progress% %temp1file% %temp2file% ^
highpass %ch1f% %ch1q% highpass %ch2f% %ch2q% highpass %ch3f% %ch3q% highpass %ch4f% %ch4q% highpass %ch5f% %ch5q% ^
reverse ^
highpass %ch1f% %ch1q% highpass %ch2f% %ch2q% highpass %ch3f% %ch3q% highpass %ch4f% %ch4q% highpass %ch5f% %ch5q% ^
reverse
IF !%ERRORLEVEL%! NEQ 0 (ECHO ERROR: Sox: subsonic filter %sub% Hz & EXIT /B 1)
)
:subsonicdone
IF NOT EXIST %temp1file% (ECHO subsonic fail creating output & EXIT /B 1)
EXIT /B 0
:azimuthcorrection
:: input: (degrees in 360, range -45 to 45) (mute)
:: input: setup variables
:: input file: temp1file output file: temp1file
SET azimuthindegrees=%1
SET azmuted=no
IF /I "%2"=="mute" SET azmuted=mute
SET Result=ERROR
Call:Math round((%azimuthindegrees%), 14)
IF %Result%==ERROR ECHO ERROR: Math function call in setup & EXIT /B 1
SET azimuthindegrees=%Result%
Call:Math int(round((abs(%azimuthindegrees%) * 5000), 0))
IF %Result%==ERROR ECHO ERROR: Math function call in setup & EXIT /B 1
IF %Result% GTR 225000 (ECHO ERROR: Azimuth correction at %azimuthindegrees% is impossible & EXIT /B 1)
IF NOT "%azmuted%"=="mute" ECHO === Stage start: azimuth correction ======================
call :getazimuth %azimuthindegrees% %azmuted%
IF %ERRORLEVEL% NEQ 0 (ECHO ERROR: calling getazimuth with %azimuthindegrees% degrees & EXIT /B %ERRORLEVEL%)
Call:Math Int(abs(%azimuthOppdB%))
IF %Result%==ERROR (ECHO ERROR: Math function call failed in azimuth: checking db levels oppdb & EXIT /B 1)
IF %Result% EQU 0 (ECHO ERROR: calling getazimuth with %azimuthindegrees% degrees gave %azimuthOppdB% dB Opp & EXIT /B 1)
Call:Math Int(abs(%azimuthSamedB%))
IF %Result%==ERROR (ECHO ERROR: Math function call failed in getazimuth checking db levels samedb & EXIT /B 1)
IF %Result% EQU 0 (ECHO ERROR: calling getazimuth with %azimuthindegrees% degrees gave %azimuthSamedB% dB & EXIT /B 1)
if "%isazimuthclockwise%"=="yes" (
:cwazimuth
sox --multi-threaded --buffer=%buffer% -V%verbose% %progress% %temp1file% %temp2file% ^
remix 1p,1p%azimuthSamedB%,2i%azimuthOppdB%, 2p,2p%azimuthSamedB%,1p%azimuthOppdB%
IF !%ERRORLEVEL%! NEQ 0 (ECHO ERROR: Sox: clockwise azimuth & EXIT /B 1)
) ELSE (
:ccwazumuth
sox --multi-threaded --buffer=%buffer% -V%verbose% %progress% %temp1file% %temp2file% ^
remix 1p,1p%azimuthSamedB%,2p%azimuthOppdB%, 2p,2p%azimuthSamedB%,1i%azimuthOppdB%
IF !%ERRORLEVEL%! NEQ 0 (ECHO ERROR: Sox: counterclockwise azimuth & EXIT /B 1)
)
:azimuthcorrectiondone
IF EXIST %temp2file% (DEL %temp1file% & move %temp2file% %temp1file% >NUL ) ELSE (ECHO azimuth fail moving output & EXIT /B 1)
IF NOT EXIST %temp1file% (ECHO ERROR: azimuth correction fail creating output & EXIT /B 1)
IF NOT "%azmuted%"=="mute" echo Applied %azimuthdeg% degrees correction:
IF NOT "%azmuted%"=="mute" echo Same: %azimuthSamedB% dB Opposite: %azimuthOppdB% dB Clockwise: %isazimuthclockwise%
EXIT /B 0
:azimuthcorrectionspread
:: input: (degrees in 360, range -45 to 45) (mute)
:: input: setup variables
:: input file: temp1file output file: temp1file
SET azimuthindegrees=%1
SET azimuthspread=%2
SET azmuted=no
IF /I "%3"=="mute" SET azmuted=mute
SET Result=ERROR
Call:Math round((%azimuthindegrees%), 14)
IF %Result%==ERROR ECHO ERROR: Math function call in setup & EXIT /B 1
SET azimuthindegrees=%Result%
Call:Math int(round((abs(%azimuthindegrees%) * 5000), 0))
IF %Result%==ERROR ECHO ERROR: Math function call in setup & EXIT /B 1
IF %Result% GTR 225000 (ECHO ERROR: Azimuth correction at %azimuthindegrees% is impossible & EXIT /B 1)
SET Result=ERROR
Call:Math round((%azimuthspread%), 14)
IF %Result%==ERROR ECHO ERROR: Math function call in setup & EXIT /B 1
SET azimuthspread=%Result%
Call:Math int(round((abs(%azimuthspread%) * 5000), 0))
IF %Result%==ERROR ECHO ERROR: Math function call in setup & EXIT /B 1
IF %Result% GTR 125000 (ECHO ERROR: Azimuth spread correction at %azimuthspread% is impossible & EXIT /B 1)
IF NOT "%azmuted%"=="mute" ECHO === Stage start: azimuth correction ======================
call :getazimuthspread %azimuthindegrees% %azimuthspread% %azmuted%
IF %ERRORLEVEL% NEQ 0 (ECHO ERROR: calling getazimuth with %azimuthindegrees% degrees & EXIT /B %ERRORLEVEL%)
Call:Math Int(abs(%azimuthOppdB%))
IF %Result%==ERROR (ECHO ERROR: Math function call failed in azimuth: checking db levels oppdb & EXIT /B 1)
IF %Result% EQU 0 (ECHO ERROR: calling getazimuth with %azimuthindegrees% degrees gave %azimuthOppdB% dB Opp & EXIT /B 1)
Call:Math Int(abs(%azimuthSamedB%))
IF %Result%==ERROR (ECHO ERROR: Math function call failed in getazimuth checking db levels samedb & EXIT /B 1)
IF %Result% EQU 0 (ECHO ERROR: calling getazimuth with %azimuthindegrees% degrees gave %azimuthSamedB% dB & EXIT /B 1)
if "%isazimuthclockwise%"=="yes" (
:cwazimuth
sox --multi-threaded --buffer=%buffer% -V%verbose% %progress% %temp1file% %temp2file% ^
remix 1p,1p%azimuthSamedB%,2i%azimuthOppdB%, 2p,2p%azimuthSamedB%,1p%azimuthOppdB%
IF !%ERRORLEVEL%! NEQ 0 (ECHO ERROR: Sox: clockwise azimuth & EXIT /B 1)
) ELSE (
:ccwazumuth
sox --multi-threaded --buffer=%buffer% -V%verbose% %progress% %temp1file% %temp2file% ^
remix 1p,1p%azimuthSamedB%,2p%azimuthOppdB%, 2p,2p%azimuthSamedB%,1i%azimuthOppdB%
IF !%ERRORLEVEL%! NEQ 0 (ECHO ERROR: Sox: counterclockwise azimuth & EXIT /B 1)
)
:azimuthcorrectiondone
IF EXIST %temp2file% (DEL %temp1file% & move %temp2file% %temp1file% >NUL ) ELSE (ECHO azimuth fail moving output & EXIT /B 1)
IF NOT EXIST %temp1file% (ECHO ERROR: azimuth correction fail creating output & EXIT /B 1)
IF NOT "%azmuted%"=="mute" echo Applied %azimuthdeg% degrees correction:
IF NOT "%azmuted%"=="mute" echo Same: %azimuthSamedB% dB Opposite: %azimuthOppdB% dB Clockwise: %isazimuthclockwise%
EXIT /B 0
:getazimuthspread
:: input parameter: degrees (360)
:: output variables: azimuthSamedB and azimuthOppdB
IF "%1"=="" (ECHO I need to know how many degrees as input parameter & EXIT /B 1)
SET azimuthdeg=%1
SET azspread=%2
SET azmuted=no
IF /I "%3"=="mute" set azmuted=mute
SET LINazimuthOppdB=0
SET LINazimuthSamedB=0
SET RINazimuthOppdB=0
SET RINazimuthSamedB=0
SET Result=ERROR
Call:Math Int(abs(%azimuthdeg% * 10000))
IF %Result%==ERROR (ECHO ERROR: Math function call failed in getazimuth bounds check & EXIT /B 1)
IF %Result% GTR 450000 (ECHO == ERROR: Insane azimuth value == & EXIT /B 1)
set Result=ERROR
Call:Math round((Atn(1) / 45), 15)
IF %Result%==ERROR (ECHO ERROR: Math function call in getazimuth calculate rad/deg & EXIT /B 1)
set toradians=%Result%
Call:Math (%azimuthdeg%-%azspread%) * %toradians%
IF %Result%==ERROR (ECHO ERROR: Math function call failed in getazimuth input degrees to radians & EXIT /B 1)
SET inputrad=%Result%
Call:Math abs(%azimuthdeg% * %toradians%)
IF %Result%==ERROR (ECHO ERROR: Math function call failed in getazimuth absolute value in radians & EXIT /B 1)
SET azimuthrad=%Result%
IF "%inputrad%"=="%azimuthrad%" (set isazimuthclockwise=yes) ELSE (set isazimuthclockwise=no)
Call:Math (1 / Cos(%azimuthrad%)) - 1.0
IF %Result%==ERROR (ECHO ERROR: Math function call failed in getazimuth cos of radians & EXIT /B 1)
SET samex=%Result%
CALL :todb %samex%
IF %errorlevel% NEQ 0 (ECHO ERROR: I barfed trying to call todb subroutine with %samex% & EXIT /B 1)
SET azimuthSamedB=%dbvalue%
Call:Math Tan(%azimuthrad%)
IF %Result%==ERROR (ECHO ERROR: Math function call failed in getazimuth tan of radians & EXIT /B 1)
SET oppx=%Result%
CALL :todb %oppx%
IF %errorlevel% NEQ 0 (ECHO ERROR: I barfed trying to call todb subroutine 2 with %oppx% & EXIT /B 1)
SET azimuthOppdB=%dbvalue%
:getazimuthspreaddone
IF %azimuthOppdB%==0 EXIT /B 1
IF %azimuthSamedB%==0 EXIT /B 1
EXIT /B 0
:getazimuth
:: input parameter: degrees (360)
:: output variables: azimuthSamedB and azimuthOppdB
IF "%1"=="" (ECHO I need to know how many degrees as input parameter & EXIT /B 1)
SET azimuthdeg=%1
SET azmuted=no
IF /I "%2"=="mute" set azmuted=mute
SET azimuthOppdB=0
SET azimuthSamedB=0
SET Result=ERROR
Call:Math Int(abs(%azimuthdeg% * 10000))
IF %Result%==ERROR (ECHO ERROR: Math function call failed in getazimuth bounds check & EXIT /B 1)
IF %Result% GTR 450000 (ECHO == ERROR: Insane azimuth value == & EXIT /B 1)
set Result=ERROR
Call:Math round((Atn(1) / 45), 15)
IF %Result%==ERROR (ECHO ERROR: Math function call in getazimuth calculate rad/deg & EXIT /B 1)
set toradians=%Result%
Call:Math %azimuthdeg% * %toradians%
IF %Result%==ERROR (ECHO ERROR: Math function call failed in getazimuth input degrees to radians & EXIT /B 1)
SET inputrad=%Result%
Call:Math abs(%azimuthdeg% * %toradians%)
IF %Result%==ERROR (ECHO ERROR: Math function call failed in getazimuth absolute value in radians & EXIT /B 1)
SET azimuthrad=%Result%
IF "%inputrad%"=="%azimuthrad%" (set isazimuthclockwise=yes) ELSE (set isazimuthclockwise=no)
Call:Math (1 / Cos(%azimuthrad%)) - 1.0
IF %Result%==ERROR (ECHO ERROR: Math function call failed in getazimuth cos of radians & EXIT /B 1)
SET samex=%Result%
CALL :todb %samex%
IF %errorlevel% NEQ 0 (ECHO ERROR: I barfed trying to call todb subroutine with %samex% & EXIT /B 1)
SET azimuthSamedB=%dbvalue%
Call:Math Tan(%azimuthrad%)
IF %Result%==ERROR (ECHO ERROR: Math function call failed in getazimuth tan of radians & EXIT /B 1)
SET oppx=%Result%
CALL :todb %oppx%
IF %errorlevel% NEQ 0 (ECHO ERROR: I barfed trying to call todb subroutine 2 with %oppx% & EXIT /B 1)
SET azimuthOppdB=%dbvalue%
:getazimuthdone
IF %azimuthOppdB%==0 EXIT /B 1
IF %azimuthSamedB%==0 EXIT /B 1
EXIT /B 0
:todb
IF "%1"=="" (ECHO todb function requires input volume (1.00 = 0dB) & EXIT /B 1)
SET inputvolume=%1
SET dbvalue=borktest
SET Result=ERROR
Call:Math %inputvolume%
IF %Result%==ERROR (ECHO ERROR: Math function call fail in todb function check1 & EXIT /B 1)
IF %Result% EQU 0 (set dbvalue=-400.000 & goto :todbdone)
set Result=ERROR
Call:Math (Log(%inputvolume%) / Log (10.0)) * 20.0
IF "%Result%"=="ERROR" (ECHO ERROR: Math function log call failed in todb & EXIT /B 1)
set dbvalue=%Result%
:todbdone
if %dbvalue%==borktest EXIT /B 1
EXIT /B 0
:balancechannels
IF "%1"=="" (ECHO balancechannels function requires an input parameter in dB & EXIT /B 1)
:: Negative: turn up left side (we actually turn down other side)
SET Result=ERROR
Call:Math round((%1), 4)
IF %Result%==ERROR (ECHO ERROR: Math function call failed in balance channels abs & EXIT /B 1)
SET channeladjust=%Result%
SET Result=ERROR
Call:Math round((abs(%1)), 4)
IF %Result%==ERROR (ECHO ERROR: Math function call failed in balance channels abs & EXIT /B 1)
set perchanneladjust=%Result%
IF %channeladjust%==%perchanneladjust% SET cutleft=0 ELSE SET cutleft=1
Call:Math round((%perchanneladjust% * 10000), 0)
IF %Result%==ERROR (ECHO ERROR: Math function call failed in balance channels abs check no change & EXIT /B 1)
IF %Result% EQU 0 (ECHO STATUS: Skipping channel balance for correction %perchanneladjust% dB & EXIT /B 0)
IF "%cutleft%"=="1" (
REM turn down left side
sox --multi-threaded --buffer=%buffer% -V%verbose% %temp1file% %temp2file% ^
remix 1p-%perchanneladjust% 2p
IF !%ERRORLEVEL%! NEQ 0 (ECHO ERROR: Sox: balancechannels positive level %channeladjust% adjustment & EXIT /B 1)
) ELSE (
REM turn down right side
sox --multi-threaded --buffer=%buffer% -V%verbose% %temp1file% %temp2file% ^
remix 1p 2p-%perchanneladjust%
IF !%ERRORLEVEL%! NEQ 0 (ECHO ERROR: Sox: balancechannels negative level %channeladjust% adjustment & EXIT /B 1)
)
:balancechannelsdone
IF EXIST %temp2file% (DEL %temp1file% & move %temp2file% %temp1file% >NUL ) ELSE (EXIT /B 1)
EXIT /B 0
:crosstalk
SET inverted=%1
SET crosslevel=%2
set Result=ERROR
Call:Math round((%crosslevel% * 10000), 0)
IF %Result%==ERROR (ECHO ERROR: Math function call in setup & EXIT /B 1)
if %Result% GEQ 0 GOTO :crosstalkdone
:: todo - actually mix an equalized version of crosstalk back in
:: todo - check input db
ECHO === Stage start: crosstalk correction==============================
IF /I "%inverted%"=="no" (
:normalcrosstalk
sox --multi-threaded --buffer=%buffer% -V%verbose% %temp1file% %temp2file% ^
remix 1p,2i%crosslevel%, 2p,1i%crosslevel%
IF !%ERRORLEVEL%! NEQ 0 (ECHO ERROR: Sox: normal crosstalk & EXIT /B 1)
) ELSE (
:inversecrosstalk
sox --multi-threaded --buffer=%buffer% -V%verbose% %temp1file% %temp2file% ^
remix 1p,2p%crosslevel%, 2p,1p%crosslevel%
IF !%ERRORLEVEL%! NEQ 0 (ECHO ERROR: Sox: inverse crosstalk & EXIT /B 1)
)
:crosstalkdone
IF EXIST %temp2file% (DEL %temp1file% & move %temp2file% %temp1file% >NUL) ELSE (EXIT /B 1)
EXIT /B 0
:noisereduction
IF NOT %1=="" SET %NRstrength%=%1
set Result=ERROR
Call:Math round((%NRstrength% * 10000), 0)
IF %Result%==ERROR (ECHO ERROR: Math function call in noise reduction setup & EXIT /B 1)
IF %Result% LSS 1 GOTO :noisereductiondone
IF %Result% GEQ 10000 (ECHO ERROR: Noise reduction NRStrength: %NRstrength% is invalid & EXIT /B 1)
ECHO === Stage start: noise reduction ==================================
sox --multi-threaded --buffer=%buffer% -V%verbose% %temp1file% -n ^
trim 0 %NRseconds% noiseprof %noiseprofile%
IF %ERRORLEVEL% NEQ 0 (ECHO ERROR: Sox: stereo noise reduction profile & EXIT /B 1)
sox --multi-threaded --buffer=%buffer% %progress% -V%verbose% %temp1file% %temp2file% ^
noisered %noiseprofile% %NRstrength%
IF %ERRORLEVEL% NEQ 0 (ECHO ERROR: Sox: stereo noise reduction processing & EXIT /B 1)
:noisereductiondone
IF EXIST %temp2file% (DEL %temp1file% & move %temp2file% %temp1file%) >NUL
EXIT /B 0
:speedup
IF NOT "%1"=="" SET speedup=%1
:: A setting of 1.0000 = no speedup
set Result=ERROR
Call:Math round((%speedup% * 10000), 0)
IF %Result%==ERROR (ECHO ERROR: Math function call in speedup while validating input & EXIT /B 1)
set speedupcheck=%Result%
IF %speedupcheck% EQU 10000 (GOTO :speedupdone)
IF %speedupcheck% LSS 1000 (ECHO ERROR speed: %speedup%, I'm not letting you slow down by more than 10x & EXIT /B 1)
IF %speedupcheck% GTR 100000 (ECHO ERROR speed:%speedup%, I'm not letting you speed up by more than 10x & EXIT /B 1)
ECHO === Stage start: speed correction==================================
sox --multi-threaded --buffer=%buffer% -V3 %progress% %temp1file% %temp2file% ^
rate -b 75 192k ^
biquad 1.0000000000 -1.9312626096 0.9313724325 1.0000000000 -0.8796912298 -0.1023703458 ^
speed %speedup% ^
rate -b 75 192k ^
biquad 1.0000000000 -0.8796912298 -0.1023703458 1.0000000000 -1.9312626096 0.9313724325 ^
rate %speedupdownsample%k
IF %ERRORLEVEL% NEQ 0 (ECHO ERROR: Sox: speedup and RIAA re-EQ & EXIT /B 1)
:speedupdone
IF EXIST %temp2file% (DEL %temp1file% & move %temp2file% %temp1file%) >NUL
EXIT /B 0
:midside
ECHO === Stage start: convert stereo to mid-side =======================
sox --multi-threaded --buffer=%buffer% -V%verbose% %progress% %temp1file% %temp2file% ^
remix 1p-6.0206,2p-6.0206 1p-6.0206,2i-6.0206
IF %ERRORLEVEL% NEQ 0 (ECHO ERROR: Sox: stereo to mid-side & EXIT /B 1)
:midsidedone
IF EXIST %temp2file% (DEL %temp1file% & move %temp2file% %temp1file%) >NUL
EXIT /B 0
:midchannel
ECHO === Stage start: process mid channel ==============================
sox --multi-threaded --buffer=%buffer% -V%verbose% %progress% %temp1file% %midfile% ^
remix 1
IF %ERRORLEVEL% NEQ 0 (ECHO ERROR: Sox: mix midside to mid & EXIT /B 1)
:midnoisereduction
rem IF /I NOT "%usenoisereduction%"=="yes" GOTO :midchanneldone
IF /I NOT "%midsideNR%"=="yes" GOTO :midchanneldone
ECHO === Stage start: mid-channel noise reduction =====================
sox --multi-threaded --buffer=%buffer% -V%verbose% %midfile% -n ^
trim %NRseconds% %NR2seconds% noiseprof %noiseprofile%
IF %ERRORLEVEL% NEQ 0 (ECHO ERROR: Sox: mid noise reduction profiling & EXIT /B 1)
sox --multi-threaded --buffer=%buffer% -V%verbose% %progress% %midfile% %temp2file% ^
noisered %noiseprofile% %NR2strength%
IF %ERRORLEVEL% NEQ 0 (ECHO ERROR: Sox: mid noise reduction processing & EXIT /B 1)
:midchanneldone
IF EXIST %temp2file% (DEL %midfile% & move %temp2file% %midfile%) >NUL
EXIT /B 0
:sidechannel
:sideeq
ECHO === Stage start: process side channel =============================
rem ## To restore a 150Hz side-channel bass cut, possibly used in mastering, we equalize
rem ## then more highpass subsonic to reduce vertical modulation rumble
IF %sidesub% NEQ 0 (
sox --multi-threaded --buffer=%buffer% -V%verbose% %progress% %temp1file% %sidefile% ^
remix 2 ^
highpass %sidesub% .5412 highpass %sidesub% 1.3065 ^
reverse ^
highpass %sidesub% .5412 highpass %sidesub% 1.3065 ^
equalizer 80 0.65q %sidebassboostdb% ^
reverse
IF %ERRORLEVEL% NEQ 0 (ECHO ERROR: Sox: side channel bass boost and rumble filter & EXIT /B 1)
) ELSE (
ECHO skipping side-channel rumble filter at setting %sidesub% Hz
IF %sidebassboostdb%==0 GOTO :sideeqdone
sox --multi-threaded --buffer=%buffer% -V%verbose% %temp1file% %sidefile% ^
remix 2 ^
equalizer 80 0.65q %sidebassboostdb%
IF %ERRORLEVEL% NEQ 0 (ECHO ERROR: Sox: side channel bass boost without rumble filter & EXIT /B 1)
)
:sideeqdone
:sidenoisereduction
rem IF /I NOT "%usenoisereduction%"=="yes" GOTO :sidenoisereductiondone
IF NOT "%midsideNR%"=="yes" GOTO :sidenoisereductiondone
ECHO === Stage start: side-channel noise reduction ====================
sox --multi-threaded --buffer=%buffer% -V%verbose% %sidefile% -n ^
trim 0 %NRseconds% noiseprof %noiseprofile%
IF %ERRORLEVEL% NEQ 0 (ECHO ERROR: Sox: side channel noise reduction profiling & EXIT /B 1)
sox --multi-threaded --buffer=%buffer% -V%verbose% %progress% %sidefile% %temp2file% ^
noisered %noiseprofile% %NRstrength%
IF %ERRORLEVEL% NEQ 0 (ECHO ERROR: Sox: side channel noise reduction processing & EXIT /B 1)
:sidenoisereductiondone
:sidechanneldone
IF EXIST %noiseprofile% (DEL %noiseprofile%)
IF EXIST %temp2file% (DEL %sidefile% & move %temp2file% %sidefile%)
EXIT /B 0
:unmidside
ECHO === Stage start: mid-side to stereo ===============================
sox --multi-threaded --buffer=%buffer% -V%verbose% %progress% --combine merge %midfile% %sidefile% %temp1file% ^
remix -m 1,2 1,2i
IF %ERRORLEVEL% NEQ 0 (ECHO ERROR: Sox: combine mid and side to stereo & EXIT /B 1)
EXIT /B 0
:makeoutput
IF NOT EXIST %temp1file% (ECHO ERROR: Expected input file %temp1file% doesn't exist & EXIT /B 1)
SET outname=%1
IF '%outname%'=='' SET outname=%outfile%
ECHO === Stage start: creating output file ============================
SET Result=ERROR
Call:Math int(%normalizeto% * 1000000)
IF %Result%==ERROR (ECHO ERROR: Math function call fail in todb function check1 & EXIT /B 1)
:: greater than 0 db setting disables normalization
IF %Result% GTR 0 (
sox --multi-threaded --buffer=%buffer% -V%verbose% %progress% %temp1file% --comment="" -b 24 %outname% ^
silence 1 2 0 ^
reverse ^
silence 1 2 0 ^
reverse ^
gain %processinggainreduction%
IF !%ERRORLEVEL%! NEQ 0 (ECHO ERROR: Sox: increase gain back to input & EXIT /B 1)
) ELSE (
sox --multi-threaded --buffer=%buffer% -V%verbose% %progress% --norm=%normalizeto% %temp1file% --comment="" -b 24 %outname% ^
gain %processinggainreduction%
IF !%ERRORLEVEL%! NEQ 0 (ECHO ERROR: Sox: final normalization & EXIT /B 1)
)
:makeoutputdone
IF NOT EXIST %outname% (ECHO ERROR: creating output file %outfile% & EXIT /B 1) ELSE ( ECHO ==== DONE: Created %outname% ==== )
EXIT /B 0
:cleanup
rem IF /i NOT "%disablecleanuptempfiles%"=="no" GOTO :cleanupdone
DEL %midfile% 2> NUL
DEL %sidefile% 2> NUL
DEL %temp1file% 2> NUL
DEL %temp2file% 2> NUL
DEL %noiseprofile% 2> NUL
DEL %tempdir%Math.vbs 2> NUL
:cleanupdone
EXIT /B 0
:findazimuth
ECHO -- Generating stepped output
set sub=300
SET rmslist=
SET degreelist=
CALL :setup %1
IF NOT %ERRORLEVEL%==0 (echo ..quitting due to setup function subroutine errors & CALL :cleanup & EXIT /B 1)
SET filteredfile=%noiseprofile%
SET rancount=1
sox --multi-threaded --buffer=%buffer% -V1 %progress% %infile% -b 24 %filteredfile% ^
pad 0.5 0.5 ^
gain -10 ^
rate -b 75 24k ^
sinc -L %sub% -n 32767 ^
highpass 2000 ^
reverse ^
sinc -L %sub% -n 32767 ^
highpass 2000 ^
reverse
IF %ERRORLEVEL% NEQ 0 (ECHO ERROR: Sox: findazimuth notch filtering & EXIT /B 1)
:testloop
SET /A "incs=steps-1"
DEL "%tempdir%%filebase%-iter*.wav" 2>NUL
FOR /L %%a in (0,1,%incs%) do (call :insideloopsub %%a)
ECHO/
sox --multi-threaded --buffer=%buffer% -V2 --combine concatenate "%tempdir%%filebase%-iter*.wav" --comment="" %temp1file%
IF %ERRORLEVEL% NEQ 0 (ECHO ERROR: trying to merge & EXIT /B 1)
DEL "%tempdir%%filebase%-iter*.wav" 2>NUL
ECHO/
CALL :makeoutput "%inpath%%filebase%-stereosteps.wav"
CALL :midside
CALL :makeoutput "%inpath%%filebase%-midsidesteps.wav"
IF %ERRORLEVEL% NEQ 0 (ECHO ERROR: calling makeoutput & EXIT /B 1)
echo ----------------------------------------
ECHO #: Degree MID+SIDERMS MIDRMS SIDE RMS
for /l %%n in (1,1,%steps%) do (
echo !resulttable[%%n]!
)
call :cleanup
ECHO/
ECHO -- Done. Analyze these files for phase and pan to find best correction:
ECHO -- "%inpath%%filebase%-stereosteps.wav";
ECHO -- "%inpath%%filebase%-midsidesteps.wav"
ECHO (%steps% steps are centered on %center% degrees, %fromcenter% degrees on each size)
pause
exit /b
:insideloopsub
set inparm=%1
IF 1%inparm% LSS 100 SET inparm=0%inparm%
SET Result=ERROR
Call:Math round( ( (%center% - %fromcenter%) + (%1 * 2 *%fromcenter% / ( %incs% ))) , 4) + 0.00001
IF %Result%==ERROR (ECHO ERROR: Math function call in extraction & EXIT /B 1)
SET degrees=%Result%
copy %filteredfile% %temp1file% >NUL 2>NUL
call :rmsgrabber %degrees%
sox %filteredfile% %tempdir%gaptemp.wav synth 2 sine 10 gain -120
sox --buffer=%buffer% -V2 %temp1file% "%tempdir%%filebase%-iter%inparm%.wav"
IF %ERRORLEVEL% NEQ 0 (ECHO ERROR: calling rmsgrabber: insideloopsub & EXIT /B 1)
if NOT !rancount! EQU 1 (
SET "degreelist=%degreelist% %aztestvalue%"
SET "midlist=%midlist% %midrms%"
SET "sidelist=%sidelist% %siderms%"
SET "avglist=%avglist% %avgrms%"
SET "samelist=%samelist% %azimuthSamedB%"
SET "opplist=%opplist% %azimuthOppdB%"
) ELSE (
SET "degreelist=%aztestvalue%"
SET "midlist=%midrms%"
SET "sidelist=%siderms%"
SET "avglist=%avgrms%"
SET "samelist=%azimuthSamedB%"
SET "opplist=%azimuthOppdB%"
)
IF 1%rancount% LSS 100 (
SET resulttable[%rancount%]=0%rancount%: %aztestvalue%: %avgrms% -- %midrms% -- %siderms%
) ELSE (
SET resulttable[%rancount%]=%rancount%: %aztestvalue%: %avgrms% -- %midrms% -- %siderms%
)
SET /A "rancount=rancount+1"
GOTO :eof
exit /b 0
:rmsgrabber
:: input argument: degrees of azimuth
:: input file: %temp1file%
:: output: sets midrms siderms avgrms
:getactual
IF "%1"=="" (echo get mid-side RMS function needs input in degrees & EXIT /B 1)
set aztestvalue=%1
call :azimuthcorrection %aztestvalue% mute
IF %ERRORLEVEL% NEQ 0 (ECHO ERROR: calling azimuthcorrection 1 & EXIT /B 1)
:: azimuth-adjusted signal to mid
sox --multi-threaded --buffer=%buffer% -V%verbose% %temp1file% %midfile% ^
remix 1p,2p
IF %ERRORLEVEL% NEQ 0 (ECHO ERROR: Sox: midside rms 1 & EXIT /B 1)
:: corrected signal to side
sox --multi-threaded --buffer=%buffer% -V%verbose% %temp1file% %sidefile% ^
remix 1p,2i
IF %ERRORLEVEL% NEQ 0 (ECHO ERROR: Sox: midside rms 2 & EXIT /B 1)
:: EXTRACT STDERR OUTPUT OF SoX ============
sox -V1 %midfile% -n stat -s 1 2> %tempdir%soxstat.log
IF %ERRORLEVEL% NEQ 0 (ECHO ERROR: Sox: makestats & EXIT /B 1)
for /f "tokens=*" %%i in ('FINDSTR RMS %tempdir%soxstat.log ^| FINDSTR amplitude') do ( set RMSline=%%i )
for /f "tokens=3 delims= " %%i IN ("%RMSline%") do (set midrms=%%i)
del %tempdir%soxstat.log
sox -V1 %sidefile% -n stat -s 1 2>%tempdir%soxstat.log
IF %ERRORLEVEL% NEQ 0 (ECHO ERROR: Sox: makestats rms amplitude 2 & EXIT /B 1)
for /f "tokens=*" %%i in ('FINDSTR RMS %tempdir%soxstat.log ^| FINDSTR amplitude') do ( set RMSline=%%i )
for /f "tokens=3 delims= " %%i IN ("%RMSline%") do (set siderms=%%i)
del %tempdir%soxstat.log
set Result=ERROR
Call:Math (%midrms% + %siderms%)/2
IF %Result%==ERROR (ECHO ERROR: Math function call in extraction & EXIT /B 1)
set avgrms=%Result%
Call:Math round((%midrms%), 0)
IF %Result%==ERROR (ECHO ERROR: Math function call in extraction & EXIT /B 1)
set midrms=%Result%
Call:Math round((%siderms%), 0)
IF %Result%==ERROR (ECHO ERROR: Math function call in extraction & EXIT /B 1)
set siderms=%Result%
Call:Math round((%avgrms%), 0)
IF %Result%==ERROR (ECHO ERROR: Math function call in extraction & EXIT /B 1)
set avgrms=%Result%
Call:Math round((%aztestvalue%), 2)
IF %Result%==ERROR (ECHO ERROR: Math function call in extraction & EXIT /B 1)
set aztestvalue=%Result%
Call:Math int((abs(%aztestvalue%) - %aztestvalue%)*10000)
IF %Result%==ERROR (ECHO ERROR: Math function call in extraction & EXIT /B 1)
IF %Result% EQU 0 SET aztestvalue=+%aztestvalue%
Call:Math ((%aztestvalue% - int(%aztestvalue%))*10)
IF %Result%==ERROR (ECHO ERROR: Math function call in extraction & EXIT /B 1)
IF %Result% EQU 0 SET aztestvalue=%aztestvalue%.0
Call:Math %aztestvalue% * 10 - int( %aztestvalue% * 10 )
IF %Result%==ERROR (ECHO ERROR: Math function call in extraction & EXIT /B 1)
IF %Result% EQU 0 SET aztestvalue=%aztestvalue%0
rem echo degrees mr+sr m s
rem echo %aztestvalue% %avgrms%,%midrms%,%siderms%
echo | set /p=%aztestvalue%,
:rmsgrabberdone
exit /b
:findazimuthdone
:referencesteps
ECHO --- Azimuth-correcting your input file x 21 steps... ---
set sub=30
CALL :setup %1
IF NOT %ERRORLEVEL%==0 (echo ..quitting due to setup function subroutine errors & CALL :cleanup & EXIT /B 1)
SET filteredfile=%temp1file%
sox -S --multi-threaded --buffer=%buffer% -V1 %progress% %infile% %filteredfile% ^
rate -b 75 -L 48k ^
gain -%processinggainreduction% ^
highpass %ch1f% %ch1q% highpass %ch2f% %ch2q% highpass %ch3f% %ch3q% highpass %ch4f% %ch4q% highpass %ch5f% %ch5q% ^
lowpass 20000 ^
reverse ^
highpass %ch1f% %ch1q% highpass %ch2f% %ch2q% highpass %ch3f% %ch3q% highpass %ch4f% %ch4q% highpass %ch5f% %ch5q% ^
lowpass 20000 ^
reverse
IF %ERRORLEVEL% NEQ 0 (ECHO ERROR: Sox: referencesteps notch filtering & EXIT /B 1)
DEL %tempdir%%filebase%steps*.wav 2>NUL
sox --multi-threaded -V%verbose% %filteredfile% -b 16 %tempdir%%filebase%steps01.wav ^
remix 1p,1p-48.36,2p-21.16 2p,2p-48.36,1i-21.16 pad .5 .5
sox --multi-threaded -V%verbose% %filteredfile% -b 16 %tempdir%%filebase%steps02.wav ^
remix 1p,1p-50.19,2p-22.08 2p,2p-50.19,1i-22.08 pad .5 .5
sox --multi-threaded -V%verbose% %filteredfile% -b 16 %tempdir%%filebase%steps03.wav ^
remix 1p,1p-52.25,2p-23.11 2p,2p-52.25,1i-23.11 pad .5 .5
sox --multi-threaded -V%verbose% %filteredfile% -b 16 %tempdir%%filebase%steps04.wav ^
remix 1p,1p-54.57,2p-24.27 2p,2p-54.57,1i-24.27 pad .5 .5
sox --multi-threaded -V%verbose% %filteredfile% -b 16 %tempdir%%filebase%steps05.wav ^
remix 1p,1p-57.25,2p-25.61 2p,2p-57.25,1i-25.61 pad .5 .5
sox --multi-threaded -V%verbose% %filteredfile% -b 16 %tempdir%%filebase%steps06.wav ^
remix 1p,1p-60.42,2p-27.20 2p,2p-60.42,1i-27.20 pad .5 .5
sox --multi-threaded -V%verbose% %filteredfile% -b 16 %tempdir%%filebase%steps07.wav ^
remix 1p,1p-64.30,2p-29.14 2p,2p-64.30,1i-29.14 pad .5 .5
sox --multi-threaded -V%verbose% %filteredfile% -b 16 %tempdir%%filebase%steps08.wav ^
remix 1p,1p-69.30,2p-31.64 2p,2p-69.30,1i-31.64 pad .5 .5
sox --multi-threaded -V%verbose% %filteredfile% -b 16 %tempdir%%filebase%steps09.wav ^
remix 1p,1p-76.34,2p-35.16 2p,2p-76.34,1i-35.16 pad .5 .5
sox --multi-threaded -V%verbose% %filteredfile% -b 16 %tempdir%%filebase%steps10.wav ^
remix 1p,1p-88.39,2p-41.18 2p,2p-88.39,1i-41.18 pad .5 2
sox --multi-threaded -V%verbose% %filteredfile% -b 16 %tempdir%%filebase%steps11.wav ^
pad .5 2
sox --multi-threaded -V%verbose% %filteredfile% -b 16 %tempdir%%filebase%steps12.wav ^
remix 1p,1p-88.39,2i-41.18 2p,2p-88.39,1p-41.18 pad .5 .5
sox --multi-threaded -V%verbose% %filteredfile% -b 16 %tempdir%%filebase%steps13.wav ^
remix 1p,1p-76.34,2i-35.16 2p,2p-76.34,1p-35.16 pad .5 .5
sox --multi-threaded -V%verbose% %filteredfile% -b 16 %tempdir%%filebase%steps14.wav ^
remix 1p,1p-69.30,2i-31.64 2p,2p-69.30,1p-31.64 pad .5 .5
sox --multi-threaded -V%verbose% %filteredfile% -b 16 %tempdir%%filebase%steps15.wav ^
remix 1p,1p-64.30,2i-29.14 2p,2p-64.30,1p-29.14 pad .5 .5
sox --multi-threaded -V%verbose% %filteredfile% -b 16 %tempdir%%filebase%steps16.wav ^
remix 1p,1p-60.42,2i-27.20 2p,2p-60.42,1p-27.20 pad .5 .5
sox --multi-threaded -V%verbose% %filteredfile% -b 16 %tempdir%%filebase%steps17.wav ^
remix 1p,1p-57.25,2i-25.61 2p,2p-57.25,1p-25.61 pad .5 .5
sox --multi-threaded -V%verbose% %filteredfile% -b 16 %tempdir%%filebase%steps18.wav ^
remix 1p,1p-54.57,2i-24.27 2p,2p-54.57,1p-24.27 pad .5 .5
sox --multi-threaded -V%verbose% %filteredfile% -b 16 %tempdir%%filebase%steps19.wav ^
remix 1p,1p-52.25,2i-23.11 2p,2p-52.25,1p-23.11 pad .5 .5
sox --multi-threaded -V%verbose% %filteredfile% -b 16 %tempdir%%filebase%steps20.wav ^
remix 1p,1p-50.19,2i-22.08 2p,2p-50.19,1p-22.08 pad .5 .5
sox --multi-threaded -V%verbose% %filteredfile% -b 16 %tempdir%%filebase%steps21.wav ^
remix 1p,1p-48.36,2i-21.16 2p,2p-48.36,1p-21.16 pad .5 .5
sox -V%verbose% --multi-threaded --guard --combine concatenate ^
%tempdir%%filebase%steps*.wav ^
--comment="" "%inpath%%filebase%-referencesteps-stereo.wav"
IF %ERRORLEVEL% NEQ 0 (ECHO ERROR: Sox: referencesteps recombinging steps & EXIT /B 1)
sox -V%verbose% "%inpath%%filebase%-referencesteps-stereo.wav" "%inpath%%filebase%-referencesteps-midside.wav" ^
remix 1p-6.0206,2p-6.0206 1p-6.0206,2i-6.0206
IF %ERRORLEVEL% NEQ 0 (ECHO ERROR: Sox: referencesteps making midside version of steps & EXIT /B 1)
:cleanupsteps
DEL %tempdir%%filebase%steps*.wav
CALL :cleanup
:referencestepsstepsdone
ECHO/
ECHO -- Done. Analyze these files for phase and pan to find best correction:
ECHO -- "%inpath%%filebase%-referencesteps-stereo.wav";
ECHO -- "%inpath%%filebase%-referencesteps-midside.wav"
ECHO (range of steps is -5 degrees ccw to +5 degrees clockwise)
pause
exit /B 0
goto :eof
:Math
REM echo VB command: "%*"
set Result=ERROR
for /f %%a in ('cscript /nologo %tempdir%Math.vbs "%*"') do set "Result=%%a"
exit /b %matherror%
:deviation
CALL :stddevfile
echo VB command: -- %* --
set Result=ERROR
for /f %%a in ('cscript /nologo %tempdir%Stddev.vbs "%*"') do set "Result=%%a"
exit /b %matherror%
:stddevfile
IF EXIST %tempdir%Stddev.vbs DEL %tempdir%Stddev.vbs >NUL
ECHO arData = Split(WScript.Arguments(0),",") >%tempdir%Stddev.vbs
echo Wscript.echo "hello" & StandardDeviation(arData),15 >>%tempdir%Stddev.vbs
ECHO/ >>%tempdir%Stddev.vbs
ECHO Wscript.echo StandardDeviation(arData) >>%tempdir%Stddev.vbs
ECHO WScript.Quit 1 >>%tempdir%Stddev.vbs
ECHO/ >>%tempdir%Stddev.vbs
ECHO Function StandardDeviation(arData) >>%tempdir%Stddev.vbs
ECHO StandardDeviation = 0 >>%tempdir%Stddev.vbs
ECHO If IsArray(arData) Then >>%tempdir%Stddev.vbs
ECHO Difference = 0 >>%tempdir%Stddev.vbs
ECHO Temp = 0 >>%tempdir%Stddev.vbs
ECHO Average = GetAverage(arData) >>%tempdir%Stddev.vbs
ECHO Amount = UBound(arData) >>%tempdir%Stddev.vbs
ECHO For i = 0 To Amount >>%tempdir%Stddev.vbs
ECHO Difference = ((arData(I) - Average) ^^ 2) >>%tempdir%Stddev.vbs
ECHO Temp = Temp + Difference >>%tempdir%Stddev.vbs
ECHO Difference = 0 >>%tempdir%Stddev.vbs
ECHO Next >>%tempdir%Stddev.vbs
ECHO StandardDeviation = Sqr(Temp / (Amount)) >>%tempdir%Stddev.vbs
ECHO End If >>%tempdir%Stddev.vbs
ECHO End Function >>%tempdir%Stddev.vbs
ECHO/ >>%tempdir%Stddev.vbs
ECHO Function GetAverage(arData) >>%tempdir%Stddev.vbs
ECHO GetAverage = 0 >>%tempdir%Stddev.vbs
ECHO If IsArray(arData) Then >>%tempdir%Stddev.vbs
ECHO total = UBound(arData) >>%tempdir%Stddev.vbs
ECHO For i = 0 To total >>%tempdir%Stddev.vbs
ECHO GetAverage = GetAverage + arData(i) >>%tempdir%Stddev.vbs
ECHO Next >>%tempdir%Stddev.vbs
ECHO GetAverage = GetAverage / (total + 1) >>%tempdir%Stddev.vbs
ECHO End If >>%tempdir%Stddev.vbs
ECHO End Function >>%tempdir%Stddev.vbs
EXIT /B 0
:nosox
echo/
echo ======== SoX.exe audio processor not found - What do you want to do? =========
echo/
echo [1] - EXIT: I'll download it myself from Sourceforge (and put sox.exe file in path)
echo [2] - Download sox.exe from author's site to work directory and continue (easy if working)
echo [xx] - Download and expand zip from Sourceforce to local directory and continue (needs PS 5)
echo [xx] - Just download installer from Sourceforce (so I can run it manually and move sox.exe)
echo/
choice /C 12 /N /M "Your choice: "
echo/
if errorlevel 4 goto :getinstalleronly
if errorlevel 3 goto :zipdownload
if errorlevel 2 goto :authordownload
EXIT /B 4
:authordownload
powershell -Command "Invoke-WebRequest
http://hotnova.com/sox.exe -OutFile %cd%\sox.exe"
IF NOT EXIST sox.exe (echo Sorry, didn't work. & goto :nosox)
echo Got it!!
sox --version
IF NOT %ERRORLEVEL%==0 (echo Something's wrong with the downloaded file, sorry & goto :nosox)
EXIT /B 0
:nosoxdone
EXIT /B 0
:nofile
echo ==== There is no %infile% input file found! ====
echo (Reminder: With spaces in file names, surrounding quotes are needed)
pause
exit /b 9
:nofiledone
:cantdel
echo ==== %outfile% output or temp files exist and can't be deleted - do you have one open?? ====
pause
exit /b 7