# @audio/decode-tta

> Decode TTA (True Audio) lossless audio to PCM samples

Latest version **1.0.0** (published 2026-08-29) · MIT license · 0 weekly downloads

## Install

```sh
npm install @audio/decode-tta
pnpm add @audio/decode-tta
yarn add @audio/decode-tta
bun add @audio/decode-tta
```

## Health

**Score 70/100 (B)** — status: active.

Positive: has types; esm support; no vulnerabilities; recently updated; high maintenance score; high quality score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 1.0.0 |
| Published | 2026-08-29 |
| First published | 2026-08-29 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Node | >=18 |
| Dependencies | 0 |
| Unpacked size | 21 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 208 |
| Author | Dmitry Iv. |
| Maintainers | jamen, dfcreative, dy |
| Keywords | tta, true-audio, lossless, audio, decode, decoder, pcm, rice-coding |

## Links

- npm: https://www.npmjs.com/package/@audio/decode-tta
- Repository: https://github.com/audiojs/decode
- Homepage: https://github.com/audiojs/decode/tree/main/packages/decode-tta
- Issues: https://github.com/audiojs/decode/issues
- Funding: https://github.com/sponsors/audiojs
- npm.io page: https://npm.io/package/@audio/decode-tta

## Alternatives

- [flatbuffers](https://npm.io/package/flatbuffers.md) — 6.0M weekly downloads
- [jwt-simple](https://npm.io/package/jwt-simple.md) — 259.5K weekly downloads
- [@exodus/patch-broken-hermes-typed-arrays](https://npm.io/package/@exodus/patch-broken-hermes-typed-arrays.md) — 28.5K weekly downloads
- [@native-to-anchor/buffer-layout](https://npm.io/package/@native-to-anchor/buffer-layout.md) — 12.2K weekly downloads
- [binary-parser-encoder](https://npm.io/package/binary-parser-encoder.md) — 5.3K weekly downloads

## Recent versions

- 1.0.0 (latest) — 2026-08-29

## README

# @audio/decode-tta [![npm](https://img.shields.io/npm/v/@audio/decode-tta)](https://www.npmjs.com/package/@audio/decode-tta) [![MIT](https://img.shields.io/badge/MIT-%E0%A5%90-white)](https://github.com/krishnized/license)

Decode TTA (True Audio) lossless audio to PCM samples, in pure JavaScript

```
npm install @audio/decode-tta
```

```js
import decode, { decoder } from '@audio/decode-tta'
```

TTA1 is Alexander Djourik's lossless codec: per channel, an adaptive two-state Rice coder feeds an 8-tap sign-sign-LMS "hybrid" filter and a fixed first-order predictor; multichannel streams decorrelate the last channel against the rest with a cascading half-sum/difference. Written from the [TTA project](https://sourceforge.net/projects/tta/) and the BSD-licensed reference decoder — Djourik & Zhilin, True Audio Software (2004): `ttadec.c` / `filter.h` / `ttadec.h` / `ttalib.h`, via [Rockbox's libtta port](https://github.com/Rockbox/rockbox/tree/master/lib/rbcodec/codecs/libtta) which retains the original license — see [LICENSE.ttadec](./LICENSE.ttadec). Decodes exactly what `ffmpeg -c:a tta` writes: 8/16/24-bit PCM, mono through 16 channels.

```js
let { channelData, sampleRate } = decode(ttaBytes)

let dec = decoder()
let head = dec.decode(chunk1)   // synchronous; header/seek-table/frame boundaries carry over
let tail = dec.flush()
dec.free()
```

## API

### `decode(src: Uint8Array | ArrayBuffer): AudioData`

Decode a complete stream.

### `decoder(): TTADecoder`

Synchronous streaming decoder. `decode(chunk)` returns the samples of every complete frame in the data so far — frame byte lengths are known from the seek table, so a chunk boundary anywhere (even mid-header) just carries over to the next call. `flush()` drops a trailing incomplete header/seek-table/frame. `free()` releases state and is idempotent. `errors` counts frames dropped for a CRC32 mismatch.

### `AudioData`

```ts
{ channelData: Float32Array[], sampleRate: number }
```

## CRC32

TTA1 checksums the header, the seek table, and every frame independently. A header or seek-table mismatch throws — those describe the stream's shape and can't be decoded around. A frame mismatch is not fatal: since each frame resets its filter/predictor/Rice state from scratch, one bad frame can't corrupt its neighbors, so that frame's samples are dropped, `errors` increments, and decoding continues.

## Notes

- Only format 1 (plain PCM) is decoded; format 2 (password-encrypted TTA) throws.
- Channel order is kept exactly as encoded — TTA does not reorder channels the way AC-3/DTS do, so `channelData[i]` is stream channel `i`.
- A leading ID3v2 tag (some encoders other than ffmpeg prepend one) is detected and skipped before the `TTA1` signature; a trailing APEv2 tag is ignored.
- A truncated file loses its final incomplete frame silently, matching `flush()`'s "drop the partial" behavior in the other atoms in this umbrella.
- 60 s of 44.1 kHz stereo decodes in ~225 ms on a current laptop (~265× real-time).

**Use when:** opening `.tta` files, or decoding a TTA track pulled out of a container.

---

Part of [@audio/decode](https://github.com/audiojs/decode) — the decode family umbrella.

MIT © [audiojs](https://github.com/audiojs), algorithm ported from the BSD-licensed TTA reference decoder — see [LICENSE.ttadec](./LICENSE.ttadec)

---
_Source: https://npm.io/package/@audio/decode-tta · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
