apen

package
v0.0.0-...-192e0e1 Latest Latest
Warning

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

Go to latest
Published: Aug 21, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package apen reads and writes native Monkey's Audio framing: the descriptor, format header, and mandatory seek table a .ape file opens with, the run of frames behind them, and the APEv2 tag most files carry after the audio.

A frame carries neither its length nor its block count, so unlike every self-framing format here nothing can be recovered by scanning: the seek table is the index, and it is exact. That makes seeking a table lookup and makes a file whose table is unusable undecodable rather than degraded. It is also why the muxer needs a destination it can seek: the table and the totals in front of the audio are only knowable once the audio has gone out.

The package is named apen rather than ape because the registry imports codec/ape alongside it (the flacn precedent). The public container name and error prefix are "ape" either way.

Index

Constants

View Source
const MatchNeed = ape.MatchNeed

MatchNeed is the sniff window Match wants.

Variables

This section is empty.

Functions

func Match

func Match(head []byte) bool

Match reports whether head begins with a Monkey's Audio file. It is the format sniff-table entry.

Types

type Demuxer

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

Demuxer reads one Monkey's Audio track from a native .ape source.

func NewDemuxer

func NewDemuxer(src container.Source, opts *DemuxerOptions) (*Demuxer, error)

NewDemuxer parses the header of a native Monkey's Audio source and positions on the first frame. The returned Demuxer implements container.Seeker, container.Warner, and container.Tagger.

func (*Demuxer) ReadPacket

func (d *Demuxer) ReadPacket(pkt *container.Packet) error

ReadPacket yields one frame, with the block count and alignment the decoder needs in front of it. Packet data is reused across calls.

func (*Demuxer) SeekSample

func (d *Demuxer) SeekSample(track int, sample int64) (int64, error)

SeekSample repositions to the frame containing the target sample and returns that frame's first sample; format.Media pre-rolls the remainder. The seek table makes this exact arithmetic rather than a search, at the cost of a frame's worth of pre-roll, which the deep levels make long.

func (*Demuxer) Tags

func (d *Demuxer) Tags() map[string][]string

Tags returns the APEv2 tag's fields under canonical uppercase keys.

func (*Demuxer) Tracks

func (d *Demuxer) Tracks() []container.Track

Tracks returns the single APE track.

func (*Demuxer) Warnings

func (d *Demuxer) Warnings() []container.Warning

Warnings returns damage tolerated during parsing.

type DemuxerOptions

type DemuxerOptions struct {
	// Strict turns tolerated damage (the Warnings list) into errors.
	Strict bool
}

DemuxerOptions configures parsing.

type Muxer

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

Muxer writes one Monkey's Audio track as a native .ape stream.

NeedsSeek reports true: the file opens with a descriptor whose fields (the frame count, the final frame's length, the file's MD5) are only known once the audio has gone out, and with a seek table that is the format's only index -- a frame states neither its length nor its position, so a .ape without a filled table is not a degraded stream but an unreadable one. There is no streaming form to fall back to.

func NewMuxer

func NewMuxer(w io.Writer, opts *MuxerOptions) *Muxer

NewMuxer returns a Monkey's Audio muxer writing to w. Begin fails unless w can actually seek; callers should check NeedsSeek and provide a file.

func (*Muxer) Begin

func (m *Muxer) Begin(tracks []container.Track) error

Begin validates the track and writes the descriptor, the format header, and the seek table's reservation.

func (*Muxer) End

func (m *Muxer) End(trailer codec.Trailer) error

End writes the trailing word, the tag block, and the totals: the seek table, the format header's frame counts, and the descriptor's byte counts and MD5.

func (*Muxer) NeedsSeek

func (m *Muxer) NeedsSeek() bool

NeedsSeek reports true: Monkey's Audio cannot be written to a plain stream.

func (*Muxer) WritePacket

func (m *Muxer) WritePacket(pkt container.Packet) error

WritePacket appends one frame and indexes it.

type MuxerOptions

type MuxerOptions struct {
	// Tags are written as an APEv2 block after the audio, which is where a
	// .ape file conventionally carries them and where the demuxer reads them.
	Tags []container.Tag
}

MuxerOptions configures writing.

Jump to

Keyboard shortcuts

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