Batch Processing Sox on Windows 10

I realize that this forum is about Audacity, but many users here seem familiar with SoX, so I thought I would ask my question here.

I’m doing some work using an 8 bit MCU to take PCM uLaw data from an SD card, converts it back to signed 14 bit linear, adds a DC offset and sends it to a DAC which then goes to an amplified speaker. That all works as expected.

I create my source audio files (human voice saying words and phrases) in Audacity as 44100 s/s WAV files. I then use SoX to convert the WAV files to 8 bit uLaw PCM. I use the following script on the Windows 10 command line (SoX is in my PATH, the WAV file is not in the SoX executable directory):

sox.exe input.wav -r 8000 -b 8 output.raw remix -

I know little about SoX but this seems to work (the output.raw file sounds good to the ear when listening to the amplified speaker, after the MCU converts 8 bit uLaw back to 14 bit signed linear with DC offset).

My problem comes when I want to generalize my command line script to convert a bunch of WAV files to PCM files, i.e., batch process.

I found this website that discusses batch processing with SoX

https://madskjeldgaard.dk/posts/sox-tutorial-batch-processing/

which gives examples. One example is to normalize a bunch of WAV files using:

for file in *.wav; do sox “$file” “n_$file” norm -0.1; done

My problem is that when I run this on the Windows 10 command line I get the following response:

file was unexpected at this time.
P:\cstuff\SoX_>for file in *.wav; do sox “$file” “n_$file” norm -0.1; done

This is probably some sort of syntax problem, but I haven’t been able to figure it out.

Any guidance or suggestions would be very welcome.

Paul

Yes. I know nothing about sox; however I suppose for Windows, you could try formatting your command a little more like:

for %f in (*.WAV); do sox “%f” “n_%f” norm -0.1; done

Why not export from Audacity as 8-bit uLaw?
“File menu > Export > Export Audio…”
Then select the header (such as “WAV” or “RAW”), and the encoding (“U-Law”).

It’s often better to refer to the official documentation: http://sox.sourceforge.net/sox.html

This works on Linux:

for file in *.wav; do sox "$file" "n_$file" --norm=-0.1; done

Thanks for this suggestions, but on windows (at least on my computer) doesn’t seem to like that form either. I suspect my problem is more about the correct syntax for windows and not SoX itself

Thanks for pointing this out. I wasn’t aware that I could get a direct no-header 8 bit uLaw PCM output from Audacity. Unfortunately, that procedure looks to be a one-at-a-time type of thing, and doesn’t appear to be capable of batch processing a bunch of WAV source files.

When I look at the export options in Tools>Macros, there doesn’t appear to be an export option that yields 8 bit uLaw output. The only Export options I see in Tools>Macros are Export FLAC, Export MP3, Export OGG, Export WAV. That’s why I was looking at SoX for a WAV to PCM solution that I could batch process, or hoped I could batch process. I’d love to do all my audio editing and processing in Audacity, but in the end I expect to be working with a hundreds of WAV source files and I’m looking for an automated way to turn them into raw uLaw PCM.

Thanks. Once again the world looks simpler in Linux. I need to set up my PC with WSL2 so I can run Linux and Windows at the same time. But that’s a future project. For now, I’m stuck with Windows 10.

I would expect the command that I posted to also work in Windows.
Note that the difference between my code and your original code is this part:

--norm=-0.1;

Thanks for this. But when I try that on my W10 PC I get the following (with no files generated).

file was unexpected at this time.
P:\cstuff\SoX_>for file in *.wav; do sox “$file” “n_$file” --norm=-0.1; done

Is there something special I need to do on my PC in order for command line scripting to work? So sort of utilities to install?

How are you running the command? Are you using the command prompt (“cmd”), or PowerShell, or something else?

Correct, the commands you are looking for relate to shell scripting (to issue the right sox commands) - they are not part of sox itself.

Confusingly, every environment has different shell scripting rules. Although some keywords look the same, details vary - especially variable substitution.

The original one you posted is for Linux, probably the bash shell (but there are others!). For Windows, there’s the DOS command line / batch file syntax - but there’s also the newer PowerShell - and it’s even possible to install a Linux-like environment on Windows and get the bash shell! Which is what I do when I have to use Windows … and have therefore forgotten the differences.

If this means nothing to you, I recommend sticking with the plain DOS command line. There is no need to download and install anything else.

You’ll definitely need the % sign in front of variable names (this is one of the differences with Linux shell scripts).
I think the for-loop syntax is different too. Try this:

for %f in (*.WAV) do @echo sox "%f" "n_%f" norm -0.1

Using echo or @echo is useful for testing the syntax, and avoiding running the actual commands until you are happy. Just remove that word to run it properly.

Command Prompt

Thank you for the suggestion. When I try that I get:

f" “n_f” norm -0.1 was unexpected at this time.
P:\cstuff\SoX_>for f" “n_f” norm -0.1

I got it working in Windows 10 by adding an output folder called “out” in the same directory as the input files, then running this command:

for %f in (*.WAV); do sox --norm=-0.1 %f ./out/n_%f

Wow! thank you, that works. But in a piece of Windows weirdness, it only works when I type your script command line by hand on the command line and press ENTER. If I put that same script command string in a file (doit.bat) and then type “doit” ENTER from the command line then I get the “f was unexpected at this time” message and nothing else seems to happen. That may have been most of my previous problem, scripting doesn’t seem to work when embedded in a batch file. I had always been using the batch file approach previously.

I believe you need to replace % with %% (in a batch file use %%f, in a cmd shell use %f ).

YES! That (%%) works in the batch file. I’m back in gear. Thank you very much for your help.