goxiph

module
v0.0.0-...-da6c86d Latest Latest
Warning

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

Go to latest
Published: Aug 23, 2026 License: BSD-3-Clause

README

goxiph

Pure-Go audio codecs: Ogg, Vorbis, Opus, FLAC, MP3 and WAVE. No cgo, no bindings, no reference library to link against.

go get github.com/faide/goxiph

Every codec is verified against the reference implementation it is meant to replace, and the numbers below are what the test suite reports rather than what the code aspires to.

Compatibility matrix

Ogg decodes / encodes Vorbis decodes/ encodes Opus decodes / NO encoder MP3 decodes (layers I, II and III) / NO encoder WAVE decodes/ encodes

Tags are read for all of them: Vorbis comments, and ID3v2.2 through 2.4, ID3v1 and APEv2 for MP3.

MP3's patents expired in 2017. Encoding it is not planned. The world has enough MP3 encoders anyway.

Quality

FLAC decodes bit-exactly against ffmpeg on all 64 files of the conformance set RFC 9639 names — 22 kHz to 384 kHz, 8 to 24 bits, 1 to 8 channels, thirty-second-order predictors, escaped Rice partitions. It encodes to streams ffmpeg accepts and decodes back to the exact input samples, and on real music comes to 0.997x ffmpeg's size.

Opus decodes every mode — SILK, CELT and hybrid — and all 20075 packets of the official test vectors agree with the reference on the entropy coder's final state. Packet loss concealment, forward error correction and the redundancy path are all in. It implements RFC 6716 as corrected by RFC 8251, and the Ogg mapping of RFC 7845 as extended by RFC 8486.

MP3 decodes all three layers, and every one of the 33 ISO compliance vectors meets full compliance — 110 to 136 dB against the 101 dB the standard asks for. Every stage has an oracle of its own against minimp3: the bitstream, requantisation, the stereo couplings, the transform and the filterbank. Files play gapless from the LAME or VBRI tag.

Vorbis decodes to an exact frame count with at most one 16-bit LSB of error. It encodes streams ffmpeg and ogginfo accept without complaint; against oggenc on real music it is competitive at high quality and loses at low.

Reading a file

Each codec has a Decoder that hands back one block at a time, and the whole-file shortcut where that is what you want.

f, err := os.Open("song.flac")
if err != nil {
	return err
}
defer f.Close()

dec, err := flac.NewDecoder(f)
if err != nil {
	return err
}
info := dec.StreamInfo()
fmt.Println(info.SampleRate, "Hz,", info.Channels, "channels")

for {
	block, err := dec.Next()
	if errors.Is(err, io.EOF) {
		break
	}
	if err != nil {
		return err
	}
	// block.Samples is one []int32 per channel.
	_ = block
}

Samples come out as int32 per channel for FLAC, which is lossless and has a bit depth to preserve, and as float32 in an audio.Buffer for the lossy codecs. audio converts between the two and between interleaved and planar.

Writing a file

out, err := os.Create("song.flac")
if err != nil {
	return err
}
defer out.Close()

enc, err := flac.NewEncoder(out, flac.StreamInfo{
	SampleRate: 44100, Channels: 2, BitsPerSample: 16,
}, flac.EncoderOptions{})
if err != nil {
	return err
}
if err := enc.Write(samples); err != nil { // [][]int32, one per channel
	return err
}
return enc.Close()

Duration

Every format can give duration without decoding, which is what a progress bar needs:

d, err := mp3.Duration(f) // also flac.Duration, vorbis.Duration, opus.Duration

For Ogg it comes from the last page's granule position, for FLAC from STREAMINFO, and for MP3 from the VBR tag where there is one and the bitrate otherwise. All of them leave the reader where they found it.

CLI

cmd/goxiph reads any of the formats above and writes any it can encode.

go run ./cmd/goxiph info song.mp3
go run ./cmd/goxiph convert song.mp3 -o song.flac

Tags carry across where both formats have somewhere to put them.

Building and testing

The repo uses mise for tasks:

mise run ci           # format, vet, lint, test, race — the gate before any change
mise run fixtures     # synthesise the test corpus; media is generated, never committed
mise run conformance  # the tests that shell out to ffmpeg, oggenc, opusdec and the rest

go test ./... works on a bare machine with no tools installed: the tests that need them are behind a build tag and skip cleanly.

Conformance testing needs the reference tools — mise run doctor reports what is missing.

Licensing

BSD 3-Clause. See LICENSE, and NOTICE for what was taken from where.

Nothing here is a translation of libvorbis, libopus, libFLAC or ffmpeg. The one exception: MP3 has no freely readable specification, and its constant tables were recovered from minimp3, which is CC0. They were recovered rather than copied — minimp3's own packed lookup was walked over every bit pattern it accepts and the codes it emitted written out as a tree, so what is taken is the standard's data and not one implementation's arrangement of it.

Directories

Path Synopsis
Package audio defines the PCM representation shared by every container and codec in goxiph.
Package audio defines the PCM representation shared by every container and codec in goxiph.
cmd
goxiph command
Command goxiph converts between the Xiph formats and reports what a file holds.
Command goxiph converts between the Xiph formats and reports what a file holds.
Package flac implements the Free Lossless Audio Codec defined by RFC 9639.
Package flac implements the Free Lossless Audio Codec defined by RFC 9639.
Package id3 reads the tags wrapped around an MP3 file.
Package id3 reads the tags wrapped around an MP3 file.
internal
bitio
Package bitio provides the bit-level readers and writers the codecs are built from.
Package bitio provides the bit-level readers and writers the codecs are built from.
celt
Package celt implements the MDCT layer of the Opus codec, RFC 6716 section 4.3.
Package celt implements the MDCT layer of the Opus codec, RFC 6716 section 4.3.
lpc
Package lpc computes linear prediction coefficients.
Package lpc computes linear prediction coefficients.
mdct
Package mdct implements the modified discrete cosine transform used by transform codecs.
Package mdct implements the modified discrete cosine transform used by transform codecs.
rangecoder
Package rangecoder implements the Opus entropy coder of RFC 6716 section 4.1 and 5.1.
Package rangecoder implements the Opus entropy coder of RFC 6716 section 4.1 and 5.1.
silk
Package silk implements the linear-prediction layer of the Opus codec, RFC 6716 section 4.2.
Package silk implements the linear-prediction layer of the Opus codec, RFC 6716 section 4.2.
testutil/gen command
Command gen synthesises the conformance corpus.
Command gen synthesises the conformance corpus.
testutil/listen command
Command listen builds a blind listening kit for the questions the measures cannot settle.
Command listen builds a blind listening kit for the questions the measures cannot settle.
testutil/mp3oracle command
Command mp3oracle records what the reference decoder makes of the compliance bitstreams, at four points inside a granule, and writes the result as the oracle files the mp3 conformance tests read.
Command mp3oracle records what the reference decoder makes of the compliance bitstreams, at four points inside a granule, and writes the result as the oracle files the mp3 conformance tests read.
testutil/mp3tables command
Command mp3tables generates the constant tables the MP3 decoder needs.
Command mp3tables generates the constant tables the MP3 decoder needs.
testutil/refenc command
Command refenc builds Opus fixtures that opusenc will not produce.
Command refenc builds Opus fixtures that opusenc will not produce.
testutil/silkframes command
Command silkframes extracts the SILK payloads from the generated corpus.
Command silkframes extracts the SILK payloads from the generated corpus.
testutil/silktables command
Command silktables transcribes the SILK constant tables from the RFC 6716 reference into Go.
Command silktables transcribes the SILK constant tables from the RFC 6716 reference into Go.
testutil/vectors command
Command vectors surveys the official Opus test vectors.
Command vectors surveys the official Opus test vectors.
Package mp3 decodes MPEG-1, MPEG-2 and MPEG-2.5 audio, layers I, II and III.
Package mp3 decodes MPEG-1, MPEG-2 and MPEG-2.5 audio, layers I, II and III.
Package ogg implements the Ogg container defined by RFC 3533.
Package ogg implements the Ogg container defined by RFC 3533.
Package opus implements the Opus audio codec of RFC 6716 and its Ogg mapping of RFC 7845.
Package opus implements the Opus audio codec of RFC 6716 and its Ogg mapping of RFC 7845.
Package vorbis implements the Vorbis I audio codec.
Package vorbis implements the Vorbis I audio codec.
Package vorbiscomment implements the Vorbis comment metadata block.
Package vorbiscomment implements the Vorbis comment metadata block.
Package wav reads and writes RIFF/WAVE files.
Package wav reads and writes RIFF/WAVE files.

Jump to

Keyboard shortcuts

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