A gap-free, locally produced 16-bit PCM WAV is the cleanest way to combine audio files without losing quality: the browser decodes each source through one AudioContext, copies the channel samples end-to-end in your chosen order, and writes a freshly encoded RIFF/WAVE file whose samples come straight from those decoded buffers. Because the join happens before the WAV encoder runs, the output never re-encodes an intermediate compressed file, never inserts silence between tracks, and never applies a crossfade or normalization. The result is an uncompressed 16-bit PCM file that preserves the decoded sample sequence exactly as your browser produced it, which is the closest a browser-based tool can get to a sample-identical merge.

Readers searching for a way to add audio to a visual project — a slideshow, a short video, a presentation reel — usually need one continuous audio file that behaves predictably in their editor. Joining the source clips into a single WAV first removes timing drift between multiple imports, avoids repeated re-encoding inside the video tool, and gives the editor one timeline-friendly asset to drop in. The challenge is doing that without quality loss, which is where a local, decode-then-concatenate pipeline matters.

add audio to image without losing quality
add audio to image without losing quality

What "Without Quality Loss" Actually Means in an Audio Join

Quality loss in audio concatenation usually comes from one of three places: re-encoding through a lossy codec, inserting silence or crossfades that change the perceived timing, or remixing channels so the output is no longer what the sources contained. A lossless audio join should leave the decoded samples untouched between the last sample of one track and the first sample of the next, and should write those samples into a container that does not compress them again.

Audio Joiner concatenates channel samples directly in list order. The last sample frame of one decoded track is followed immediately by the first sample frame of the next track in the output channel arrays, with no inserted silence, overlap, crossfade, normalization, transition, or automatic trimming. Matching channels are retained in their decoded order and concatenated independently before WAV interleaving, so the left and right channels of a stereo file stay identifiable through the join. The container is a standard RIFF/WAVE file with interleaved, little-endian, signed 16-bit PCM samples.

It is worth being honest about what is and is not preserved. The WAV does not preserve the original codec, bitrate, encoder settings, tags, album art, chapters, cue points, loop points, loudness fields, timestamps, or other container metadata — it is a new static PCM representation of the decoded samples. The decoded sample rate shown for the tracks and the result may also differ from rates stored in the original files, because Web Audio can resample sources to the context's working sample rate.

Why a Local Browser Joiner Avoids Re-Encoding

When you concatenate audio on a server, the files travel over the network, are processed on a machine you do not control, and the result is downloaded back. That round trip is fine for many use cases, but it adds upload time and a privacy step, and the server may run its own re-encode to a compressed format to save bandwidth. A browser-only joiner sidesteps both problems: file reading, Web Audio decoding, channel concatenation, WAV encoding, preview, and download all happen in the current browser tab.

The implementation uses one shared AudioContext for every file in one selection. That shared context may resample source files to its working sample rate, which is why a single join always runs at one rate rather than preserving independent source rates. The shared plan validates track count, sample rate, channel count, total frames, duration, channel-sample budget, and the frame offset where every track begins, so a corrupted frame or a misaligned plan is rejected rather than producing a silent or off-by-one output.

The encoder itself writes the RIFF size, WAVE and fmt identifiers, PCM format tag, channel count, decoded sample rate, byte rate, block alignment, 16-bit depth, data identifier, and exact data byte length into a 44-byte header, then clips each float sample 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 — before interleaving channels in frame order. If you want to see how a browser-side AudioBuffer feeds that pipeline, the MDN AudioBuffer reference describes the decoded sample container the joiner reads from.

How to Combine Audio Files Into One WAV

  1. Open Audio Joiner and choose 2 to 10 browser-decodable audio files. The picker recognizes common MP3, WAV, M4A, AAC, Ogg, WebM, and FLAC names and MIME types, though a recognized extension does not guarantee every codec variant decodes in Safari, Chrome, Firefox, or another browser.
  2. Watch the per-file and total budgets shown next to the picker. Each encoded file may be no larger than 25 MiB (26,214,400 bytes) and the selection may not exceed 100 MiB (104,857,600 bytes) total; nothing is shortened, downmixed, downsampled, or omitted to fit a limit, so an oversized selection is rejected with a specific message.
  3. Wait for the browser to decode each track. Decoding runs through one shared AudioContext, and you can preview each decoded track as it appears in the list.
  4. Use Move up or Move down on each row until the list shows the order you want. Reordering changes the decoded-buffer array and visible list together and clears any older WAV, so a stale result from a previous order cannot be mistaken for the current one.
  5. Select Join in this order. The tool builds a plan that checks decoded sample rate, channel count, total frames, duration, channel-sample budget, and the frame offset where every track begins, then copies each decoded channel into one Float32Array at tested cumulative frame offsets.
  6. Preview the resulting PCM16 WAV in the browser, then download it. Every download is a newly encoded RIFF/WAVE file with interleaved, little-endian, signed 16-bit PCM samples.
  7. Keep the source files until you have confirmed the downloaded duration, order, joins, channel playback, and file size are correct, then delete the originals.

Limits and Rules That Decide Whether the Join Succeeds

Because the join copies decoded samples into one output, the constraints are measured against the decoded buffers, not just the encoded files on disk. Decoded audio may not exceed 30 minutes in total, eight channels, 192 kHz, or 30 million samples counted across all channels. A high-rate or multichannel selection can reach the sample budget before the duration limit, which is why both numbers are displayed rather than only one of them.

Channel-count parity is enforced: all files must decode to the same channel count. A mono and stereo mixture is rejected rather than silently duplicating, dropping, averaging, or remapping channels, so you will never get a "converted" output you did not ask for. If your mix combines mono and stereo sources, convert them in a dedicated editor first or split the join into two mono or two stereo batches.

Codec coverage depends on your browser and operating system. Input decoding uses the Web Audio API and therefore depends on the codecs available there; damaged, encrypted, incomplete, mislabeled, or unsupported files produce a clear error rather than a silent failure. No codec library or server fallback is added, so the supported set is exactly what your current browser can decode.

LimitValueWhat happens when it is exceeded
Files in one selection2 to 10Selection rejected with a specific message
Per-file size25 MiB (26,214,400 bytes)Selection rejected; nothing is downsized to fit
Total selection size100 MiB (104,857,600 bytes)Selection rejected; nothing is downsized to fit
Total decoded duration30 minutesSelection rejected before encoding starts
Sample rateUp to 192 kHzHigher rates rejected by the plan
Channel countUp to 8, with all tracks matchingMismatched channels rejected, not remixed
Channel-sample budget30,000,000 samples across all channelsSelection rejected; can trigger before the duration limit

The tool also handles job identity and cleanup so a slow decode cannot overwrite a newer selection. Decode work carries a job identifier, and component cleanup invalidates older jobs. The AudioContext is closed after decoding, on replacement, and during cleanup, and selected files and the finished WAV use temporary local object URLs for playback and download that are released when replaced or when the page closes.

When to Use a Different Audio Tool

An audio joiner solves one job: concatenating full tracks into one file at the decoded sample level. If you need a time range rather than a full track, fades, loudness matching, channel conversion, compressed output, metadata preservation, or sample-level repair, you should reach for a dedicated editor instead. The limits above also mean that very long compilations need to be split into batches that each fit inside 30 minutes and 30 million channel-samples combined.

For readers who are preparing the joined audio to drop into a video or slideshow project, merging clips locally for a video project walks through the same joiner from that specific workflow angle, including how to think about the joined WAV once it lands on the video timeline. The MDN BaseAudioContext decodeAudioData page documents the decode step the joiner relies on, which is useful background if you want to understand why codec support tracks your browser rather than the tool.