How can I combine a number of (timestamped) wav files into one long file?
September 19, 2010 6:55 AM   Subscribe

I have a number of wav files, timestamped as hhmmss.wav and would like to combine them into a single file with all of the clips at their correct (relative) positions. Does anyone have any ideas of how to do this?

Detail: I am training to be an Air Traffic Controller, and we are able to record our simulator exercises to listen back to later.

The bad: It has its own software player, so needs a computer to play back.

The good: The recordings are stored as a series of WAV files, named as e.g. "142004.wav", for a transmission at 14:20:04. It is possible that some of these will overlap.

I would like to use these timestamps to combine the WAVs into a single file, which could then be encoded as MP3 or similar for playback on other devices.

I've looked briefly into Python options, and a little at audacity. Does anyone have any ideas of how to do this (relatively) easily. I'm wary of overengineering a solution and making it more effort than it's worth.

Thanks for any help.
posted by d7415 to Computers & Internet (12 answers total)
 
I think you can do this with avisynth, although i've never tried it. It basically is a non linear video editing solution that's 100% scriptable. Don't know if it can produce wav files, but you can always convert any video output it creates with ffmpeg.
posted by 3mendo at 6:59 AM on September 19, 2010


Otherwise try sox
posted by 3mendo at 7:03 AM on September 19, 2010


This *might* work, and is simple enough to not pass up trying atleast once. From a CMD prompt while in the WAV directory:

copy *.wav final.wav

Usually it will copy in alphabetical order (technique is used often for splitting large mpg/avi files...though I've never tried it with wav)
posted by samsara at 7:04 AM on September 19, 2010


Response by poster: samsara: Looks like the wav headers don't allow concatenation like that.

3mendo: Just had a look at sox. I'm not sure it will put them in the right place (but I may just need to look harder) but it should at least be able to join them up. Looking at avisynth now....
posted by d7415 at 7:29 AM on September 19, 2010


What happens if there are multiple audio streams applicable for a certain time span? Do you mind hearing them simultaneously? If not, sox and audacity should do the trick.

Suppose your first WAV is 093054.wav i.e. 09:30:54 AM

then for each of your WAV files, you need to run

sox HHMMSS.wav HHMMSS-padded.wav pad {time offset from 09:30:54 in seconds} i.e., for 104553.wav, it should be

sox 104553.wav 104553-padded.wav pad 4499


Once done, load all files in Audacity at once, downmix and export.
posted by Gyan at 7:36 AM on September 19, 2010


Ah yes, of course, sorry about that. Ok here's another method that should work. Grab a copy of foobar2000 and load all of your wavs into a playlist. Highlight them, and right-click/convert/...

From there you can change the destination to a single output file.
posted by samsara at 7:42 AM on September 19, 2010


Response by poster: samsara: Good thinking, but sox does that nicely (now that I've been pointed that way!) and is easier for me as I'm in Linux most of the time. Thanks though!

Gyan: You've read my mind - I'm just running a script I've bodged together to do that, and I'll be running it through Audacity when it's done. That should work fine.

I don't suppose anyone knows how to do the combining/downmixing from the command line? Just a thought. It'd be nice to be able to combine all of this into one script....

*goes looking into the sox documentation again*
posted by d7415 at 8:15 AM on September 19, 2010


Response by poster: Update: "merge" command looks promising for a start....
posted by d7415 at 8:17 AM on September 19, 2010


Previously, for sox.
posted by rhizome at 9:27 AM on September 19, 2010


Convert to mp3 and then concatenate the files. On Macs and Linux you can just cat filenames > singlefile
posted by zippy at 9:53 AM on September 19, 2010


Response by poster: Thanks, guys. Rewrote the script, repadded the files, now trying to use sox to combine them. It's running now, I'll let you know how it works out (and if it does, I'll post the script here for the next guy)
posted by d7415 at 10:02 AM on September 19, 2010


Response by poster: After some effort, it seems to all work. Originally the output was very quiet, so I added the normalisation to the final sox call.
#!/bin/bash
# Combines a number of files with timestamps (hhmmss.wav) into a file with the clips in the correct place.
# It's a bodge. But it works. Or it did before I made it presentable, anyway.

# Get the time from the first filename
for i in $(ls *.wav)
do
  FIRST_H=${i:0:2}
  FIRST_M=${i:2:2}
  FIRST_S=${i:4:2}
  # This might be better, but not tested:
  # FIRST = $(( ${i:0:2}*3600 + ${i:2:2}*60 + ${i:4:2} ))
break
done

for i in $(ls *.wav)
do
  # Get the time from this filename, relative to the first.
  PREPAD_H=`echo "${i:0:2}-$FIRST_H" | bc`
  PREPAD_M=`echo "${i:2:2}-$FIRST_M" | bc`
  PREPAD_S=`echo "${i:4:2}-$FIRST_S" | bc`
  # As above; Untested.
  # PREPAD = $(( ${i:0:2}*3600 + ${i:2:2}*60 + ${i:4:2} ))

  # Calculate this in seconds
  PAD=$(( $PREPAD_H*3600 + $PREPAD_M*60 + $PREPAD_S ))
  
  # And again:
  # PAD = $(( $PREPAD - $FIRST ))

  # Apply the padding
  echo Adding $PAD second delay to $i
  sox $i out/${i%.wav}.flac pad $PAD
done

# Combine all files
# M = Merge files (play all at once)
# S = Show progress
# out/*.flac = input files
# final.flac = output file
# channels 2 = stereo
# gain -n = normalise output
sox -MS out/*.flac final.flac channels 2 gain -n

# If desired, delete the temporary files/directory
# rm out/*
# rm -r out

posted by d7415 at 9:00 AM on September 20, 2010


« Older Where should we pick apples?   |   spend my $1000 on a laptop, please. Newer »
This thread is closed to new comments.