Skip to content

Add AIFF / AIFF-C support (read + write)#409

Open
mmamedel wants to merge 3 commits into
Vanilagy:mainfrom
mmamedel:feat/aiff-input-format
Open

Add AIFF / AIFF-C support (read + write)#409
mmamedel wants to merge 3 commits into
Vanilagy:mainfrom
mmamedel:feat/aiff-input-format

Conversation

@mmamedel

@mmamedel mmamedel commented Jun 13, 2026

Copy link
Copy Markdown

Summary

Adds bidirectional support for the AIFF and AIFF-C (AIFC) container formats — reading via AiffInputFormat / AiffDemuxer and writing via AiffOutputFormat / AiffMuxer — mirroring the existing WAVE support.

AIFF is the big-endian, IFF-based sibling of WAVE and typically wraps uncompressed signed PCM, so no new codec is required. It maps directly onto the PCM codecs Mediabunny already encodes/decodes.

Reading

AIFF / AIFC compression codec
NONE / twos (uncompressed BE PCM) pcm-s8 / pcm-s16be / pcm-s24be / pcm-s32be
sowt (byte-swapped) pcm-s16 / pcm-s24 / pcm-s32
raw pcm-u8
fl32 / fl64 pcm-f32be / pcm-f64be
ulaw / alaw ulaw / alaw
  • The COMM chunk's 80-bit IEEE 754 extended-precision sample rate is decoded.
  • Metadata is parsed from the native NAME / AUTH / ANNO / (c) text chunks and from embedded ID3 chunks.
  • Compressed AIFC payloads that Mediabunny doesn't decode resolve to a null codec (so canDecode() is false) rather than throwing.
  • The demuxer follows the same streaming / unknown-file-size handling as WaveDemuxer.

Writing

AiffOutputFormat supports pcm-s8, pcm-s16be, pcm-s24be, pcm-s32be (written as plain AIFF) and pcm-f32be, pcm-f64be, ulaw, alaw (written as AIFF-C with the matching compression type + FVER chunk). The COMM sample rate is encoded as an 80-bit extended float (exact for integer rates).

Metadata is written via the metadataFormat option, mirroring the WAVE muxer:

  • 'text' (default): native AIFF text chunks (NAME/AUTH/ANNO) — title, artist, comment.
  • 'id3': an ID3 chunk for the full, rich tag set (album, genre, track number, images, …).

Changes

  • src/aiff/aiff-demuxer.tsAiffDemuxer + audio track backing + metadata parsing
  • src/aiff/aiff-muxer.tsAiffMuxer + metadata writing
  • src/aiff/aiff-writer.ts — big-endian IFF writer (the AIFF counterpart to RiffWriter)
  • src/input-format.tsAiffInputFormat class, AIFF singleton, added to ALL_FORMATS
  • src/output-format.tsAiffOutputFormat class + AiffOutputFormatOptions
  • src/index.ts — exports
  • test/node/aiff.test.ts — read tests (16-bit, 8-bit, AIFC fl32, AIFC sowt), sample-accurate write→read round-trips (pcm-s16be/-s24be/-s8/-f32be), and metadata round-trips (text + ID3)
  • docs/guide/*, README.md — AIFF documented as bidirectional, with an AIFF output-formats section

Notes

  • Output is audio-only (one audio track), like WAVE.
  • I used lowercase ulaw/alaw for the AIFF-C compression type on write; the demuxer accepts both cases.

Testing

eslint, tsc --noEmit, npm run build, docblock check, and the aiff suite (11 tests) all pass locally.

mmamedel added 2 commits June 13, 2026 08:09
Adds read support for the AIFF and AIFF-C (AIFC) container formats via a
new AiffInputFormat and AiffDemuxer, mirroring the existing WAVE support.

AIFF is the big-endian, IFF-based sibling of WAVE and typically wraps
uncompressed signed PCM, so no new codec is needed — it maps onto the PCM
codecs Mediabunny already decodes:

- AIFF / AIFC 'NONE' / 'twos' → pcm-s8 / pcm-s16be / pcm-s24be / pcm-s32be
- AIFC 'sowt'                 → pcm-s16 / pcm-s24 / pcm-s32 (little-endian)
- AIFC 'raw '                 → pcm-u8
- AIFC 'fl32' / 'fl64'        → pcm-f32be / pcm-f64be
- AIFC 'ulaw' / 'alaw'        → ulaw / alaw

The COMM chunk's 80-bit IEEE 754 extended-precision sample rate is decoded.
Compressed AIFC payloads we don't decode resolve to a null codec (canDecode
is false) rather than throwing.

Exports the AIFF singleton and adds it to ALL_FORMATS. Adds read-aiff tests
covering 16-bit, 8-bit, AIFC float, and AIFC byte-swapped fixtures, and
updates the format docs (read-only).
Adds AiffOutputFormat + AiffMuxer (and a big-endian AiffWriter), mirroring
the WAVE output path. Uncompressed signed PCM is written as plain AIFF;
floating-point and µ-law/A-law are written as AIFF-C with the matching
compression type and an FVER chunk.

Supported output codecs: pcm-s8, pcm-s16be, pcm-s24be, pcm-s32be (AIFF) and
pcm-f32be, pcm-f64be, ulaw, alaw (AIFF-C). The COMM sample rate is encoded
as an 80-bit IEEE 754 extended float (exact for integer rates).

Exports AiffOutputFormat + AiffOutputFormatOptions. Renames the test file to
aiff.test.ts and adds sample-accurate write→read round-trip tests for
pcm-s16be/-s24be/-s8/-f32be. Updates the format docs to bidirectional and
adds an AIFF output-formats section.
@mmamedel mmamedel changed the title Add AIFF / AIFF-C input format Add AIFF / AIFF-C support (read + write) Jun 13, 2026
Writes metadata tags into either native AIFF text chunks (NAME/AUTH/ANNO,
the default) or an ID3 chunk for a richer tag set, selected via the new
`metadataFormat` option on AiffOutputFormat — mirroring the WAVE muxer.

The demuxer now parses NAME/AUTH/ANNO/(c) text chunks and embedded ID3
chunks back into MetadataTags. Adds round-trip tests for both metadata
formats and documents the option.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant