To join audio files means to concatenate the decoded samples of two or more tracks in a chosen order and save the result as one continuous audio file, with no inserted silence, overlap, crossfade, fade-in, fade-out, or level change between them. The output is a gap-free WAV in which the last sample frame of one decoded track is immediately followed by the first sample frame of the next track in the output channel arrays. In a browser-based joiner, the workflow is to pick 2 to 10 source files, let the Web Audio API decode each one through a shared AudioContext, reorder the decoded tracks into the final sequence, and encode one PCM16 WAV using a standard 44-byte little-endian RIFF header. The Audio Joiner follows exactly that path: it combines 2 to 10 browser-decodable audio files in the order shown on screen, decodes them locally, and produces one downloadable WAV. Because every step runs inside the current browser tab, no source file is uploaded to a remote server, and the file you save is the same WAV that is previewed on the page.

how to join audio files
how to join audio files

What joining audio files actually means

Joining is a strict sample-level operation, not a track-based one. Each source file is decoded into per-channel Float32Array sample data, and each decoded channel is copied into one combined Float32Array at tested cumulative frame offsets. The last frame of track 1 sits directly next to the first frame of track 2, with no padding, no trimming, no fade, and no normalization. That is what "joining in this order" means in a deterministic joiner: the visible list order is the exact output order, and changing the list changes the output bytes. Reordering changes the decoded-buffer array and the visible list together, and it clears any older WAV so a stale result cannot claim a previous order.

The decode step itself is performed by the Web Audio API. The MDN BaseAudioContext decodeAudioData page describes how decodeAudioData turns a compressed audio buffer into an AudioBuffer holding per-channel Float32Array samples ready for further processing, and the MDN AudioBuffer reference documents the per-channel sample storage that the joiner copies into the output. If the original files are encoded with a codec the current browser can decode, the joiner sees those samples; if not, the decode fails and the selection is rejected.

Hard limits the join enforces

Limits are explicit and run before any encoding work begins. The selection must hold between 2 and 10 files. Each file may be no larger than 25 MiB (26,214,400 bytes). The full selection may not exceed 100 MiB (104,857,600 bytes). Across all selected tracks, the decoded audio may not exceed 30 minutes in total, 8 channels per track, 192 kHz, or 30 million samples counted across all channels.

LimitValue
Tracks per join2 to 10
Per-file size25 MiB (26,214,400 bytes)
Total selection size100 MiB (104,857,600 bytes)
Total decoded duration30 minutes
Sample rateup to 192 kHz
Channel count per trackup to 8
Combined channel-samples30,000,000

A high-rate or multichannel selection can reach the 30 million sample budget before the 30 minute limit, because each second of 192 kHz 8-channel audio already accounts for 1,536,000 channel-samples. When a limit is hit, the joiner does not downsample, shorten, downmix, or omit anything to fit; the selection is rejected with a specific message so the user can adjust the inputs and try again.

How to join audio files in your browser

  1. Open the Audio Joiner in a current desktop browser such as Chrome, Firefox, Safari, or Edge. Make sure the browser supports the Web Audio API and the codec used in your source files.
  2. Choose 2 to 10 audio files from your computer using the file picker. The picker recognizes common MP3, WAV, M4A, AAC, Ogg, WebM, and FLAC names and MIME types, but a recognized extension does not guarantee that every codec variant can be decoded by Safari, Chrome, Firefox, or another browser. Damaged, incomplete, encrypted, or mislabeled sources produce a clear error rather than a silent skip.
  3. Wait for the browser to finish decoding each file through the shared AudioContext. The decoded track list shows the working sample rate and channel count for each file. If any track is rejected because of a per-file or total limit, a channel-count mismatch, or an unsupported codec, the selection stops and the offending file is named in the error message.
  4. Preview each decoded track and use Move up or Move down until the list shows the order you want in the output. Reordering clears any older WAV so the preview always reflects the current list.
  5. Select Join in this order and wait for the encoder to interleave the decoded channels into one PCM16 stream and write the 44-byte little-endian RIFF/WAVE header. Float samples are clipped to the range from -1 through 1, negative full scale maps to -32768, positive full scale to 32767, and non-finite values are written as silence.
  6. Preview the resulting WAV to confirm duration, order, joins, and channel playback, then download it to your computer. The file is a freshly encoded RIFF/WAVE with interleaved, little-endian, signed 16-bit PCM samples.

What the output WAV contains and discards

The output WAV contains only the decoded audio samples, in the order you chose, with the channel layout that the source files shared. It does not preserve the original codec, the original bitrate, the original encoder settings, ID3 or Vorbis tags, album art, chapters, cue points, loop points, loudness fields, timestamps, or any other container metadata. It is a new static PCM representation of the browser-decoded samples, so anything outside the audio stream itself is dropped.

That also means the WAV is uncompressed. PCM16 WAV is usually much larger than the equivalent MP3, AAC, Opus, Vorbis, or FLAC sources of the same content, and that is expected. A 1 minute stereo segment at 44.1 kHz and 16 bits uses 60 × 44,100 × 2 × 2 = 10,584,000 bytes of PCM audio, so the resulting WAV is about 10 MB plus a 44 byte header, regardless of how compact the source file was.

PropertyStatus in output WAV
Decoded audio samplesPreserved, concatenated in list order
Channel countPreserved, must match across tracks
Per-track orderPreserved exactly as shown in the list
Original codecReplaced by PCM16
Original bitrateDiscarded (PCM16 has no bitrate)
Encoder settingsDiscarded
ID3, Vorbis, or other tagsDiscarded
Album art, chapters, cue pointsDiscarded
Original sample rateMay change to the AudioContext working rate

The Web Audio API may resample source files to the working sample rate of the shared AudioContext, so the rate shown for each track and for the result may differ from the rates stored in the original files. The output does not preserve independent source sample rates. If the source files came in at 48 kHz but the browser context runs at 44.1 kHz, every track is resampled to 44.1 kHz before joining.

Common reasons a join is rejected and how to fix it

A join can be rejected for one of a few specific reasons, and each one produces a clear error rather than a partial result.

Channel-count mismatch is the most common reason. If one track decodes to mono and another decodes to stereo, the join is rejected. The joiner does not silently duplicate, drop, average, or remap channels. The fix is to convert all source files to the same channel count in a separate editor before joining, or to use the joiner for a set of files that already share a channel count.

Unsupported codec is the next common reason. Because decoding uses the Web Audio API, the result depends on the codecs available in the current browser and operating system. A recognized extension such as .m4a or .ogg does not guarantee that every variant can be decoded in Safari, Chrome, or Firefox. The joiner does not bundle a codec library and does not use a server fallback, so the browser is the only decoder. The fix is to try a different browser, or to re-encode the source to a more universally supported format like WAV before joining.

Damaged or mislabeled files are rejected by the decoder. Encrypted files, incomplete downloads, or files whose actual content does not match the extension produce a clear error. The fix is to verify the file plays normally in a regular media player before adding it to the join.

Limit exceeded produces a specific error message that names the violated limit. The fix is to remove a file, shorten a file using a tool like the Audio Cutter, or split the join into two passes. The joiner does not silently shrink the output to fit a budget.

Stale preview is not really an error, but a guard against it exists: reordering clears the older result so a stale WAV cannot claim a previous order. If the preview still shows the previous WAV after a reorder, select Join in this order again to refresh the output.

Because every step happens in the current browser tab, keep the original source files until the downloaded WAV has the right duration, order, joins, channel playback, and file size. Once those properties are verified, the source files can be deleted.