frame

package
v1.0.10 Latest Latest
Warning

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

Go to latest
Published: Nov 11, 2023 License: Unlicense Imports: 11 Imported by: 6

Documentation

Overview

Package frame implements access to FLAC audio frames.

A brief introduction of the FLAC audio format [1] follows. FLAC encoders divide the audio stream into blocks through a process called blocking [2]. A block contains the unencoded audio samples from all channels during a short period of time. Each audio block is divided into subblocks, one per channel.

There is often a correlation between the left and right channel of stereo audio. Using inter-channel decorrelation [3] it is possible to store only one of the channels and the difference between the channels, or store the average of the channels and their difference. An encoder decorrelates audio samples as follows:

mid = (left + right)/2 // average of the channels
side = left - right    // difference between the channels

The blocks are encoded using a variety of prediction methods [4][5] and stored in frames. Blocks and subblocks contains unencoded audio samples while frames and subframes contain encoded audio samples. A FLAC stream contains one or more audio frames.

[1]: https://www.xiph.org/flac/format.html#architecture
[2]: https://www.xiph.org/flac/format.html#blocking
[3]: https://www.xiph.org/flac/format.html#interchannel
[4]: https://www.xiph.org/flac/format.html#prediction
[5]: https://godoc.org/github.com/mewkiz/flac/frame#Pred

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrInvalidSync = errors.New("frame.Frame.parseHeader: invalid sync-code")
)

Errors returned by Frame.parseHeader.

View Source
var FixedCoeffs = [...][]int32{

	1: {1},
	2: {2, -1},
	3: {3, -3, 1},

	4: {4, -6, 4, -1},
}

FixedCoeffs maps from prediction order to the LPC coefficients used in fixed encoding.

x_0[n] = 0
x_1[n] = x[n-1]
x_2[n] = 2*x[n-1] - x[n-2]
x_3[n] = 3*x[n-1] - 3*x[n-2] + x[n-3]
x_4[n] = 4*x[n-1] - 6*x[n-2] + 4*x[n-3] - x[n-4]

Functions

This section is empty.

Types

type Channels

type Channels uint8

Channels specifies the number of channels (subframes) that exist in a frame, their order and possible inter-channel decorrelation.

const (
	ChannelsMono           Channels = iota // 1 channel: mono.
	ChannelsLR                             // 2 channels: left, right.
	ChannelsLRC                            // 3 channels: left, right, center.
	ChannelsLRLsRs                         // 4 channels: left, right, left surround, right surround.
	ChannelsLRCLsRs                        // 5 channels: left, right, center, left surround, right surround.
	ChannelsLRCLfeLsRs                     // 6 channels: left, right, center, LFE, left surround, right surround.
	ChannelsLRCLfeCsSlSr                   // 7 channels: left, right, center, LFE, center surround, side left, side right.
	ChannelsLRCLfeLsRsSlSr                 // 8 channels: left, right, center, LFE, left surround, right surround, side left, side right.
	ChannelsLeftSide                       // 2 channels: left, side; using inter-channel decorrelation.
	ChannelsSideRight                      // 2 channels: side, right; using inter-channel decorrelation.
	ChannelsMidSide                        // 2 channels: mid, side; using inter-channel decorrelation.
)

Channel assignments. The following abbreviations are used:

C:   center (directly in front)
R:   right (standard stereo)
Sr:  side right (directly to the right)
Rs:  right surround (back right)
Cs:  center surround (rear center)
Ls:  left surround (back left)
Sl:  side left (directly to the left)
L:   left (standard stereo)
Lfe: low-frequency effect (placed according to room acoustics)

The first 6 channel constants follow the SMPTE/ITU-R channel order:

L R C Lfe Ls Rs

func (Channels) Count

func (channels Channels) Count() int

Count returns the number of channels (subframes) used by the provided channel assignment.

type Frame

type Frame struct {
	// Audio frame header.
	Header
	// One subframe per channel, containing encoded audio samples.
	Subframes []*Subframe
	// contains filtered or unexported fields
}

A Frame contains the header and subframes of an audio frame. It holds the encoded samples from a block (a part) of the audio stream. Each subframe holding the samples from one of its channel.

ref: https://www.xiph.org/flac/format.html#frame

func New

func New(r io.Reader) (frame *Frame, err error)

New creates a new Frame for accessing the audio samples of r. It reads and parses an audio frame header. It returns io.EOF to signal a graceful end of FLAC stream.

Call Frame.Parse to parse the audio samples of its subframes.

func Parse

func Parse(r io.Reader) (frame *Frame, err error)

Parse reads and parses the header, and the audio samples from each subframe of a frame. If the samples are inter-channel decorrelated between the subframes, it correlates them. It returns io.EOF to signal a graceful end of FLAC stream.

ref: https://www.xiph.org/flac/format.html#interchannel

func (*Frame) Correlate added in v1.0.10

func (frame *Frame) Correlate()

Correlate reverts any inter-channel decorrelation between the samples of the subframes.

An encoder decorrelates audio samples as follows:

mid = (left + right)/2
side = left - right

func (*Frame) Decorrelate added in v1.0.10

func (frame *Frame) Decorrelate()

Decorrelate performs inter-channel decorrelation between the samples of the subframes.

An encoder decorrelates audio samples as follows:

mid = (left + right)/2
side = left - right

func (*Frame) Hash

func (frame *Frame) Hash(md5sum hash.Hash)

Hash adds the decoded audio samples of the frame to a running MD5 hash. It can be used in conjunction with StreamInfo.MD5sum to verify the integrity of the decoded audio samples.

Note: The audio samples of the frame must be decoded before calling Hash.

func (*Frame) Parse

func (frame *Frame) Parse() error

Parse reads and parses the audio samples from each subframe of the frame. If the samples are inter-channel decorrelated between the subframes, it correlates them.

ref: https://www.xiph.org/flac/format.html#interchannel

func (*Frame) SampleNumber added in v1.0.7

func (frame *Frame) SampleNumber() uint64

SampleNumber returns the first sample number contained within the frame.

type Header struct {
	// Specifies if the block size is fixed or variable.
	HasFixedBlockSize bool
	// Block size in inter-channel samples, i.e. the number of audio samples in
	// each subframe.
	BlockSize uint16
	// Sample rate in Hz; a 0 value implies unknown, get sample rate from
	// StreamInfo.
	SampleRate uint32
	// Specifies the number of channels (subframes) that exist in the frame,
	// their order and possible inter-channel decorrelation.
	Channels Channels
	// Sample size in bits-per-sample; a 0 value implies unknown, get sample size
	// from StreamInfo.
	BitsPerSample uint8
	// Specifies the frame number if the block size is fixed, and the first
	// sample number in the frame otherwise. When using fixed block size, the
	// first sample number in the frame can be derived by multiplying the frame
	// number with the block size (in samples).
	Num uint64
}

A Header contains the basic properties of an audio frame, such as its sample rate and channel count. To facilitate random access decoding each frame header starts with a sync-code. This allows the decoder to synchronize and locate the start of a frame header.

ref: https://www.xiph.org/flac/format.html#frame_header

type Pred

type Pred uint8

Pred specifies the prediction method used to encode the audio samples of a subframe.

const (
	// PredConstant specifies that the subframe contains a constant sound. The
	// audio samples are encoded using run-length encoding. Since every audio
	// sample has the same constant value, a single unencoded audio sample is
	// stored in practice. It is replicated a number of times, as specified by
	// BlockSize in the frame header.
	PredConstant Pred = iota
	// PredVerbatim specifies that the subframe contains unencoded audio samples.
	// Random sound is often stored verbatim, since no prediction method can
	// compress it sufficiently.
	PredVerbatim
	// PredFixed specifies that the subframe contains linear prediction coded
	// audio samples. The coefficients of the prediction polynomial are selected
	// from a fixed set, and can represent 0th through fourth-order polynomials.
	// The prediction order (0 through 4) is stored within the subframe along
	// with the same number of unencoded warm-up samples, which are used to kick
	// start the prediction polynomial. The remainder of the subframe stores
	// encoded residuals (signal errors) which specify the difference between the
	// predicted and the original audio samples.
	PredFixed
	// PredFIR specifies that the subframe contains linear prediction coded audio
	// samples. The coefficients of the prediction polynomial are stored in the
	// subframe, and can represent 0th through 32nd-order polynomials. The
	// prediction order (0 through 32) is stored within the subframe along with
	// the same number of unencoded warm-up samples, which are used to kick start
	// the prediction polynomial. The remainder of the subframe stores encoded
	// residuals (signal errors) which specify the difference between the
	// predicted and the original audio samples.
	PredFIR
)

Prediction methods.

type ResidualCodingMethod added in v1.0.10

type ResidualCodingMethod uint8

ResidualCodingMethod specifies a residual coding method.

const (
	// Rice coding with a 4-bit Rice parameter (rice1).
	ResidualCodingMethodRice1 ResidualCodingMethod = 0
	// Rice coding with a 5-bit Rice parameter (rice2).
	ResidualCodingMethodRice2 ResidualCodingMethod = 1
)

Residual coding methods.

type RicePartition added in v1.0.10

type RicePartition struct {
	// Rice parameter.
	Param uint
	// Residual sample size in bits-per-sample used by escaped partitions.
	EscapedBitsPerSample uint
}

RicePartition is a partition containing a subset of the residuals of a subframe.

type RiceSubframe added in v1.0.10

type RiceSubframe struct {
	// Partition order used by fixed and FIR linear prediction decoding
	// (for residual coding methods, rice1 and rice2).
	PartOrder int // TODO: remove PartOrder and infer from int(math.Log2(float64(len(Partitions))))?
	// Rice partitions.
	Partitions []RicePartition
}

RiceSubframe holds rice-coding subframe fields used by residual coding methods rice1 and rice2.

type SubHeader

type SubHeader struct {
	// Specifies the prediction method used to encode the audio sample of the
	// subframe.
	Pred Pred
	// Prediction order used by fixed and FIR linear prediction decoding.
	Order int
	// Wasted bits-per-sample.
	Wasted uint
	// Residual coding method used by fixed and FIR linear prediction decoding.
	ResidualCodingMethod ResidualCodingMethod
	// Coefficients' precision in bits used by FIR linear prediction decoding.
	CoeffPrec uint
	// Predictor coefficient shift needed in bits used by FIR linear prediction
	// decoding.
	CoeffShift int32
	// Predictor coefficients used by FIR linear prediction decoding.
	Coeffs []int32
	// Rice-coding subframe fields used by residual coding methods rice1 and
	// rice2; nil if unused.
	RiceSubframe *RiceSubframe
}

A SubHeader specifies the prediction method and order of a subframe.

ref: https://www.xiph.org/flac/format.html#subframe_header

type Subframe

type Subframe struct {
	// Subframe header.
	SubHeader
	// Unencoded audio samples. Samples is initially nil, and gets populated by a
	// call to Frame.Parse.
	//
	// Samples is used by decodeFixed and decodeFIR to temporarily store
	// residuals. Before returning they call decodeLPC which decodes the audio
	// samples.
	Samples []int32
	// Number of audio samples in the subframe.
	NSamples int
}

A Subframe contains the encoded audio samples from one channel of an audio block (a part of the audio stream).

ref: https://www.xiph.org/flac/format.html#subframe

Jump to

Keyboard shortcuts

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