Background
I listen to a lot of tech podcasts, and a while back I started not being able to keep up with all of them on a weekly basis. The thought of dropping some of them to make room wasn’t really an option. So I started fast forwarding through some of the “dead air” in an attempt to speed up their playback. This got old pretty quickly. Being a pretty tech. savvy person, I thought there had to be a programmatic way to solve my dilema. I initially latched on to the idea that a program could remove/compress this “dead air” automatically so that its effect would be minimized. This would in theory condense a 1 hour podcast to something less than an hour. Although my final solution didn’t exactly go this route, there was enough of a kernel of an idea that ultimately led me to a workable solution.
Initial Concept
The biggest irony in my solution? it came while I was listening to a podcast, The Linux Outlaws. I think it was this episode. One of the listeners had either emailed or called in with the crux of the solution that I ultimately utilized to get exactly what I wanted. The key concept that this listener had mentioned was changing the tempo of an audio file. Now I’m no audiophile but I had heard the term tempo before, I just never really put much thought into exactly what it was. This listener claimed that you could increase/decrease the tempo of an audio file but still maintain its listenability. My previous experience with speeding up audio, was taking 45 and 78 RPM records and cranking up the speed dial on my turntable so that they sounded like Alvin and the Chimpmunks, an effect called resampling.
Subsequent googling turned up this Wikipedia article. In a nutshell, tempo is similar to the beats per minute (bpm) in music. So what we’re doing when we manipulate the tempo, is we’re increasing/decreasing the beats per minute, but we’re maintaining the pitch of those beats. The key component in maintaining the original quality of an audio file, is to maintain its pitch. Increasing the pitch is the effect you are hearing when you simply turn up the playback speed, as in the turntable example.
mp3faster
So how do you affect the tempo without messing with the pitch? Several tools can do this. Audacity is one of them. However I wanted to develop a script that would do this, because I ultimately wanted to have my podcatching software, bashpodder, automatically speed up all the MP3 files that it downloads. Some more googling turned up exactly what I was looking for, a page on the gPodder wiki” about time stretching . This wiki page had a script on it called mp3faster that did exactly what I wanted. The centerpiece to this script is a command-line tool called soundstretch, which is part of a suite of tools called SoundTouch. The mp3faster script was originally developed to run on Ubuntu, I’ve since modified it with the following enhancements:
- runs on Redhat Distros (RHEL, Fedora, & CentOS)
- improved method for converting the initial MP3 file to WAV
- improved the copying of the original MP3′s id3 tags over to the new MP3 file
- variablized the tempo so that it can be passed in as a command line arguement
- force the replacement of the original MP3 file with the newly modified version
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | % more mp3faster.bash #!/bin/bash # mp3faster - script for making mp3 playback faster with soundstretch # # debian/ubuntu package requirements # apt-get install mpg321 soundstretch lame libid3-3.8.3-dev # # rhel/centos/fedora package requirements # yum install mpg321 soundtouch lame id3lib # # sample usage for converting all mp3 files in a directory structure: # find -name "*.mp3" -print0 | xargs -0 -i mp3faster {} # # decode mp3 to wav file #mpg321 --wav "$1.wav" "$1" # the above decoding technique doesn't always work, and can sometimes # create a wav file that plays back too fast. Seems to happen with mp3 files that # have a low bitrate (< 80kbps). Using the lame alternative below get's around this. # alternative #1 to decoding an mp3 to wav lame --decode "$1" "$1.wav" # alternative #2 to decoding an mp3 to wav # mpg321 -b 10000 -s -r 44100 $1 | sox -t raw -r 44100 -s -w -c2 - "$1.wav" # process file with soundstretch #soundstretch "$1.wav" "$1.fast.wav" -tempo=+65 soundstretch "$1.wav" "$1.fast.wav" -tempo=+$2 # encode mp3 file lame --preset fast medium "$1.fast.wav" "$1.2.mp3" # copy id3 tags from old file id3cp -1 "$1" "$1.2.mp3" # remove temp files rm "$1.wav" "$1.fast.wav" # rename original mp3 file to .bak extension # mv "$1" "$1.bak" # rename processed mp3 file to original name mv -f "$1.2.mp3" "$1" |
Prerequisites
To install the prerequisite software on my CentOS 5 system, I used the following command:
1 | yum install mpg321 soundtouch lame id3lib |
Bashpodder
bp.conf
I then modified my bashpodder config file, bp.conf, so that every line that contained a URL of an RSS feed now included the value that I wanted to use for the tempo. The value I chose was 65. 65 initially was almost too fast, but after about 2 weeks it became very tolerable, and in fact, it is now impossible for me to listen to most of the podcasts at their regular speed. It’s just too slow.
NOTE: My bp.conf file is formated like this per line: <RSS URL> <directory name> <tempo>
1 2 3 4 5 6 7 8 9 10 | # NPR: Science Friday http://www.sciencefriday.com/audio/scifriaudio.xml npr_scifri 65 # this WEEK in TECH - MP3 Edition http://leo.am/podcasts/twit twit 65 # The Linux Link Tech Show MP3 Feed http://www.thelinuxlink.net/tllts/tllts.rss tllts 65 # The lottalinuxlinks linux podcast http://lottalinuxlinks.com/podcast/rss.xml lottalinuxlinks 65 # FLOSS Weekly http://leo.am/podcasts/floss floss_weekly 65 |
bashpodder.sh
I’ve modified bashpodder.sh so much that I can’t really recall what’s original and what’s mine. So here are some of the interesting bits that make mp3faster.bash work. First off I specify the name of bp.conf like so:
1 | fetchlist='bp.conf' |
This is then pulled in as input to a while loop. The while loop does all the lifting of seperating out the RSS URL, the directory name, and the tempo value. The values for these bits are stored in the 3 variables that are being passed to the while loop. The variables are called: podcast, feeddir, and tempo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | ... ... ... while read podcast feeddir tempo; do # Skip lines beginning with '#' as comment lines - from Rick Slater if echo $podcast | grep '^#' > /dev/null; then continue fi ... ... ... done < $fetchlist ... ... ... |
And here’s the block within the while loop that changes directory to the feed directory, downloads the MP3 file based on the RSS feed. After downloading, the file is condensed by mp3faster.bash, and then the feed directory is exited.
1 2 3 4 5 6 7 8 9 10 11 | ...
...
...
pushd $feeddir > /dev/null 2>&1
#wget $wget_continue $wget_quiet -q -P "$feeddir" "$url" &
mp3filename=$(echo "$url" | awk -F'/' {'print $NF'} | awk -F'=' {'print $NF'} | awk -F'?' {'print $1'})
(wget $wget_continue $wget_quiet -O $mp3filename "$url"; ../mp3faster.bash $mp3filename $tempo > /dev/null 2>&1) &
popd > /dev/null 2>&1
...
...
... |
The line that does the downloading and then calling mp3faster.bash is called a list, due to the fact it’s sitting inside of parentheses, ( command1; command2 ). The entire list of commands, i.e.
1 | ( wget ...; ../mp3faster.bash $mp3filename $tempo ... ) & |
is then backgrounded so that all the MP3′s can be downloaded and run through mp3faster.bash simultaneously. This can definitely be a drag on your system while all this downloading and processing is going on at once, but I run this on a spare CentOS 5 server box, and so it hasn’t really ever been a problem. If this was my primary desktop, then I might augment this approach, but it’s been working this way for over a year now with no major problems, so I’m content to just leave it this way.
1 | (wget $wget_continue $wget_quiet -O $mp3filename "$url"; ../mp3faster.bash $mp3filename $tempo > /dev/null 2>&1) & |
My version of the bashpodder.sh script can be viewed here.
Final Thoughts
The amount of time you can shave off of a podcast is a bit of a moving target so I’ll just share some data points for 2 recent podcasts.
| Podcast | Original Length | New Length |
|---|---|---|
| Security Now | 51 min. | 31 min. |
| TLLTS | 2 hrs. 28 min. | 1 hr. 33 min. |
Those are pretty huge savings in time and I’m not really losing any of the content. It’s just tightening them up.
Other Approaches
While doing research for this post I came across this solution, which is similar to mine, except it’s for Windows.

Wow!
This is what I need to get through my weekly TWiT fix. Wonder if I can do it with Macports or if I’ll have to do it on the server
Thx slmingol
Glad it helped. That’s what I use it for too 8-).