mpseek

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Nov 20, 2020 License: GPL-3.0 Imports: 3 Imported by: 3

README

https://pkg.go.dev/github.com/korandiz/mpseek

Documentation

Overview

Package mpseek provides seek tables for MPEG-1 Audio files.

Seeking in an mp3 is tricky. The stream consists of so-called frames, which all code the same number of samples (and the same length of sound), but their size in bytes can vary, even when the bitrate is nominally constant. This means you can't use some simple formula to map seconds to byte offsets. Moreover, frames carry no timestamps, so you can't use bisection search either.

The only viable solution is to parse the stream and precompute a list of (timestamp, offset) pairs. Such a list is called a seek table. There is an obvious tradeoff here: The more seek points you add, the more accurate your seeks will be, but a larger table will take up more memory.

To make life more complicated, the decoder needs to be "warmed up" before it can provide correct output, so decoding must start a few frames before the seek point. The samples resulting from these warm-up frames must be thrown away, and any decoding errors must be ignored. Once the warm-up is done, the decoder should be able operate as normal.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Result

type Result struct {
	Sample int64
	Time   float64
	Offset int64
	WarmUp int
}

A Result is the result of a look-up operation. Sample and Time are the sample index and the timestamp of the seek point, respectively. Offset is the byte offset to seek to, while WarmUp is the number of frames that need to be decoded after the seek to actually get to the seek point.

type Table

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

A Table translates times and sample indexes to byte offsets.

func CreateTable

func CreateTable(input io.Reader, g float64) (*Table, error)

CreateTable reads the input stream through and creates a seek table for it. The granularity (time between seek points) will be an integral number of frames, and it will be as close to g seconds as possible. If g == 0, a seek point will be created for every frame.

The memory footprint of a seek point is on the order of a few bytes.

When a non-nil *Table is returned, it always contains information about the part of the stream which could successfully be read and parsed, even if an error occured. EOF is not considered as an error.

As it requires reading the entire stream through, constructing the table may take non-trivial time.

func (*Table) FindSample

func (t *Table) FindSample(n int64) Result

FindSample looks up the latest seek point with a sample index no greater than n. Panics if n < 0.

func (*Table) FindTime

func (t *Table) FindTime(s float64) Result

FindTime looks up the latest seek point with a timestamp no greater than s seconds. Panics if s < 0.

func (*Table) Length

func (t *Table) Length() float64

Length returns the length of the stream in seconds.

func (*Table) NFrames

func (t *Table) NFrames() int

NFrames returns the length of the stream in frames.

func (*Table) NSamples

func (t *Table) NSamples() int64

NSamples returns the length of the stream in samples.

func (*Table) SamplesPerFrame

func (t *Table) SamplesPerFrame() int

SamplesPerFrame returns the number of samples per frame.

func (*Table) SamplingFrequency

func (t *Table) SamplingFrequency() int

SamplingFrequency returns the sampling frequency in Hz.

Jump to

Keyboard shortcuts

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