I am trying to concatenate 15 wav audio files, recorded as 24-bit, 96kHz, linear PCM. I have run experiments with ffmpeg, shntool, and sox, with differing results.

The files were created by a Zoom H2n recorder, which split the ~15 hours of continuous recording into several files (in real time) to accommodate the SD memory card spec.

The first 14 files are each 2,147,385,344 bytes (1:02:08.04 in time) and the last file is 1,838,248,046 bytes (53:11.35 in time). The original files report a bitrate of 4,608 kb/s (using ffmpeg -i).

Using ffmpeg

Create a text file with the filenames:

printf "file '%s'\n" ./*.WAV > mylist.txt

Concatenate the files:

ffmpeg -f concat -i mylist.txt -c copy output-ffmpeg.wav

This generates a file that is 31,901,151,444 bytes, but reports as only 53:08 in time. ffmpeg -i reports a bitrate of 80,049 kb/s, much higher than the original 4,608 kb/s.

Using shntool

Join the files:

shntool join -r none 01.wav 02.wav [etc]

This generates a file that is 31,901,151,386 bytes -- different than the ffmpeg concatenate -- but also reports as 53:08.16 in time. Again, ffmpeg -i reports a bitrate of 80,049 kb/s, much higher than the original 4,608 kb/s.

Using Sox

Concatenate the files:

sox 01.wav 02.wav [etc] output-sox.wav

This generates a file that is 31,901,151,422 bytes -- different than both ffmpeg and shntool -- but reports as 01:02:08.26 in time. ffmpeg -i reports a bitrate of 68,452 kb/s, much higher than the original 4,608 kb/s but different than ffmpeg or shntool conversions.


1) How can I make the file reflect it's actual time? Bringing this 31 Gb / ~15 hour recording into audio software that thinks it's only ~53 min long is likely to be problematic.

2) Why do the three concatenations differ in file size? Is there a flag or setting I should be using to, for example, pad the length for some reason? Are the differing file sizes a clue as to why the files think they're only 53:08 or 01:02:08 long?

When I first saw the 53:08 I thought, Ah, it's writing the time length of the final file into the header -- but the time length of the final file is actually 53:11. When I first saw the 01:02:08.26 I thought, Ah, it's writing the time length of the FIRST file, but sadly, no (close, but not exact).

It seems like my best clue is the incorrect (?) bitrate of the concatenated files. I'm surprised a stream copy or file concatenation changes this. Perhaps it's just a metadata error?

  • I know this is no answer, but what about just throwing them into anything from Audacity to Pro Tools, butt-editing them & saving the result? – Tetsujin Jul 2 '15 at 15:41
  • Well, I could go to copy/paste, but there are two sets of 15, and I'll have to be careful about precise alignment of the segments so it will be time-consuming. It's my fall-back solution though, and is possibly less time-consuming than running the experiments and writing up this question! :) – Michael J. Jul 2 '15 at 15:43
  • 2
    wav is limited to 2/4 GBytes en.wikipedia.org/wiki/WAV#Limitations – befzz Jul 2 '15 at 16:55
  • 1
    Ok, this works great: "ffmpeg -f concat -i mylist.txt -c:a flac output-ffmpeg.flac" Duration: 15:23:03.94, bitrate: 3198 kb/s, file size: 22,144,074,469. (Mac OS X, ffmpeg installed via homebrew.) Thank you @befzz! – Michael J. Jul 2 '15 at 18:46
  • 1
    Since that works, either you or @befzz should write it up as an answer and accept it- as it stands, it is buried in the comments. And it is an excellent question with a (relatively) simple answer which is worth sharing! – bertieb Jul 3 '15 at 12:30

.wav is a RIFF File format (msdn)

Size of RIFF chunk data is stored in 32 bits. (max. unsigned value is 4 294 967 295)

RIFF is limited to ~4.2 GBytes per file.

When software creating a very big RIFF chunk, its storing size in 32 bit value.

At some point integer overflow is occur and higher bits of number is dropped:

Example file: 6.220 GBytes / 3:00:00 / 96000 Hz / 24 bit / 2 channels / 4608 kbit/s

Real file size(hex):              01 72 C9 E0 86  (6 220 800 134)
Readed from RIFF header(hex) :       72 C9 E0 7E  (1 925 832 830)

Real file size(binary):            1 01110010 11001001 11100000 10000110  //33 bits
Readed from RIFF header(binary):     01110010 11001001 11100000 01111110  //32 bits

01 here is dropped part.

ffprobe report:

Duration: 00:55:43.46, bitrate: 14884 kb/s
 Stream #0:0: Audio: pcm_s24le ([1][0][0][0] / 0x0001), 96000 Hz, 2 channels, s32 (24 bit), 4608 kb/s

FFprobe wrong duration / bitrate

FFprobe can't find any metadata in file and trying to calculate it from truthful data:

  1. One stream with bitrate: 4608 kbit/s (96000 Hz * 24 bit * 2 chan)
  2. RIFF chunk size: 1 925 832 830 (true, but wrong :D)

Duration will be(Whole chunk size divided by bitrate):

1 925 832 830 / (4 608 000 / 8) = 3343.459 seconds

/ 8 is because bitrate is bits per second (one byte is 8 bits)

3343.459 is exactly 00:55:43.459

(Average?) Bitrate for whole file is SizeOfFile / TotalSeconds:

6 220 800 134 / 3343.459 = 1860588.1316 Bytes/s ( 14884705.053 bits/s )

How to get one big file?

Use other formats to store it, like:

FLAC / .rf64 / .w64 / Etc.

To concatenate files using ffmpeg(FFmpeg Wiki Page Concatenate):

ffmpeg -f concat -i mylist.txt -c:a flac output-ffmpeg.flac

where mylist.txt is

file '/path/to/file1.wav'
file '/path/to/file2.wav'
file '/path/to/file3.wav'

Already have big WAV file?

You can play it. Whole. With a trick.
We will set size of RIFF data chunk as 0. This will cause some (?) audio players to read whole data chunk(till the end of file ?).

FFprobe report from edited file:

Duration: 03:00:00.00, bitrate: 4608 kb/s
 Stream #0:0: Audio: pcm_s24le ([1][0][0][0] / 0x0001), 96000 Hz, 2 channels, s32 (24 bit), 4608 kb/s

NOTE: Rewriting full file is not required when saving file in HEX editor.

  1. Download an free HEX editor (HxD for example)
  2. Make a screenshot or copy of marked bytes.(as a backup)
  3. Fill it with 00.
  4. If using HxD: Press save then Cancel button immediately (to prevent creating full backup copy)
  5. Open. (Tested in VLC / MPC-HC. but WMP failed :D) big wav in hex editor

Also FLAC can convert it using option --ignore-chunk-sizes

But FLAC will drop an error if .WAV have some metadata at end of file.
Tested with Audacity. Checked with HEX editor and found metadata at end of file.

FLAC: ERROR: got partial sample
But file with 2:59:59 seconds length. And without md5 checksum.
This is mean we have not true flac file(read corrupted).
But readable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.