Documentation
¶
Overview ¶
Package wav provides the shared types and error sentinels for reading and writing WAV audio, including the 64-bit RF64 and BW64 extensions.
The streaming API lives in the pcm subpackage, so that this package can hold the types both layers need without an import cycle. Callers who want to encode or decode audio want github.com/tphakala/go-wav/pcm; this package is what that one returns and the errors it reports.
Containers ¶
Three container flavours share one chunk layout. Plain RIFF stores sizes in 32-bit fields and therefore cannot describe a file of 4 GiB or more. RF64 (EBU Tech 3306) and BW64 (ITU-R BS.2088) lift that limit by writing a sentinel into the 32-bit fields and carrying the real 64-bit sizes in a ds64 chunk. BW64 is structurally identical to RF64 and differs only in its magic and in the metadata chunks it is expected to carry, so this package reads both and reports which one it saw in StreamInfo.Container.
Sample formats ¶
Samples are always little-endian. Integer PCM is unsigned at 8 bits with a midpoint of 128, and signed two's complement at 16, 24 and 32 bits; 24-bit samples are packed into three bytes with no padding. Float samples are IEEE 754 at 32 or 64 bits with a nominal full scale of [-1, +1].
A-law, mu-law, ADPCM and the other compressed WAVE format tags are not supported. A file using one is reported as ErrUnsupported rather than decoded incorrectly.
Index ¶
Constants ¶
const Version = "0.1.0"
Version is the module version.
Variables ¶
var ( // ErrNotRIFF reports a stream whose first twelve bytes are not a RIFF, // RF64 or BW64 WAVE header. It means "this is not a WAV file at all", // as distinct from ErrCorruptStream, which means "this is a WAV file and // it is broken". ErrNotRIFF = errors.New("go-wav: not a RIFF, RF64 or BW64 stream") // ErrCorruptStream reports a malformed stream: a chunk header that runs // past the end of its parent, a fmt chunk shorter than 16 bytes, a // missing fmt or data chunk, or an RF64 stream with no ds64 chunk. It is // reserved for damage the reader cannot work around; the tolerated // real-world deviations documented on the decoder do not produce it. ErrCorruptStream = errors.New("go-wav: corrupt stream") // ErrUnsupported reports a well-formed stream this package will not // decode: a compressed or companded format tag such as A-law, mu-law or // ADPCM, a bit depth outside the supported set, or a float stream at a // width other than 32 or 64 bits. ErrUnsupported = errors.New("go-wav: unsupported sample format") // ErrEncoderClosed is returned by Encoder.Write and Encoder.Close after // Close has been called, and by methods on an encoder left uninitialised // by a zero value or a failed Reset. ErrEncoderClosed = errors.New("go-wav: encoder is closed") // ErrTooLarge reports a stream that has outgrown the 4 GiB limit of the // 32-bit RIFF size fields at a point where no RF64 upgrade is possible: // the policy forbids it, or the sink cannot seek and the frame count was // not declared up front. The encoder returns this instead of writing a // size field it knows to be wrong. ErrTooLarge = errors.New("go-wav: stream exceeds the 4 GiB RIFF limit and RF64 is unavailable") // ErrSeekUnsupported reports a seek requested on a source that does not // implement io.Seeker. ErrSeekUnsupported = errors.New("go-wav: seek unsupported (source is not an io.Seeker)") )
Sentinel errors returned by the wav and pcm packages, testable with errors.Is. They live in the root package so that both layers can report the same values, mirroring go-flac's layout.
Functions ¶
func Sniff ¶
Sniff reports whether b begins with a RIFF, RF64 or BW64 WAVE header. It reads at most the first twelve bytes, needs no allocation, and returns false rather than panicking on a short slice.
It exists so that callers dispatching on file type do not have to hand-roll a magic check that forgets RF64 and BW64.
Types ¶
type Container ¶
type Container int
Container identifies the RIFF flavour of a stream.
const ( // ContainerRIFF is a plain RIFF WAVE stream with 32-bit size fields. It // cannot describe 4 GiB or more of audio. ContainerRIFF Container = iota // ContainerRF64 is an RF64 stream as defined by EBU Tech 3306: the magic // is "RF64", the 32-bit sizes hold 0xFFFFFFFF, and a ds64 chunk carries // the real 64-bit values. ContainerRF64 // ContainerBW64 is a BW64 stream as defined by ITU-R BS.2088. It is // structurally identical to RF64 and differs only in its magic. ContainerBW64 )
type SampleFormat ¶
type SampleFormat int
SampleFormat identifies how samples in the data chunk are encoded.
const ( // SampleFormatPCM is integer PCM: unsigned with a midpoint of 128 at 8 // bits, signed two's complement at 16, 24 and 32 bits. SampleFormatPCM SampleFormat = iota // SampleFormatFloat is IEEE 754 floating point at 32 or 64 bits, with a // nominal full scale of [-1, +1]. SampleFormatFloat )
func (SampleFormat) String ¶
func (f SampleFormat) String() string
String returns a short name for the sample format.
type StreamInfo ¶
type StreamInfo struct {
// SampleRate is the number of samples per second per channel.
SampleRate int
// Channels is the interleaved channel count.
Channels int
// BitDepth is the storage width in bits of one sample as the caller sees
// it: 8, 16, 24 or 32 for integer PCM, 32 or 64 for float. It describes
// the bytes Decoder.Read yields, so under a conversion option it is the
// converted width, not the width stored in the file. SourceBitDepth
// reports the latter.
//
// It is the container width, which under WAVE_FORMAT_EXTENSIBLE may
// exceed the meaningful width reported by ValidBits.
BitDepth int
// SourceBitDepth is the storage width in bits of one sample as it is
// encoded in the file. It differs from BitDepth only when the decoder
// was asked to convert; otherwise the two are equal.
SourceBitDepth int
// ValidBits is the number of meaningful bits per sample declared by an
// extensible fmt chunk, for sources such as 20-bit audio stored in a
// 24-bit container. It is 0 when the stream did not declare one, in
// which case every bit of BitDepth is meaningful.
ValidBits int
// Format is the sample encoding as the caller sees it. Like BitDepth it
// describes the bytes Decoder.Read yields, so a float file being
// converted to integer reports SampleFormatPCM here and
// SampleFormatFloat in SourceFormat.
Format SampleFormat
// SourceFormat is the sample encoding as it appears in the file. It
// differs from Format only when the decoder was asked to convert;
// otherwise the two are equal.
SourceFormat SampleFormat
// Container is the RIFF flavour the stream was read from or written as.
Container Container
// Extensible reports whether the fmt chunk used WAVE_FORMAT_EXTENSIBLE
// rather than a bare format tag.
Extensible bool
// ChannelMask is the dwChannelMask speaker assignment from an extensible
// fmt chunk. It is 0 when the stream did not declare one.
ChannelMask uint32
// TotalFrames is the number of inter-channel frames in the stream. It is
// 0 when the count is not known, which happens for a stream whose data
// chunk size was absent or unreadable.
TotalFrames uint64
}
StreamInfo describes a WAVE stream. A Decoder reports the properties of the stream it is reading; an Encoder reports the properties of the stream it is writing. It mirrors flac.StreamInfo in the sibling go-flac library.
func (StreamInfo) BytesPerFrame ¶
func (si StreamInfo) BytesPerFrame() int
BytesPerFrame is the storage width of one inter-channel frame in bytes. It is the value a WAVE fmt chunk records as nBlockAlign.
func (StreamInfo) BytesPerSample ¶
func (si StreamInfo) BytesPerSample() int
BytesPerSample is the storage width of a single-channel sample in bytes.
func (StreamInfo) Duration ¶
func (si StreamInfo) Duration() time.Duration
Duration is the length of the stream. It is 0 when TotalFrames or SampleRate is 0, so a stream of unknown length reports 0 rather than a wrong answer.
Directories
¶
| Path | Synopsis |
|---|---|
|
internal
|
|
|
riff
Package riff implements the container half of a WAV file: the RIFF chunk structure, the fmt chunk, and the ds64 mechanics that lift RF64 and BW64 past the 4 GiB ceiling of a plain RIFF stream.
|
Package riff implements the container half of a WAV file: the RIFF chunk structure, the fmt chunk, and the ds64 mechanics that lift RF64 and BW64 past the 4 GiB ceiling of a plain RIFF stream. |
|
sample
Package sample converts WAVE sample data between the encodings this library supports.
|
Package sample converts WAVE sample data between the encodings this library supports. |
|
Package pcm reads and writes WAV audio as interleaved little-endian PCM.
|
Package pcm reads and writes WAV audio as interleaved little-endian PCM. |