The best — though least helpful — way to do this is not to use MP3 files as your source files. WAV, FLAC or M4A files don't have this problem.

MP3s aren't made up of fixed-rate samples, so cropping out a section of an arbitrary length will not work as you expect. Unless the encoder was smart (like lame), there will often be a gap at the start or end of the MP3 file's audio. I did a test with a sample 0.98s long (which is precisely 73½ CDDA frames, and many MP3 encoders use frames for minimum sample lengths). I then encoded the sample with three different MP3 encoders (lame, sox, and the ancient shine), then decoded those files with three decoders (lame, sox, and madplay). Here's how the sample lengths compare to the original:

 Enc.→Dec.          Length     Samples  CDDA Frames
 -----------------  ---------  -------  -----------
 shine→lame         0.95"      42095    71.5901
 shine→madplay      0.97"      42624    72.4898
 shine→sox          0.97"      42624    72.4898
 lame→lame          0.98"      43218    73.5000
*Original           0.98"      43218    73.5000
 sox→sox            0.99"      43776    74.4490
 sox→lame           1.01"      44399    75.5085
 lame→madplay       1.02"      44928    76.4082
 lame→sox           1.02"      44928    76.4082
 sox→madplay        1.02"      44928    76.4082

Only the file encoded and decoded by lame ended up the same length (mostly because lame inserts a length tag to correct for these too-short samples, and knows how to decode it). Everything encoded by sox ended up with a tiny gap, no matter what decoder I used. So joining the files will result in tiny clicks.

Your browser is likely mixing and overlapping the source files very slightly so you don't hear the clicks. Gapless playback is hard to do correctly.

Answer from scruss on Stack Overflow
Top answer
1 of 3
12

The best — though least helpful — way to do this is not to use MP3 files as your source files. WAV, FLAC or M4A files don't have this problem.

MP3s aren't made up of fixed-rate samples, so cropping out a section of an arbitrary length will not work as you expect. Unless the encoder was smart (like lame), there will often be a gap at the start or end of the MP3 file's audio. I did a test with a sample 0.98s long (which is precisely 73½ CDDA frames, and many MP3 encoders use frames for minimum sample lengths). I then encoded the sample with three different MP3 encoders (lame, sox, and the ancient shine), then decoded those files with three decoders (lame, sox, and madplay). Here's how the sample lengths compare to the original:

 Enc.→Dec.          Length     Samples  CDDA Frames
 -----------------  ---------  -------  -----------
 shine→lame         0.95"      42095    71.5901
 shine→madplay      0.97"      42624    72.4898
 shine→sox          0.97"      42624    72.4898
 lame→lame          0.98"      43218    73.5000
*Original           0.98"      43218    73.5000
 sox→sox            0.99"      43776    74.4490
 sox→lame           1.01"      44399    75.5085
 lame→madplay       1.02"      44928    76.4082
 lame→sox           1.02"      44928    76.4082
 sox→madplay        1.02"      44928    76.4082

Only the file encoded and decoded by lame ended up the same length (mostly because lame inserts a length tag to correct for these too-short samples, and knows how to decode it). Everything encoded by sox ended up with a tiny gap, no matter what decoder I used. So joining the files will result in tiny clicks.

Your browser is likely mixing and overlapping the source files very slightly so you don't hear the clicks. Gapless playback is hard to do correctly.

2 of 3
6

This is my guess for your issue:

  • sox does not add time gap during concatenation,
  • however it add time-gap in other operations, for instance if you do a conversion before the concatenation.

To find out what happens I suggest you to check all durations of your files at each time (you can use soxi for instance) to see what's going on.

If it doesn't work (the time-gap is added during concatenation), let me please do another guess:

  • Sox add time gap because your samples at the beginning or at the end of the file are not close to zero.

To solve this, you could use very short fade-in an fade-out on you files.

Moreover, to force sox to output files with a well-defined length, you could use the trim parameter like this:

sox filein.mp3 trim 0 duration fileout.mp3
Discussions

Need a batch file to merge audio files using Sox
Find answers to Need a batch file to merge audio files using Sox from the expert community at Experts Exchange More on experts-exchange.com
🌐 experts-exchange.com
July 31, 2019
Merge 2 audio files in sox - Stack Overflow
I am trying to merge 2 wave files into one file. The 2 files should start playing at the beginning of the new file. Independently of sound length. Running the following command does not give me this More on stackoverflow.com
🌐 stackoverflow.com
Combine 3 WAV files with Sox? merge and concatenate difference?
Hi, u/hugeaurorafan ! This is a reminder about Rule #1 (If you have already added great details, awesome, ignore this comment): DETAILS MATTER: Use detail in your post. If you are posting for help with specific hardware, please post the brand/model. If you need help troubleshooting, post what you have done, post the hardware/software you are using, post the steps to recreate the problem. Don’t post a screenshot (or any image, really) with no context and expect people to know what you are talking about. How to ask good questions: http://www.catb.org/esr/faqs/smart-questions.html I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns. More on reddit.com
🌐 r/audio
4
1
May 31, 2022
Sox : merge two audio files with a pad - Stack Overflow
Find centralized, trusted content ... you use most. Learn more about Collectives ... Bring the best of human thought and AI automation together at your work. Explore Stack Internal ... Save this question. Show activity on this post. I'm using the sox tool and I would like to merge two audio files, let's say ... More on stackoverflow.com
🌐 stackoverflow.com
🌐
Billposer
billposer.org › Linguistics › Computation › SoxTutorial.html
Using SOX
The files to be concatenated must be of the same type, have the same sampling rate, and so forth. ... Sox can synthesize a number of standard waveforms and types of noise. These are specified by means of the synth effect. Even though sox creates the output from scratch, an input file name must ...
🌐
Super User
superuser.com › questions › 789059 › concatenate-wav-audio-files-leaving-a-small-gap-using-sox-or-other-command-line
Concatenate wav audio files leaving a small gap using SoX or other command line tool - Super User
July 28, 2014 - I just tried this. sox -t sox <(sox the-proclaimers_500miles.mp3 -p pad 3 0 ) -t sox <(sox the-proclaimers_500miles.mp3 -p pad 3 0 ) -d ... I get the same error, though preceded by an error saying that it can not find 500 miles by the proclaimers. It may be that you do not have this song in your present working directory. ... Find the answer to your question by asking.
🌐
Experts Exchange
experts-exchange.com › questions › 29153650 › Need-a-batch-file-to-merge-audio-files-using-Sox.html
Solved: Need a batch file to merge audio files using Sox | Experts Exchange
July 31, 2019 - ro.wav rem Initialize file count ... Seq=!Seq:~-3! rem Merge intro and this file, save as new file with sequence number sox --combine concatenate "%IntroFile%" "�seDir%\%%~nxA" "�stDir%\EPR5!Seq!.wav" ) pause...
🌐
Yes I Know IT!
yesik.it › blog › 2018-sox
How to process audio files from the command line with SoX | Yes, I Know IT !
While the concatenate combiner processes the files one after the other, the merge combiner process them all in parallel: sh$ sox --combine merge \ 100_D_LikeAClock_*.wav \ combined.wav sh$ soxi 100_D_LikeAClock_*.wav combined.wav | grep -e Length -e File -e Duration -e Channels Input File : '100_D_LikeAClock_01_381.wav' Channels : 2 Duration : 00:00:14.40 = 635040 samples = 1080 CDDA sectors File Size : 2.54M Input File : '100_D_LikeAClock_02_381.wav' Channels : 2 Duration : 00:00:19.20 = 846720 samples = 1440 CDDA sectors File Size : 3.39M Input File : 'combined.wav' Channels : 4 Duration : 00:00:19.20 = 846720 samples = 1440 CDDA sectors File Size : 6.77M
🌐
Linux Man Pages
linux.die.net › man › 1 › soxmix
soxmix(1) - Linux man page
For all methods other than 'sequence', multiple input files must have the same sampling rate; if necessary, separate SoX invocations can be used to make sampling rate adjustments prior to combining. If the 'concatenate' combining method is selected (usually, this will be by default) then the input files must also have the same number of channels. The audio from each input will be concatenated in the order given to form the output file.
Find elsewhere
Top answer
1 of 2
21

If all the files have the same parameters, like sample rate and number of channels, you still can't just catenate them. You have to strip away the WAV header.

It may be easiest to use an audio file manipulation utility like sox, which contains a method for catenating files. In fact, it does this by default. E.g. to combine three .wav files into one long one:

$ sox short1.wav short2.wav short3.wav long.wav

A loop will not arrange the files in the order you want. What you want is to sort the names, but treat them numerically. sort -n will do this.

Thus:

$ sox $(ls *.wav | sort -n) out.wav

If sox cannot handle that many files, we can break up the job like this:

$ ls *.wav | sort -n > script

Then we have a script file which looks like:

1.wav
2.wav
...
3999.wav
4000.wav
...
file7500.wav

We edit that to make several command lines:

# catenate about half the files to temp1.wav   
sox \
1.wav \
2.wav \
... \
3999.wav \
temp1.wav

# catenate the remainder to temp2.wav  
sox \
4000.wav \
... \
7500.wav \
temp2.wav

# catenate the two halves
sox temp1.wav temp2.wav out.wav ; rm temp1.wav temp2.wav

As the first editing step on the file list, you can use the vi command :%s/.*/& \\/ to add a backslash after every line.

2 of 2
0

This has been bugging me today as well as I had many more files to concatenate than sox can load. So I ended up using this shell script inside the folder with the wavs (please make sure you don't need in.wav and out.wav as they'll be overwritten):

rm in.wav out.wav                                                                                                                            
ls *.wav | sort -n | while read l;
do                                                                                                                                                            
   if [ ! -f in.wav ]                                                                                                                                         
   then                                                                                                                                                       
      cp $l in.wav                                                                                                                                            
   else                                                                                                                                                       
      sox in.wav $l out.wav                                                                                                                                   
      cp out.wav in.wav                                                                                                                                       
   fi                                                                                                                                                         
   echo "$l"                                                                                                                                                  
done        
``
🌐
Readthedocs
pysox.readthedocs.io › en › latest › _modules › sox › combine.html
Source code for sox.combine - pysox's documentation!
''' from __future__ import ... 'multiply'] [docs]class Combiner(Transformer): '''Audio file combiner. Class which allows multiple files to be combined to create an output file, saved to output_filepath....
🌐
Reddit
reddit.com › r/audio › combine 3 wav files with sox? merge and concatenate difference?
r/audio on Reddit: Combine 3 WAV files with Sox? merge and concatenate difference?
May 31, 2022 -

This is poorly documented in the Sox documentation and the web. How do I use Sox to combine 3 2GB 2496 WAVs into one 2496 FLAC file?

What is the difference between "concatenate" and "merge"?

I've tried:

"C:\Program Files\sox-14-4-2\sox.exe" --combine concatenate ZOOM0002.WAV ZOOM0003.WAV ZOOM0004.WAV joined-c.flac

and

"C:\Program Files\sox-14-4-2\sox.exe" --combine merge ZOOM0002.WAV ZOOM0003.WAV ZOOM0004.WAV joined-m.flac

Both seem to do the same thing but the output files are slightly different in size. The output FLAC file should be seamless with no gaps or glitches.

🌐
Opensource.com
opensource.com › article › 20 › 2 › linux-sox
Convert audio files with this versatile Linux command | Opensource.com
February 2, 2021 - To join (or concatenate) files into one, provide more than one input file in your command: ... In this example, output.flac now contains countdown audio, followed immediately by intro music.
🌐
GitHub
github.com › jasny › audio
GitHub - jasny/audio: Process audio files using SoX
$track = new Track("sometrack.wav"); $track->convert("sometrack.mp3"); Combine two tracks. Uses sox --combine. Available methods · concatenate · merge · mix · mix-power · multiply ·
Starred by 51 users
Forked by 16 users
Languages: PHP 100.0% | PHP 100.0%
🌐
SourceForge
sourceforge.net › home › browse › sox - sound exchange › mailing lists
Thread: [SoX-users] mixing audio tracks | SoX - Sound eXchange
Brought to you by: cbagwell, mansr, robs, rrt, uklauer · Summary · Files · Reviews · Support · Mailing Lists · Tickets ▾ · Bugs · Feature Requests · Patches · News · Code · Menu ▾ ▴ · sox-commits · sox-devel · sox-users ·
🌐
Medium
medium.com › geekculture › processing-pcm-audio-with-sox-command-line-tool-97977ca8d3c4
Processing PCM audio with SoX command-line tool | by Andy Jazz | Medium
June 1, 2026 - Audio bit depth and format do not matter at the moment. Based on the above, it turns out that only one file needs to be modified. ... Now we’re ready to concatenate all the files into a single CAF file. It is as easy as saying “cheese”. As you can imagine, the resulting concatenated.caf file will be 32-bit / 96 kHz and 15 seconds long. Execute it: sox noise.aiff a432.flac voice.wav concatenated.caf
🌐
Slackermedia
slackermedia.info › handbook › doku.php
sox [Slackermedia Handbook]
To join (or concatenate) files into one, provide more than one input file in your command: ... In this example, output.flac now contains countdown audio, followed immediately by intro music. If you want the two tracks to play over one another at the same time, though, you can use the --combine ...
🌐
GitHub
gist.github.com › wbigger › edcc110893306feb92a603a68d2b5e8d
Concatenate audio files with sox · GitHub
February 13, 2019 - Save wbigger/edcc110893306feb92a603a68d2b5e8d to your computer and use it in GitHub Desktop. Download ZIP · Concatenate audio files with sox · Raw · eccio.sh · This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below.