I'm trying to make a script that monitors a directory (where recordings from a VHF radio are saved by iSpy) for new files and applies a noise reduction process to them using the SoX binary. The simplest part of the script is where I'm failing: I'm not passing parameters to the executable properly. I've tried multiple iterations of the command I'm using based on solutions found on this site only to run into new problems. I tried various quoting strategies I do not understand and piping to CMD but there's obviously something basic that I'm missing. I'm very new to PS and scripting in general, so help would be appreciated.
The whole script (early WIP) is at the bottom of this post.
The binary expects a simple syntax:
sox.exe <file to analyze> <"-n noiseprof"> <analysis output filename>
sox.exe <file to process> <file to save> <"noisered"> <analysis filename> <"0.21 silence -l 1 0.3 5% -1 2.0 5%">
I'm trying to input the binary's path and all parameters/arguments as variables, expand and run the command. Examples of all variables used:
$soxpath = "C:\Program Files (x86)\sox-14-4-2"
$path = "E:\SEC Surveillance\audio\EOJNP\2_2021-07-17_10-18-00.mp3"
$args1 = "-n noiseprof"
$profileoutput = "E:\SEC Surveillance\audio\EOJNP\2_2021-07-17_10-18-00_noiseprofile.prof"
$processoutput = "E:\SEC Surveillance\audio\EOJNP\processed\2_2021-07-17_10-18-00_processed.mp3"
$args3 = "noisered"
$args4 = "0.21 silence -l 1 0.3 5% -1 2.0 5%"
#& $soxpath\sox.exe $path $args1 $profileoutput
#& $soxpath\sox.exe $path $processoutput $args3 $profileoutput $args4
The executable will run just fine if I do not use variables to input paths and arguments, from a PS terminal as well as from a simple script:
& "C:\Program Files (x86)\sox-14-4-2\sox.exe" "E:\SEC Surveillance\audio\EOJNP\2_2021-07-17_10-18-00.mp3" -n noiseprof "E:\SEC Surveillance\audio\EOJNP\2_2021-07-17_10-18-00_noiseprofile.prof"
After various simpler attempts my reasoning was that if I replicate this exact syntax in a script's output, it should work. The result is not pretty:
& "`"$($soxpath)\sox.exe`"" "`"$($path)`"" $args1 "`"$($profileoutput)`""
& : The term '"C:\Program Files (x86)\sox-14-4-2\sox.exe"' is not recognized...
Going back a step results in the executable launching but not getting arguments (based on a Write-Host output I'd expect the command to be spot on):
& $soxpath\sox.exe "`"$($path)`"" $args1 "`"$($profileoutput)`""
sox.exe : C:\Program Files (x86)\sox-14-4-2\sox.exe WARN getopt: option ` ' not recognized
C:\Program Files (x86)\sox-14-4-2\sox.exe FAIL sox: invalid option
Also tried to create a parameter array using variables:
$prm = $ExecutionContext.InvokeCommand.ExpandString("'$path', $args1, '$profileoutput'")
& $soxpath\sox.exe $prm
But honestly I have no idea what I'm doing.
### SETTINGS
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = "E:\SEC Surveillance\audio\EOJNP"
$watcher.Filter = "*.mp3"
$watcher.IncludeSubdirectories = $false
$watcher.EnableRaisingEvents = $true
### ACTION
$action = {
### VAR STATIC
$args1 = "-n noiseprof"
#$args2 = "null"
$args3 = "noisered"
$args4 = "0.21 silence -l 1 0.3 5% -1 2.0 5%"
### VAR BASIC PATHS
$path = $Event.SourceEventArgs.FullPath
$parentpath = Split-Path -Path "$path"
$name = $Event.SourceEventArgs.Name
$namenoext = [IO.Path]::GetFileNameWithoutExtension($name)
$pathnoext = ("$parentpath" + "\" + "$namenoext")
### VAR PROCESS PATHS
$soxpath = "C:\Program Files (x86)\sox-14-4-2"
$profileoutput = ("$pathnoext" + "_noiseprofile.prof")
$processoutput = ("$parentpath" + "\processed\" + "$namenoext" + "_processed.mp3")
### PROCESSING AND FILE MANAGEMENT
# Double quotes escaped
& "`"$($soxpath)\sox.exe`"" "`"$($path)`"" $args1 "`"$($profileoutput)`""
& "`"$($soxpath)\sox.exe`"" "`"$($path)`"" "`"$($processoutput)`"" $args3 "`"$($profileoutput)`"" $args4
}
### START
Register-ObjectEvent $watcher "Created" -Action $action
#Register-ObjectEvent $watcher "Changed" -Action $action
#Register-ObjectEvent $watcher "Deleted" -Action $action
#Register-ObjectEvent $watcher "Renamed" -Action $action
while ($true) {sleep 5}