opus

package module
v0.0.0-...-3f1075e Latest Latest
Warning

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

Go to latest
Published: Mar 10, 2024 License: MIT Imports: 11 Imported by: 0

README

opus

PkgGoDev

This Go package provides decoding of streams that have been encoded with the Opus codec. When provided with an opus stream the raw PCM data can be extracted.

The xiph.org opus, opusfile, and ogg C libraries are used to do the decoding.

decoding a stream

readSeeker, err := os.Open("an-opus-file.opus")
if err != nil { ... }

decoder, err := opus.NewDecoder(readSeeker)
if err != nil { ... }

var pcm = make([]int16, 2_000)
for {
    n, err := decoder.Read(pcm)
    fmt.Printf("read %d samples (per channel)\n", n)
    samples := pcm[:n]
    // Do something with the samples...

    if err == io.EOF {
        break
    }
}

decoder.Destroy()
readSeeker.Close()

building

Because of the use of cgo in the library, the Go toolchain will need to be able to find a C compiler (typically gcc or clang) and linker on the path.

When building an application that uses the opus package (with go build or go run) the first build may take several seconds. This is because of the use of a C compiler to compile the opus, opusfile, and ogg libraries. Subsequent builds will be much quicker as the built package will be cached by the Go toolchain.

examples

There are a couple of examples in the example directory.

  • beep
    • Uses the beep package to play an Opus file.
    • go run example\beep\*.go [your-file.opus]
      • Without an argument, plays an embedded sample Opus file.
      • With an argument that is a path to an Opus file, will play the file.
  • simple
    • Uses various methods of opus.Decoder to get and print various information about an Opus stream.
    • go run example\simple\*.go [your-file.opus]
      • Without an argument, uses an embedded sample Opus file.
      • With an argument that is a path to an Opus file, uses the file.

possible alternatives

pion/opus

https://github.com/pion/opus is a pure Go implementation of the Opus codec.

hraban/opus

https://github.com/hraban/opus provides C bindings to the xiph.org C libraries.

  • It is more comprehensive than this library, and supports encoding as well as decoding of Opus streams.
  • It requires libopus and libopusfile development packages to be installed on the system.

development

pre-commit hook

Documentation

Overview

Package opus provides decoding of opus files, using the xiph.org C libraries opus, opusfile, and ogg.

Rather than use cgo to utilise system installed instances of the libraries (that may or may not be installed on a given system), the source for the libraries is included with this package. The libraries are compiled, with the help of cgo, when the package is compiled. This means that a C compiler (such as gcc or clang) and a linker need to be available on the path for cgo to use when building the package.

It may take several seconds to build this package the first time, until the Go tools cache the result of the build.

Index

Constants

View Source
const SampleRate = 48_000

SampleRate is number of samples per second in streams. It is always 48,000 for opus streams.

Variables

View Source
var (
	// A request did not succeed.
	OP_FALSE = OpusFileError{
				// contains filtered or unexported fields
	}

	// Currently not used externally.
	OP_EOF = OpusFileError{
			// contains filtered or unexported fields
	}

	// There was a hole in the page sequence numbers (e.g., a page was corrupt or missing).
	OP_HOLE = OpusFileError{
			// contains filtered or unexported fields
	}

	// An underlying read, seek, or tell operation failed when it should have succeeded.
	OP_EREAD = OpusFileError{
				// contains filtered or unexported fields
	}

	// A NULL pointer was passed where one was unexpected, or an internal memory allocation failed, or an internal library error was encountered.
	OP_EFAULT = OpusFileError{
				// contains filtered or unexported fields
	}

	// The stream used a feature that is not implemented, such as an unsupported channel family.
	OP_EIMPL = OpusFileError{
				// contains filtered or unexported fields
	}

	// One or more parameters to a function were invalid.
	OP_EINVAL = OpusFileError{
				// contains filtered or unexported fields
	}

	// A purported Ogg Opus stream did not begin with an Ogg page, a purported header packet did not start with one of the required strings, "OpusHead" or "OpusTags", or a link in a chained file was encountered that did not contain any logical Opus streams.
	OP_ENOTFORMAT = OpusFileError{
					// contains filtered or unexported fields
	}

	// A required header packet was not properly formatted, contained illegal values, or was missing altogether.
	OP_EBADHEADER = OpusFileError{
					// contains filtered or unexported fields
	}

	// The ID header contained an unrecognized version number.
	OP_EVERSION = OpusFileError{
				// contains filtered or unexported fields
	}

	// Currently not used at all.
	OP_ENOTAUDIO = OpusFileError{
					// contains filtered or unexported fields
	}

	// An audio packet failed to decode properly. More...
	OP_EBADPACKET = OpusFileError{
					// contains filtered or unexported fields
	}

	// We failed to find data we had seen before, or the bitstream structure was sufficiently malformed that seeking to the target destination was impossible.
	OP_EBADLINK = OpusFileError{
				// contains filtered or unexported fields
	}

	// An operation that requires seeking was requested on an unseekable stream.
	OP_ENOSEEK = OpusFileError{
				// contains filtered or unexported fields
	}

	// The first or last granule position of a link failed basic validity checks.
	OP_EBADTIMESTAMP = OpusFileError{
						// contains filtered or unexported fields
	}
)

Errors from the opusfile C library.

View Source
var SampleStream []byte

SampleStream is the data for a valid opus stream, that can be used for testing or demonstration purposes.

Functions

func Test

func Test(data []byte) error

Test checks to see if some data appears to be the start of an Opus stream.

For good results, at least 57 bytes are needed (for a pure Opus-only stream). Something like 512 bytes will give more reliable results for multiplexed streams. This function is meant to be a quick-rejection filter. Its purpose is not to guarantee that a stream is a valid Opus stream, but to ensure that it looks enough like Opus that it isn't going to be recognized as some other format (except possibly an Opus stream that is also multiplexed with other codecs, such as video).

Types

type Decoder

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

Decoder decodes an opus bitstream into PCM.

func NewDecoder

func NewDecoder(stream io.ReadSeeker) (*Decoder, error)

NewDecoder creates a new opus Decoder for a stream that implements io.Reader and io.Seeker.

func (*Decoder) ChannelCount

func (d *Decoder) ChannelCount() int

ChannelCount returns the number of channels in the stream. It is typically 2, representing a stereo stream.

func (*Decoder) Destroy

func (d *Decoder) Destroy()

Destroy releases C heap memory used by the decoder. After Destroy has been called no methods on the decoder should be called.

func (*Decoder) Duration

func (d *Decoder) Duration() time.Duration

Duration returns the total duration of the stream. It is independent of the current position in the stream.

func (*Decoder) Err

func (d *Decoder) Err() error

Err returns an error which may have occurred during streaming. If no error has ever occurred, nil is returned.

func (*Decoder) Head

func (d *Decoder) Head() Head

Head gets the stream's header information.

func (*Decoder) Len

func (d *Decoder) Len() int

Len returns the number of samples in the stream.

There will be SampleRate (48,000) samples per second, per channel.

func (*Decoder) Position

func (d *Decoder) Position() (int64, error)

Position obtains the PCM offset of the next sample to be read.

If the stream is not properly timestamped, this might not increment by the proper amount between reads, or even return monotonically increasing values.

func (*Decoder) Read

func (d *Decoder) Read(pcm []int16) (int, error)

Read will read up to len(pcm) samples in to the pcm argument.

The number of samples actually read, per channel, is returned. When there are no more samples to read, 0 and an io.EOF error will be returned.

func (*Decoder) ReadFloat

func (d *Decoder) ReadFloat(pcm []float32) (int, error)

Read will read up to len(pcm) samples in to the pcm argument.

The number of samples actually read, per channel, is returned. When there are no more samples to read, 0 and an io.EOF error will be returned.

func (*Decoder) Seek

func (d *Decoder) Seek(pos int64) error

Seek will seek to the specified PCM offset, such that decoding (using the Read or ReadFloat method) will begin at exactly the requested position.

func (*Decoder) TagsUserComments

func (d *Decoder) TagsUserComments() []UserComment

TagsUserComments returns comments from the stream's metadata.

The comments are ordered. Comments may have duplicate tag names.

func (*Decoder) TagsVendor

func (d *Decoder) TagsVendor() string

TagsVendor returns a string identifying the software used to encode the stream.

type Head struct {
	// Version holds the Ogg Opus format version, in the range 0...255.
	//
	// The top 4 bits represent a "major" version, and the bottom four bits represent backwards-compatible "minor" revisions. The current specification describes version 1. This library will recognize versions up through 15 as backwards compatible with the current specification. An earlier draft of the specification described a version 0, but the only difference between version 1 and version 0 is that version 0 did not specify the semantics for handling the version field.
	Version int
	// ChannelCount is the number of channels, in the range 1...255.
	ChannelCount int
	// PreSkip is the number of samples that should be discarded from the beginning of the stream.
	PreSkip uint
	// InputSampleRate is sampling rate of the original input.
	//
	// All Opus audio is coded at 48 kHz, and should also be decoded at 48 kHz for playback (unless the target hardware does not support this sampling rate). However, this field may be used to resample the audio back to the original sampling rate, for example, when saving the output to a file.
	InputSampleRate uint32
	// OutputGainDb is the gain to apply to the decoded output, in dB, as a Q8 value in the range -32768...32767.
	//
	// The decoder will automatically scale the output by pow(10,output_gain/(20.0*256)).
	OutputGainDb int
}

Head contains playback parameters for a stream.

type OpusFileError

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

OpusFileError represents an error from the opusfile C library.

func (*OpusFileError) Code

func (err *OpusFileError) Code() int

Code returns the numeric error code reported by the opusfile C library.

func (*OpusFileError) Error

func (err *OpusFileError) Error() string

func (*OpusFileError) Text

func (err *OpusFileError) Text() string

Text provides text that describes the nature of the error.

type UserComment

type UserComment struct {
	// Tag is the comment's tag name.
	Tag string
	// Value is the comment value.
	Value string
}

UserComment represents a comment from the stream's meta data. A comment comprises a tag name and a value.

Directories

Path Synopsis
example
beep command
simple command

Jump to

Keyboard shortcuts

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