Batch add silence and repeat OGG files

Hi,
I have a bunch of OGG files and I’d like to automate some edit operations on. Audacity does not work, so I’m using SOX. For each file, the sequence of operations is something like this:

  1. Find length of audio :: soxi -D %%f
  2. Pad silence same as length :: sox %%f %%f pad 0 len
  3. Repeat n times.

Commands work fine on their own, but now to put in a batch file :smiling_imp:
My dos capabilities are less than developed :blush: :blush: but I came up with this::

SETLOCAL ENABLEDELAYEDEXPANSION
FOR %%f IN (C:Userst4DesktoptestMP3L1EE*.ogg) DO (
set x = !x!soxi -D %%f
sox %%f %%f pad 0 x
SOX %%f %%f repeat 1
)

two problems: first howto set a variable in a loop? And howto assign the length of audio to the a variable? I keep getting the following error::

sox FAIL pad: usage: {length[@position]}

Can anyone help? I thought I could do this but DOS seems way too convoluted for my simple brain.

I’m not sure how you would do it in Dos, but in a Bash script (Linux) this works:

sox -n "output/temp.wav" trim 0 5
for filename in *.wav
   do sox $filename "output/temp2.wav" repeat 2
   sox "output/temp.wav" "output/temp2.wav" "output/$filename"
   done
rm "output/temp.wav"
rm "output/temp2.wav"

This assumes that there is an output folder “output” within the current folder.

The first line creates a temporary file “temp.wav” in the output folder that is 5 seconds of silence.
The second line is the start of the loop - the syntax for this is probably different in Dos
Line 3) is a “for each file” command that repeats the file twice (three times through in total) and outputs to “temp2.wav” in the output folder.
Line 4) takes the two “temp” files and concatenates them into a single file with the same name as the input file, but into the output folder.
Line 5) is the end of the loop
The last two lines delete the temporary files.

the same SoX commands should work in Dos, you’ll just need to change the loop command to the correct syntax.
Hope this helps.

Thanks for the reply. True, I want to append silence to the files, but the length of silence should be the same as the length of the given track, not 5 seconds everytime. The pattern will look something like this:

(track)+(silence as long as track)+(track)+(silence as long as track)+(track)+(silence as long as track)+(track)+(silence as long as track)+…

My original question had more to do with batch scripting than SOX, but now that I’ve fixed the script (thanks for stackoverflow) I have another problem.

FOR %%f IN (*.ogg) DO CALL :runsox "%%f"
GOTO :EOF

:runsox
soxi -D %1>tmpfile
SET /P decvalue=<tmpfile
sox %1 %1 pad 0 %decvalue%
sox %1 %1 repeat 10

The above script works fine except it adds a high pitched sound, a spike at the beginning of each repetition. I attach a sample file. Happens for some files, other are ok.

Also, when I play the files in VLC, the progress indicator hangs on silence, then continues moving on sound. I will try it on physical mp3 players also.

Also, I modified your script Steve. Like you, I’m trying to create sound file separately and concatenate to each file.

FOR %%f IN (*.wav) DO CALL :runsox "%%f"
GOTO :EOF

:runsox
soxi -D %1>tmpfile
SET /P decvalue=<tmpfile
sox -n "temp.wav" trim 0 %decvalue%
sox %1 "temp.wav" "repeated.wav"
sox "repeated.wav" %1 repeat 10

and ran it, I got these errors::

C:L4>FOR %f IN (*.wav) DO CALL :runsox "%f"
C:L4>CALL :runsox "3.wav"
C:L4>soxi -D "3.wav" 1>tmpfile
C:L4>SET /P decvalue= 0<tmpfile
C:L4>sox -n "temp.wav" trim 0 0.950000
C:L4>sox "3.wav" "temp.wav" "repeated.wav"
sox FAIL sox: Input files must have the same sample-rate
sox FAIL sox: Input files must have the same # channels
C:L4>sox "repeated.wav" "3.wav" repeat 10
sox FAIL formats: can't open input file `repeated.wav': No such file or directory
C:L4>GOTO :EOF

If all of the files being processed have the same sample rate and the same number of channels (usually “1 mono” or “2 stereo”) then you can hard code the generated silence to be the same format as the files being processed.

Example (sorry, still a Bash script) for sample rate = 44100 Hz, 2 channel (stereo):

# set number of repeats to 2
repeat= 2

# start loop
for filename in *.wav
  do
    slength=$(soxi -D $filename)

# make silence with 2 channels and sample rate 44100
    sox -n -c 2 -r 44100 "output/temp.wav" trim 0 $slength

    sox $filename "output/temp2.wav" repeat $repeats
    sox "output/temp.wav" "output/temp2.wav" "output/$filename"
  done

# clean up temp files
rm "output/temp.wav"
rm "output/temp2.wav"

If the number of channels and sample rate are unknown, you will need to test for them:

soxi -c filename
soxi -r filename

and set a couple of variable to these values so that you can create the temp silence file with the right format.

:imp: :imp: :imp: :imp: :imp: :imp:
I needed to increase the silence by some factor, so multiply by some number simple enough… MSdos does cannot do arithmetic operations on decimal numbers!! I thought bash would be smarter, so installed a bash interpreter for Windows… same same. solved like below … pipe into bc.

#!/bin/sh
# set number of repeats to 10
repeat= 10

# start loop
for filename in *.wav
do
slength=$(soxi -D $filename)
tlength=$(echo "scale=9; $slength *1.25" | bc)
# make silence with 2 channels and sample rate 44100
sox -c 1 -n -r 44100 "output/temp.wav" trim 0 $tlength

sox $filename "output/temp2.wav" repeat $repeat
sox "output/temp.wav" "output/temp2.wav" "output/$filename"
done

# clean up temp files
rm "output/temp.wav"
rm "output/temp2.wav"

I should have realized earlier, but the time I invested in trying to get this #$@!%^& working in MSdos/bash… i could have used to download/write simple python scripts… dropping dos & bash for the next job!
Thanks for the help everyone!

Sorry about that, I could have saved you some time there but I didn’t know that MSDos was also restricted to integer arithmetic. I had posted a Bash general script for adding silence to the beginning of a file here: Batch Scripts with other programs and yes it uses “bc”.

More generally, yes Python is much more flexible and powerful for this type of scripting, and if you really want to you could even write a full GUI front end.