Documentation ¶
Overview ¶
Package wav is a package allowing developers to decode and encode audio PCM data using the Waveform Audio File Format https://en.wikipedia.org/wiki/WAV
Index ¶
- type Decoder
- func (d *Decoder) Duration() (time.Duration, error)
- func (d *Decoder) EOF() bool
- func (d *Decoder) Err() error
- func (d *Decoder) Format() *audio.Format
- func (d *Decoder) FullPCMBuffer() (*audio.PCMBuffer, error)
- func (d *Decoder) FwdToPCM() error
- func (d *Decoder) IsValidFile() bool
- func (d *Decoder) NextChunk() (*riff.Chunk, error)
- func (d *Decoder) PCMBuffer(buf *audio.PCMBuffer) error
- func (d *Decoder) PCMLen() int64
- func (d *Decoder) ReadInfo()
- func (d *Decoder) Reset()
- func (d *Decoder) SampleBitDepth() int32
- func (d *Decoder) String() string
- func (d *Decoder) WasPCMAccessed() bool
- type Encoder
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Decoder ¶
type Decoder struct { NumChans uint16 BitDepth uint16 SampleRate uint32 AvgBytesPerSec uint32 WavAudioFormat uint16 PCMSize int // pcmChunk is available so we can use the LimitReader PCMChunk *riff.Chunk // contains filtered or unexported fields }
Decoder handles the decoding of wav files.
func NewDecoder ¶
func NewDecoder(r io.ReadSeeker) *Decoder
NewDecoder creates a decoder for the passed wav reader. Note that the reader doesn't get rewinded as the container is processed.
func (*Decoder) Duration ¶
Duration returns the time duration for the current audio container
Example ¶
package main import ( "fmt" "log" "os" "github.com/mattetti/audio/wav" ) func main() { f, err := os.Open("fixtures/kick.wav") if err != nil { log.Fatal(err) } defer f.Close() dur, err := wav.NewDecoder(f).Duration() if err != nil { log.Fatal(err) } fmt.Printf("%s duration: %s\n", f.Name(), dur) }
Output: fixtures/kick.wav duration: 204.172335ms
func (*Decoder) FullPCMBuffer ¶
FullPCMBuffer is an inneficient way to access all the PCM data contained in the audio container. The entire PCM data is held in memory. Consider using Buffer() instead.
func (*Decoder) FwdToPCM ¶
FwdToPCM forwards the underlying reader until the start of the PCM chunk. If the PCM chunk was already read, no data will be found (you need to rewind).
func (*Decoder) IsValidFile ¶
IsValidFile verifies that the file is valid/readable.
Example ¶
package main import ( "fmt" "log" "os" "github.com/mattetti/audio/wav" ) func main() { f, err := os.Open("fixtures/kick.wav") if err != nil { log.Fatal(err) } defer f.Close() fmt.Printf("is this file valid: %t", wav.NewDecoder(f).IsValidFile()) }
Output: is this file valid: true
func (*Decoder) ReadInfo ¶
func (d *Decoder) ReadInfo()
ReadInfo reads the underlying reader until the comm header is parsed. This method is safe to call multiple times.
func (*Decoder) Reset ¶
func (d *Decoder) Reset()
Reset resets the decoder (and rewind the underlying reader)
func (*Decoder) SampleBitDepth ¶
SampleBitDepth returns the bit depth encoding of each sample.
func (*Decoder) WasPCMAccessed ¶
WasPCMAccessed returns positively if the PCM data was previously accessed.
type Encoder ¶
type Encoder struct { SampleRate int BitDepth int NumChans int // A number indicating the WAVE format category of the file. The content of the // <format-specific-fields> portion of the ‘fmt’ chunk, and the interpretation of // the waveform data, depend on this value. // PCM = 1 (i.e. Linear quantization) Values other than 1 indicate some form of compression. WavAudioFormat int WrittenBytes int // contains filtered or unexported fields }
Encoder encodes LPCM data into a wav containter.
func NewEncoder ¶
func NewEncoder(w io.WriteSeeker, sampleRate, bitDepth, numChans, audioFormat int) *Encoder
NewEncoder creates a new encoder to create a new wav file. Don't forget to add Frames to the encoder before writing.
func (*Encoder) Close ¶
Close flushes the content to disk, make sure the headers are up to date Note that the underlying writter is NOT being closed.
func (*Encoder) Write ¶
Write encodes and writes the passed buffer to the underlying writer. Don't forger to Close() the encoder or the file won't be valid.
Example ¶
package main import ( "fmt" "os" "github.com/mattetti/audio/wav" ) func main() { f, err := os.Open("fixtures/kick.wav") if err != nil { panic(fmt.Sprintf("couldn't open audio file - %v", err)) } // Decode the original audio file // and collect audio content and information. d := wav.NewDecoder(f) buf, err := d.FullPCMBuffer() if err != nil { panic(err) } f.Close() fmt.Println("Old file ->", d) // Destination file out, err := os.Create("testOutput/kick.wav") if err != nil { panic(fmt.Sprintf("couldn't create output file - %v", err)) } // setup the encoder and write all the frames e := wav.NewEncoder(out, buf.Format.SampleRate, buf.Format.BitDepth, buf.Format.NumChannels, int(d.WavAudioFormat)) if err := e.Write(buf); err != nil { panic(err) } // close the encoder to make sure the headers are properly // set and the data is flushed. if err := e.Close(); err != nil { panic(err) } out.Close() // reopen to confirm things worked well out, err = os.Open("testOutput/kick.wav") if err != nil { panic(err) } d2 := wav.NewDecoder(out) d2.ReadInfo() fmt.Println("New file ->", d2) out.Close() os.Remove(out.Name()) }
Output: Old file -> Format: WAVE - 1 channels @ 22050 / 16 bits - Duration: 0.204172 seconds New file -> Format: WAVE - 1 channels @ 22050 / 16 bits - Duration: 0.204172 seconds