# WavPack&#39;s roundtrip advantage over FLAC

This page is about a non-obvious advantage of the audio codec [WavPack](!W).
I discovered it some years ago when archiving music I had made with samples as a teenager.
(Don&#39;t ask to hear it.
It is not good.)
WavPack has other cool features, like [&#34;hybrid mode&#34;](!W &#34;WavPack#Hybrid_mode&#34;), but I am not going to cover them here.

Current lossless audio codecs all have a compression ratio of [around 50%](https://wiki.hydrogenaud.io/index.php?title=Lossless_comparison).
Most people seem to use [FLAC](!W) for lossless audio compression.
FLAC is widely supported, including in browsers, and compresses as well as the rest.
So why choose WavPack, a less popular alternative?
WavPack has an unusual property: as far as I can tell, it always allows you to recover a bit-for-bit identical [PCM](!W &#34;Pulse-code modulation&#34;) [WAV file](!W &#34;WAV&#34;).
This means a WAV file roundtripped through WavPack will have an identical [checksum](!W).

This property got my attention in the 2010s when I wanted to save disk space while preserving my old files exactly as they were.
With more abundant disk space, it is less of a concern than it used to be.
If you need to get the same bits back, you can use a [good general-purpose compressor like Zstandard](/compressors) and eat the cost in storage and bandwidth because it&#39;s small.
Still, I find this feature fascinating, and I can think of cases where it is useful.
For example, when preserving a computer game in a public archive where it will be downloaded repeatedly, you want to both provide the original data and minimize the download size.

## Contents

## Demo

The following test shows the difference between FLAC and WavPack.
We will try a file where FLAC gets the exact file back and one where it doesn&#39;t.

For this demo, I will be using Debian 12 and issuing commands that work in both the POSIX shell and [fish](https://fishshell.com/).

First, let&#39;s create the files we will use for the test.
One we will download from [Wikimedia Commons](!W) as-is, and another we will download in MP3 and convert to PCM WAV.

```plaintext
$ sudo apt install -y b3sum curl file flac mpg123 wavpack xxd
[...]
$ curl -Lfs -o test.mp3 https://upload.wikimedia.org/wikipedia/commons/transcoded/2/2e/Mysterioso_Pizzicato.mid/Mysterioso_Pizzicato.mid.mp3
$ curl -Lfs -o test2.wav &#39;https://upload.wikimedia.org/wikipedia/commons/2/29/Drawing_of_the_word_Wikipedia_transformed_into_a_wav_file_%28Coagula_software%29.wav&#39;
$ mpg123 -w test.wav -q test.mp3
$ b3sum test*.wav
ef1ec2c71350ddec9b7a4d4143075020270651a2ffd1a605031ba7db43929cf9  test.wav
13cf3f16d09e7e120a3cd1d3dec500c8283c4cae1dd4278defc4505ba1801463  test2.wav
```

Let&#39;s compress each WAV file with both FLAC and WavPack using maximum compression.

```plaintext
$ flac --version
flac 1.4.2
$ wavpack --version
wavpack 5.6.0
libwavpack 5.6.0
$ flac -8 --silent test.wav
$ flac -8 --silent test2.wav
$ wavpack -hhx -q test.wav
$ wavpack -hhx -q test2.wav
$ du -h ./test*
532K	./test.flac
252K	./test.mp3
2.1M	./test.wav
524K	./test.wv
124K	./test2.flac
432K	./test2.wav
140K	./test2.wv
```

Now, we&#39;ll decompress the files back to WAV and checksum the source and the result.

```plaintext
$ flac -d -o test.flac.wav --silent test.flac
$ flac -d -o test2.flac.wav --silent test2.flac
$ wvunpack -o test.wv.wav -q test.wv
$ wvunpack -o test2.wv.wav -q test2.wv
$ b3sum test*.wav
ef1ec2c71350ddec9b7a4d4143075020270651a2ffd1a605031ba7db43929cf9  test.flac.wav
ef1ec2c71350ddec9b7a4d4143075020270651a2ffd1a605031ba7db43929cf9  test.wav
ef1ec2c71350ddec9b7a4d4143075020270651a2ffd1a605031ba7db43929cf9  test.wv.wav
a81b51460336e39fd9e1055075e92a7d394da82be989232aa5b2b0ea3a670dfe  test2.flac.wav
13cf3f16d09e7e120a3cd1d3dec500c8283c4cae1dd4278defc4505ba1801463  test2.wav
13cf3f16d09e7e120a3cd1d3dec500c8283c4cae1dd4278defc4505ba1801463  test2.wv.wav
```

You can see the checksums are identical for `test.wav`.
However, only the checksum of `test2.wv.wav` matches `test2.wav`;
the file that passed through FLAC doesn&#39;t match.

Let&#39;s confirm that the files are in the same format.

```plaintext
$ file test2.wav
test2.wav: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 22050 Hz
$ file test2.wv.wav
test2.wv.wav: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 22050 Hz
```

An [xxd(1)](https://linux.die.net/man/1/xxd) hexadecimal dump shows the difference between `test2.wav` and `test2.flac.wav`.

```plaintext
$ xxd test2.wav | head -n 880
00000000: 5249 4646 a4b6 0600 5741 5645 666d 7420  RIFF....WAVEfmt
00000010: 1400 0000 0100 0200 2256 0000 8858 0100  ........&#34;V...X..
00000020: 0400 1000 0000 0000 6461 7461 7cb6 0600  ........data|...
00000030: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000040: 0000 0000 0000 0000 0000 0000 0000 0000  ................
[...]
00003670: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00003680: 0000 0000 0000 0000 0300 0000 feff 0000  ................
00003690: f7ff 0000 ffff 0000 0c00 0000 0800 0000  ................
000036a0: f8ff 0000 f5ff 0000 0100 0000 0800 0000  ................
000036b0: 0400 0000 0200 0000 ffff 0000 f2ff ffff  ................
000036c0: f3ff 0000 1400 0100 2500 0100 f5ff ffff  ........%.......
000036d0: c1ff ffff f0ff 0000 4e00 0200 3c00 0000  ........N...&lt;...
000036e0: b7ff feff 93ff ffff 2700 0200 9500 0200  ........&#39;.......
000036f0: 1300 ffff 5eff fdff a4ff 0000 8c00 0300  ....^...........
$ xxd test2.flac.wav | head -n 880
00000000: 5249 4646 a0b6 0600 5741 5645 666d 7420  RIFF....WAVEfmt
00000010: 1000 0000 0100 0200 2256 0000 8858 0100  ........&#34;V...X..
00000020: 0400 1000 6461 7461 7cb6 0600 0000 0000  ....data|.......
00000030: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000040: 0000 0000 0000 0000 0000 0000 0000 0000  ................
[...]
00003670: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00003680: 0000 0000 0300 0000 feff 0000 f7ff 0000  ................
00003690: ffff 0000 0c00 0000 0800 0000 f8ff 0000  ................
000036a0: f5ff 0000 0100 0000 0800 0000 0400 0000  ................
000036b0: 0200 0000 ffff 0000 f2ff ffff f3ff 0000  ................
000036c0: 1400 0100 2500 0100 f5ff ffff c1ff ffff  ....%...........
000036d0: f0ff 0000 4e00 0200 3c00 0000 b7ff feff  ....N...&lt;.......
000036e0: 93ff ffff 2700 0200 9500 0200 1300 ffff  ....&#39;...........
000036f0: 5eff fdff a4ff 0000 8c00 0300 a000 0100  ^...............
```

The data is offset due to differences in the file header.

## Possible questions {#questions}

### Do you need to be able to recover the WAV? {#do-you-need-it .unlisted}

In most cases, you don&#39;t.

### Why not use gzip or Zstandard? {#gzip .unlisted}

You _could_ use gzip or Zstandard to save yourself work.
However, lossless audio codecs compress audio better than generic compressors.
Importantly, more audio players can play WavPack files than `.wav.gz` or `.wav.zst`.

```plaintext
$ gzip -6 --keep test.wav
$ zstd -7q test.wav
$ du -h test.wav test.wav.gz test.wav.zst test.wv
2.1M	test.wav
1.5M	test.wav.gz
1.4M	test.wav.zst
524K	test.wv
```

### Can&#39;t I just use WAV files that FLAC preserves bit-for-bit? {#choose-wav .unlisted}

You can when you are creating the WAV files.

### Does passing `--keep-foreign-metadata` to flac(1) make a difference? {#keep-foreign-metadata .unlisted}

No.

```plaintext
$ flac -8f --silent test2.wav &amp;&amp; flac -df -o test2.flac.wav --silent test2.flac
$ b3sum test2.flac.wav
a81b51460336e39fd9e1055075e92a7d394da82be989232aa5b2b0ea3a670dfe  test2.flac.wav
$ flac -8f --keep-foreign-metadata --silent test2.wav &amp;&amp; flac -df -o test2.flac.wav --keep-foreign-metadata --silent test2.flac
NOTE: --keep-foreign-metadata is a new feature; make sure to test the output file before deleting the original.
NOTE: --keep-foreign-metadata is a new feature; make sure to test the output file before deleting the original.
$ b3sum test2.flac.wav
a81b51460336e39fd9e1055075e92a7d394da82be989232aa5b2b0ea3a670dfe  test2.flac.wav
```

### Do you think one should use WavPack everywhere? {#wavpack-everywhere .unlisted}

No, FLAC is a good default and entrenched.
(I like FLAC!)

## Page metadata

URL: <https://dbohdan.com/wavpack.md>

Published 2024-11-20, updated 2025-10-20.

Tags:

- archival
- audio
- compression
- data
- file format
