faad2

package module
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 22, 2026 License: GPL-2.0 Imports: 8 Imported by: 0

README

go-faad2

Pure Go AAC audio decoder using FAAD2 compiled to WebAssembly.

Features

  • Pure Go - No CGO dependencies, cross-compiles easily
  • ADTS support - Decode raw AAC streams (ADTS format)
  • Low-level API - Decode raw AAC frames directly

Installation

go get github.com/llehouerou/go-faad2

Usage

Decode ADTS stream (raw AAC)
ctx := context.Background()

file, _ := os.Open("audio.aac")
reader, _ := faad2.OpenADTS(ctx, file)
defer reader.Close(ctx)

pcm := make([]int16, 4096)
for {
    n, err := reader.Read(ctx, pcm)
    if err == io.EOF {
        break
    }
    // Process pcm[:n]
}
Decode raw AAC frames (low-level)
ctx := context.Background()

decoder, _ := faad2.NewDecoder(ctx)
defer decoder.Close(ctx)

// Initialize with AAC codec config (AudioSpecificConfig)
decoder.Init(ctx, codecConfig)

// Decode frames
pcm, _ := decoder.Decode(ctx, aacFrame)

Building the WASM binary

The WASM binary is pre-built and embedded in the library. To rebuild it:

# Requires Emscripten (available in nix devShell)
make wasm

Development

# Enter development shell (requires Nix with flakes)
nix develop

# Run checks (format, lint, test)
make check

# Install git hooks
make install-hooks

License

GPL-2.0-or-later (required by FAAD2)

Credits

Documentation

Overview

Package faad2 provides AAC audio decoding using the FAAD2 library compiled to WebAssembly.

The package supports decoding AAC audio from:

  • M4A/MP4 container files via [OpenM4A]
  • Raw ADTS streams via OpenADTS
  • Direct frame decoding via Decoder

Basic usage with M4A files:

reader, err := faad2.OpenM4A(ctx, file)
if err != nil {
    log.Fatal(err)
}
defer reader.Close(ctx)

pcm := make([]int16, 4096)
for {
    n, err := reader.Read(ctx, pcm)
    if err != nil {
        break
    }
    // Process pcm[:n] samples...
}

The package uses a global WASM runtime that is lazily initialized on first use. Call Shutdown to release WASM resources when done.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrInvalidADTS is returned when the ADTS stream is invalid.
	ErrInvalidADTS = errors.New("faad2: invalid ADTS stream")

	// ErrADTSSyncNotFound is returned when no ADTS sync word is found.
	ErrADTSSyncNotFound = errors.New("faad2: ADTS sync word not found")
)
View Source
var (
	// ErrInvalidConfig is returned when the AAC codec configuration is invalid.
	ErrInvalidConfig = errors.New("faad2: invalid codec configuration")

	// ErrDecodeFailed is returned when AAC frame decoding fails.
	ErrDecodeFailed = errors.New("faad2: decode failed")

	// ErrOutOfMemory is returned when WASM memory allocation fails.
	ErrOutOfMemory = errors.New("faad2: out of memory")

	// ErrNotInitialized is returned when trying to decode without initialization.
	ErrNotInitialized = errors.New("faad2: decoder not initialized")

	// ErrDecoderClosed is returned when trying to use a closed decoder.
	ErrDecoderClosed = errors.New("faad2: decoder is closed")

	// ErrEmptyFrame is returned when trying to decode an empty AAC frame.
	ErrEmptyFrame = errors.New("faad2: empty AAC frame")
)

Functions

func ParseADTSHeader

func ParseADTSHeader(data []byte) (sampleRate uint32, channels uint8, frameLength uint16, err error)

ParseADTSHeader parses an ADTS header from raw bytes without creating a reader.

This is useful for inspecting ADTS streams or extracting metadata. The data slice must contain at least 7 bytes (the minimum ADTS header size).

Returns the sample rate in Hz, channel count, and frame length in bytes (including the header). Returns ErrADTSSyncNotFound if the sync word is not found, or ErrInvalidADTS if the header is too short or malformed.

func Shutdown added in v0.2.0

func Shutdown(ctx context.Context) error

Shutdown releases the global WASM runtime and all associated resources.

After calling Shutdown:

  • All existing Decoder, [M4AReader], and ADTSReader instances become invalid
  • Calling methods on closed instances will return errors or panic
  • New instances can be created, which will lazily reinitialize the runtime

Shutdown is optional but recommended when the application no longer needs AAC decoding, as it frees significant memory used by the WASM runtime.

Types

type ADTSReader

type ADTSReader struct {
	// contains filtered or unexported fields
}

ADTSReader reads and decodes audio from ADTS (Audio Data Transport Stream) format.

ADTS is a streaming format for AAC audio, commonly used for raw AAC files (.aac) and streaming applications. Unlike M4A, ADTS does not support seeking.

Create an ADTSReader using OpenADTS and release resources with ADTSReader.Close.

func OpenADTS

func OpenADTS(ctx context.Context, r io.Reader) (*ADTSReader, error)

OpenADTS opens an ADTS stream for audio decoding.

The reader should provide raw ADTS data starting with a valid ADTS sync word (0xFFF). The function reads and decodes the first frame to initialize the decoder.

Returns ErrADTSSyncNotFound if no valid ADTS header is found, or ErrInvalidADTS if the header is malformed.

func (*ADTSReader) Channels

func (ar *ADTSReader) Channels() uint8

Channels returns the number of audio channels (1 for mono, 2 for stereo).

func (*ADTSReader) Close

func (ar *ADTSReader) Close(ctx context.Context) error

Close releases all resources associated with the reader.

After Close is called, the reader cannot be reused. It is safe to call Close multiple times; subsequent calls are no-ops.

Note: Close does not close the underlying io.Reader passed to OpenADTS.

func (*ADTSReader) FramesRead

func (ar *ADTSReader) FramesRead() int64

FramesRead returns the number of AAC frames decoded so far.

This can be used to estimate playback position when the frame duration is known (typically 1024 samples per frame for AAC-LC).

func (*ADTSReader) Read

func (ar *ADTSReader) Read(ctx context.Context, pcm []int16) (int, error)

Read reads decoded PCM samples into the provided buffer.

Returns the number of samples read into pcm. For stereo audio, each sample pair (L, R) counts as 2 samples. Returns io.EOF when the stream ends.

The buffer can be any size; the reader handles internal buffering.

func (*ADTSReader) SampleRate

func (ar *ADTSReader) SampleRate() uint32

SampleRate returns the audio sample rate in Hz (e.g., 44100, 48000).

type Decoder

type Decoder struct {
	// contains filtered or unexported fields
}

Decoder is a low-level AAC decoder that decodes individual AAC frames.

For most use cases, prefer [OpenM4A] or OpenADTS which handle container parsing and provide a simpler streaming interface.

A Decoder must be initialized with Decoder.Init before calling Decoder.Decode. The decoder is safe for concurrent use after initialization.

func NewDecoder

func NewDecoder(ctx context.Context) (*Decoder, error)

NewDecoder creates a new AAC decoder instance.

The decoder must be initialized with Decoder.Init before use. Call Decoder.Close when done to release resources.

func (*Decoder) Channels

func (d *Decoder) Channels() uint8

Channels returns the number of audio channels (1 for mono, 2 for stereo).

Returns 0 if the decoder has not been initialized.

func (*Decoder) Close

func (d *Decoder) Close(ctx context.Context) error

Close releases decoder resources.

After Close is called, the decoder cannot be reused. It is safe to call Close multiple times; subsequent calls are no-ops.

func (*Decoder) Decode

func (d *Decoder) Decode(ctx context.Context, aacFrame []byte) ([]int16, error)

Decode decodes a single AAC frame and returns interleaved PCM samples.

The returned slice contains 16-bit signed PCM samples. For stereo audio, samples are interleaved (L, R, L, R, ...). The number of samples per frame is typically 1024 or 2048 per channel, depending on the AAC profile.

Returns ErrNotInitialized if Decoder.Init has not been called, ErrEmptyFrame if aacFrame is empty, or ErrDecodeFailed on decode error.

func (*Decoder) Init

func (d *Decoder) Init(ctx context.Context, config []byte) error

Init initializes the decoder with an AudioSpecificConfig.

The config parameter is the AAC AudioSpecificConfig, typically extracted from:

  • The esds box in M4A/MP4 files
  • ADTS frame headers (converted via internal helper)

Init must be called exactly once before Decoder.Decode. Returns ErrInvalidConfig if the configuration is nil, empty, or invalid.

func (*Decoder) SampleRate

func (d *Decoder) SampleRate() uint32

SampleRate returns the audio sample rate in Hz (e.g., 44100, 48000).

Returns 0 if the decoder has not been initialized.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL