Skip to content

Commit

Permalink
Partially document exported types and functions
Browse files Browse the repository at this point in the history
  • Loading branch information
pekim committed Mar 7, 2024
1 parent dbeeced commit 01ac0f6
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 12 deletions.
2 changes: 2 additions & 0 deletions decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"unsafe"
)

// Decoder decodes an opus bitstream into PCM.
type Decoder struct {
file *C.OggOpusFile
data []byte
Expand All @@ -17,6 +18,7 @@ type Decoder struct {
duration time.Duration
}

// NewDecoder creates a new opus Decoder.
func NewDecoder(data []byte) (*Decoder, error) {
var opusFileErr C.int
file := C.op_open_memory((*C.uchar)(&data[0]), C.size_t(len(data)), &opusFileErr)
Expand Down
20 changes: 20 additions & 0 deletions doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
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.
[opus]: https://github.com/xiph/opus
[opusfile]: https://github.com/xiph/opusfile
[ogg]: https://github.com/xiph/ogg
*/
package opus
43 changes: 31 additions & 12 deletions error.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,82 +8,113 @@ import (
"math"
)

// OpusFileError represents an error from the opusfile C library.
type OpusFileError struct {
code int
text string
}

func (err *OpusFileError) Error() string {
return fmt.Sprintf("opusfile error %d, '%s'", err.code, err.text)
}

// Code returns the numeric error code reported by the opusfile C library.
func (err *OpusFileError) Code() int {
return err.code
}

// Text provides text that describes the nature of the error.
func (err *OpusFileError) Text() string {
return err.text
}

// Errors from the opusfile C library.
var (
// A request did not succeed.
OP_FALSE = OpusFileError{
code: C.OP_FALSE,
text: "A request did not succeed.",
}

// Currently not used externally.
OP_EOF = OpusFileError{
code: C.OP_EOF,
text: "Currently not used externally.",
}

// There was a hole in the page sequence numbers (e.g., a page was corrupt or missing).
OP_HOLE = OpusFileError{
code: C.OP_HOLE,
text: "There was a hole in the page sequence numbers (e.g., a page was corrupt or missing).",
}

// An underlying read, seek, or tell operation failed when it should have succeeded.
OP_EREAD = OpusFileError{
code: C.OP_EREAD,
text: "An underlying read, seek, or tell operation failed when it should have succeeded.",
}

// 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{
code: C.OP_EFAULT,
text: "A NULL pointer was passed where one was unexpected, or an internal memory allocation failed, or an internal library error was encountered.",
}

// The stream used a feature that is not implemented, such as an unsupported channel family.
OP_EIMPL = OpusFileError{
code: C.OP_EIMPL,
text: "The stream used a feature that is not implemented, such as an unsupported channel family.",
}

// One or more parameters to a function were invalid.
OP_EINVAL = OpusFileError{
code: C.OP_EINVAL,
text: "One or more parameters to a function were invalid.",
}

// 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{
code: C.OP_ENOTFORMAT,
text: "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.",
}

// A required header packet was not properly formatted, contained illegal values, or was missing altogether.
OP_EBADHEADER = OpusFileError{
code: C.OP_EBADHEADER,
text: "A required header packet was not properly formatted, contained illegal values, or was missing altogether.",
}

// The ID header contained an unrecognized version number.
OP_EVERSION = OpusFileError{
code: C.OP_EVERSION,
text: "The ID header contained an unrecognized version number.",
}

// Currently not used at all.
OP_ENOTAUDIO = OpusFileError{
code: C.OP_ENOTAUDIO,
text: "Currently not used at all.",
}

// An audio packet failed to decode properly. More...
OP_EBADPACKET = OpusFileError{
code: C.OP_EBADPACKET,
text: "An audio packet failed to decode properly. More...",
}

// 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{
code: C.OP_EBADLINK,
text: "We failed to find data we had seen before, or the bitstream structure was sufficiently malformed that seeking to the target destination was impossible.",
}

// An operation that requires seeking was requested on an unseekable stream.
OP_ENOSEEK = OpusFileError{
code: C.OP_ENOSEEK,
text: "An operation that requires seeking was requested on an unseekable stream.",
}

// The first or last granule position of a link failed basic validity checks.
OP_EBADTIMESTAMP = OpusFileError{
code: C.OP_EBADTIMESTAMP,
text: "The first or last granule position of a link failed basic validity checks.",
Expand All @@ -108,18 +139,6 @@ var allOpusFileErrors = []OpusFileError{
OP_EBADTIMESTAMP,
}

func (err *OpusFileError) Error() string {
return fmt.Sprintf("opusfile error %d, '%s'", err.code, err.text)
}

func (err *OpusFileError) Code() int {
return err.code
}

func (err *OpusFileError) Text() string {
return err.text
}

func errorFromOpusFileError(code C.int) error {
for _, err := range allOpusFileErrors {
if err.code == int(code) {
Expand Down
10 changes: 10 additions & 0 deletions opus.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ import (
_ "github.com/pekim/opus/c-sources"
)

/*
Test checks to see if some data appears to be the start of an Opus stream.
For good results, you will need at least 57 bytes (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).
*/
func Test(data []byte) error {
result := C.op_test(nil, (*C.uchar)(&data[0]), C.ulong(min(512, len(data))))
if result < 0 {
Expand Down

0 comments on commit 01ac0f6

Please sign in to comment.