Category Archives: Windows Batch Programming

Splitting mp3-files using mp3splt and batch files

——RANT MODE: ON—–

Back in the good old times of audio tapes, the concept of a track was not built into the system. This had pros and cons: It was quite easy to fast-forward or rewind to a certain position in a song or radio play. However, you could not just skip a track or forward to the next track, since a tape does not support tracks. (Actually, on some fancy tape decks, there was a button for that. Those things had a silence-detection built in and hence knew when a track ended and a new one began).
Today the situation is reversed: You can easily navigate backward and forward between tracks, but navigating within them is cumbersome or impossible on most cheap mp3 players (such as the ones I happen to possess).
Another disadvantage of that cheap players is that they only remember the track, that was played when they were turned off, but not the position within the track. Since some audiobooks and podcasts come in rather long tracks, this is a pain in the ass as you spent quite some time fast-forwarding and rewinding through the track while you are hammering your brain trying to remember where you left off. And don’t you dare to let your finger tremble just the smallest bit on the fast-forward button, since on most players this means “next track” and you will have to start over. Argh!

——RANT MODE: OFF—–

So, sometimes I have the need to split large mp3-files into smaller ones. In audiobooks and podcasts, it is most convenient to split the files at ‘silence positions’ i.e. when no one is talking. There is a very nice tool that can do the job for you: It’s called mp3splt and you can get it here:

http://mp3splt.sourceforge.net

It’s a command line tool, but you can also download a GTK-frontend. mp3splt can search for silence positions within an mp3 file and then let it split the file at just those positions – neat! And just a few clicks.

But wait: I have quite a number of podcasts (e.g. many episodes of se-radio). And ‘quite a number’ times ‘a few clicks’ is definitely too much boring work. But thou shall not worry: mp3splt is a command line tool, and hence can be used from within batch files.

Splitting a Single File

The following batch file splits a given file (‘example.mp3’) into smaller files at all silence positions that are longer than 2 seconds and stores the resulting files in a folder that is named like the file, but without the extension (‘example’).

REM splitfile.bat
mp3splt -s -p min=2 -d "%~n1" %1

Splitting all Files in a Directory

The following batch file calls the first file for all mp3s in the current directory:

REM splitdir.bat
for /f "tokens=*" %%a IN ('dir /b *.mp3') do call splitfile.bat "%%a"

Yay, works! (Even if there are blanks in the file names.)

Classic for-loop in a windows batch file

Question: How can a classic for loop

for (int i=0;i<10;++i) {
// do stuff
}

be realized in a windows batch file?

Answer:

echo off
SET /a i=0

:loop
IF %i%==10 GOTO END
echo This is iteration %i%.
SET /a i=%i%+1
GOTO LOOP

:end
echo That’s it!

The answer uses goto and the /A option of the set command. Without that option, SET interprets the right side of the equals sign as a string and i would contain ‘i+1’, then ‘i+1+1’ and so on. To make SET interpret the right side as an arithmetic operation, the option /A is required. Enter SET /? to get a detailed explanation of the SET command’s capabilities.

Calling one Batch File from another (cascading batch files)

When you use batch files in windows xp, you may want to call a set of batch files from another batch file. Let’s say your file is named foo.bat and looks like this:

echo off
echo "Starting foo.bat"
subFoo1.bat
subFoo2.bat
echo "Finished foo.bat"

You will never see Finished foo.bat, since the batch processing will stop after the execution foo1.bat.

To fix this, you need to call the command line processor for each batch file:

echo off
echo "Starting foo.bat"
cmd /C subFoo1.bat
cmd /C subFoo2.bat
echo "Finished foo.bat"

Or you can use the call-command:

echo off
echo "Starting foo.bat"
call subFoo1.bat
call subFoo2.bat
echo "Finished foo.bat"