wav

package
v0.0.0-...-c5379f9 Latest Latest
Warning

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

Go to latest
Published: Apr 11, 2024 License: MIT Imports: 8 Imported by: 7

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

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

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

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) EOF

func (d *Decoder) EOF() bool

EOF returns positively if the underlying reader reached the end of file.

func (*Decoder) Err

func (d *Decoder) Err() error

Err returns the first non-EOF error that was encountered by the Decoder.

func (*Decoder) Format

func (d *Decoder) Format() *audio.Format

Format returns the audio format of the decoded content.

func (*Decoder) FullPCMBuffer

func (d *Decoder) FullPCMBuffer() (*audio.PCMBuffer, error)

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

func (d *Decoder) FwdToPCM() error

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

func (d *Decoder) IsValidFile() bool

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) NextChunk

func (d *Decoder) NextChunk() (*riff.Chunk, error)

NextChunk returns the next available chunk

func (*Decoder) PCMBuffer

func (d *Decoder) PCMBuffer(buf *audio.PCMBuffer) error

PCMBuffer populates the passed PCM buffer

func (*Decoder) PCMLen

func (d *Decoder) PCMLen() int64

PCMLen returns the total number of bytes in the PCM data chunk

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

func (d *Decoder) SampleBitDepth() int32

SampleBitDepth returns the bit depth encoding of each sample.

func (*Decoder) String

func (d *Decoder) String() string

String implements the Stringer interface.

func (*Decoder) WasPCMAccessed

func (d *Decoder) WasPCMAccessed() bool

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) AddBE

func (e *Encoder) AddBE(src interface{}) error

AddBE serializes and adds the passed value using big endian

func (*Encoder) AddLE

func (e *Encoder) AddLE(src interface{}) error

AddLE serializes and adds the passed value using little endian

func (*Encoder) Close

func (e *Encoder) Close() error

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

func (e *Encoder) Write(buf *audio.PCMBuffer) error

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

Jump to

Keyboard shortcuts

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