Skip to content

Instantly share code, notes, and snippets.

@MCJack123
Last active January 30, 2024 18:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MCJack123/90c24b64c8e626c7f130b57e9800962c to your computer and use it in GitHub Desktop.
Save MCJack123/90c24b64c8e626c7f130b57e9800962c to your computer and use it in GitHub Desktop.
Specification for DFPWM stored in WAV files

WAV format for DFPWM data

This document describes how to store DFPWM data in a WAV file.

Overview

DFPWM data is specified through the WAVE_FORMAT_EXTENDED data type, with the UUID 3ac1fa38-811d-4361-a40d-ce53ca607cd1. Channels are stored interleaved, and samples are packed in groups of 8 per byte, as is consistent with raw DFPWM data. Only DFPWM1a data is considered here - original DFPWM should not be stored using this UUID.

fmt  chunk

The fmt  chunk follows the standard layout for WAVE_FORMAT_EXTENDED, using the assigned DFPWM UUID:

Offset Bytes Description
0x00 2 Format code (0xFFFE)
0x02 2 Number of channels
0x04 4 Sample rate
0x08 4 Byte rate (sample rate * channels / 8)
0x0C 2 Block align (ceil(channels / 8))
0x0E 2 Bits per sample (1)
0x10 2 Extra data size (0x16)
0x12 2 Valid bits per sample (1)
0x14 4 Channel configuraion
0x18 16 DFPWM UUID (3ac1fa38811d4361a40dce53ca607cd1)

fact chunk

The fact chunk is required when using a non-PCM format. This is simply a 32-bit integer specifying the total number of samples in a single channel. This should be equal to (data length * 8 / channels).

data chunk

The data chunk stores the raw DFPWM data. For single channel audio, this is equivalent to existing raw DFPWM files. For multichannel audio, all samples are interleaved in the PCM input to the encoder. This may be implemented by first encoding the native audio representation to interleaved signed (or unsigned, depending on the codec's capabilities) 8-bit PCM, as would be stored in a PCM WAV file, then passed directly to the DFPWM encoder.

All data uses a single encoder instance with q and s set to 0, and lt set to -128. The instance parameters are used throughout the entire data block, and are never reset while encoding or decoding. The samples are decoded sequentially, with the least significant bit first. Since the data is interleaved before encoding, all channels share the same encoder and parameters, switching between channels for each frame. For example, if a byte 0b11001010 is stored in a 2-channel DFPWM file, the first bit (0) is decoded to the left channel, then the second bit (1) is decoded to the right channel, then the third bit (0) is decoded to the left channel, and so on.

Compliant muxers/demuxers

The following muxers are known to support DFPWM data in WAV files:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment