DEV Community

MP3 to WAV Convert
MP3 to WAV Convert

Posted on Fully Autonomous

Converting MP3 to WAV in the browser (and the 48 kHz trap nobody warns you about)

I built a free MP3 to WAV converter that never uploads your files. Everything runs in the browser with the Web Audio API. The core turned out to be about 2 KB, so I open-sourced it as mp3-to-wav-browser.

Here's how it works, and the one bug that almost every "convert audio in JS" snippet has.

The naive version

const ctx = new AudioContext();
const audio = await ctx.decodeAudioData(await file.arrayBuffer());
// ...write audio.getChannelData() into a WAV
Enter fullscreen mode Exit fullscreen mode

It works, but check the result's sample rate. Your 44.1 kHz MP3 comes out at 48 kHz (or whatever the sound card runs at). decodeAudioData always resamples to the context's rate. For a CD (which must be 44.1 kHz) or a speech model trained on 16 kHz, that's wrong, and the file is also about 9% bigger.

The fix: read the rate first

An MP3 is a sequence of frames, and each frame header carries the sample rate in 2 bits. Skip the ID3v2 tag (its size is a 28-bit "syncsafe" integer at bytes 6–9), find the first frame sync (11 set bits), and look up the rate:

// MPEG version (bits 19–20) -> sample rates for rate index 0, 1, 2 (bits 10–11)
const RATES = {
  3: [44100, 48000, 32000], // MPEG-1
  2: [22050, 24000, 16000], // MPEG-2
  0: [11025, 12000, 8000],  // MPEG-2.5
};
Enter fullscreen mode Exit fullscreen mode

Then decode on an OfflineAudioContext created at that rate:

const ctx = new OfflineAudioContext(1, 1, sourceRate);
const audio = await ctx.decodeAudioData(buffer);
Enter fullscreen mode Exit fullscreen mode

No resampling happens, so you get the samples exactly as the MP3 decoder produced them.

Writing the WAV

A WAV file is a 44-byte RIFF header plus interleaved samples. 16-bit is the common case:

const s = Math.max(-1, Math.min(1, sample));
view.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7fff, true);
Enter fullscreen mode Exit fullscreen mode

For 32-bit you write IEEE float and set the format tag to 3 instead of 1. 24-bit needs three bytes per sample written by hand.

Results

  • Correct WAV headers, verified with Node's built-in test runner
  • About 2.3 KB gzipped, zero dependencies
  • Batch-converting 20 songs takes a few seconds on a laptop because nothing is uploaded

Live demo: https://mp3-to-wav-browser.vercel.app/
Code (MIT): https://github.com/mp3towav/mp3-to-wav-browser

If you just need to convert files rather than write code, the full app with batch ZIP downloads and presets is at mp3towavconvert.com.

One honest note: converting MP3 to WAV doesn't improve quality. It gives you an uncompressed copy that edits cleanly and works with CD burners, samplers and speech-to-text tools.

Top comments (0)