README

Package snd GoDoc

Package snd provides methods and types for sound processing and synthesis.

go get dasa.cc/snd

Windows

Tested with msys2. Additional setup required due to how gomobile currently links to openal on windows. This should go away in the future stepping away from gomobile's exp/al package.

pacman -S mingw-w64-x86_64-openal
cd /mingw64/lib
cp libopenal.a libOpenAL32.a
cp libopenal.dll.a libOpenAL32.dll.a

Tests

In addition to regular unit tests, there are plot tests that produce images saved to a plots/ folder. This depends on package gonum/plot and requires an additional tag flag to enable as follows:

go get github.com/gonum/plot
go test -tags plot

SndObj

This package was very much inspired by Victor Lazzarini's SndObj Library for which I spent countless hours enjoying, and without it I may never have come to program.

Documentation

Overview

Package snd provides methods and types for sound processing and synthesis.

Audio hardware is accessed via package snd/al which in turn manages the dispatching of sound synthesis via golang.org/x/mobile/audio/al. Start the dispatcher as follows:

const buffers = 1
if err := al.OpenDevice(buffers); err != nil {
    log.Fatal(err)
}
al.Start()

Once running, add a source for sound synthesis. For example:

osc := snd.NewOscil(snd.Sine(), 440, nil)
al.AddSource(osc)

This results in a 440Hz tone being played back through the audio hardware.

Synthesis types in package snd implement the Sound interface and many type methods accept a Sound argument that can affect sampling. For example, one may modulate an oscillator by passing in a third argument to NewOscil.

sine := snd.Sine()
mod := snd.NewOscil(sine, 2, nil)
osc := snd.NewOscil(sine, 440, mod)

The above results in a lower frequency sound that may require decent speakers to hear properly.

Signals

Note the sine argument in the previous example. There are two conceptual types of sounds, ContinuousFunc and Discrete. ContinuousFunc represents an indefinite series over time. Discrete is the sampling of a ContinuousFunc over an interval. Functions such as Sine, Triangle, and Square (non-exhaustive) return Discretes created by sampling a ContinuousFunc such as SineFunc, TriangleFunc, and SquareFunc.

Discrete signals serve as a lookup table to efficiently synthesize sound. A Discrete is a []float64 and can sample any ContinuousFunc, within the package or user defined which is a func(t float64) float64.

Discrete signals may be further modified with intent or arbitrarily. For example, Discrete.Add(Discrete, int) performs additive synthesis and is used by functions such as SquareSynthesis(int) to return an approximation of a square signal based on a sinusoidal.

Time Approximation

Functions that take a time.Duration argument approximate the value to the closest number of frames. For example, if sample rate is 44.1kHz and duration is 75ms, this results in the argument representing 3307 frames which is approximately 74.99ms.

Index

Constants

View Source
const (
	DefaultSampleRate     float64 = 44100
	DefaultSampleBitDepth         = 16 // TODO not currently used for anything
	DefaultBufferLen              = 256
	DefaultAmpFac         float64 = 0.31622776601683794 // -10dB
)
View Source
const DefaultNotesLen = 128

Variables

This section is empty.

Functions

func Dtof

func Dtof(d time.Duration, sr float64) (f int)

Dtof converts time duration to approximate number of representative frames.

func EqualTempermantFunc

func EqualTempermantFunc(ns Notes, tones int, freq float64, pos int)

EqualTempermantFunc evaluates notes as an octave containing n tones at an equal distance on a logarithmic scale. The reference freq and pos is used to find all other values.

func ExpDecayFunc

func ExpDecayFunc(t float64) float64

func Ftod

func Ftod(f int, sr float64) (d time.Duration)

Ftod converts f, number of frames, to approximate time duration.

func LinearDecayFunc

func LinearDecayFunc(t float64) float64

func SawtoothFunc

func SawtoothFunc(t float64) float64

SawtoothFunc is the continuous signal of a sawtooth wave.

func SineFunc

func SineFunc(t float64) float64

SineFunc is the continuous signal of a sine wave.

func SquareFunc

func SquareFunc(t float64) float64

SquareFunc is the continuous signal of a square wave.

func TriangleFunc

func TriangleFunc(t float64) float64

TriangleFunc is the continuous signal of a triangle wave.

Types

type ADSR

type ADSR struct {
	// contains filtered or unexported fields
}

TODO reimplement sustain functionality

func NewADSR

func NewADSR(attack, decay, sustain, release time.Duration, susamp, maxamp float64, in Sound) *ADSR

func (*ADSR) Dur

func (adsr *ADSR) Dur() time.Duration

func (ADSR) Prepare

func (sq ADSR) Prepare(uint64)

func (*ADSR) Release

func (adsr *ADSR) Release() (ok bool)

Release immediately releases envelope from anywhere and starts release period.

func (*ADSR) Restart

func (adsr *ADSR) Restart()

Restart resets envelope to start from attack period.

func (*ADSR) Sustain

func (adsr *ADSR) Sustain()

Sustain locks envelope when sustain period is reached.

type BPM

type BPM float64

BPM respresents beats per minute and is a measure of tempo.

func (BPM) Dur

func (bpm BPM) Dur() time.Duration

Dur returns the time duration of bpm.

func (BPM) Hertz

func (bpm BPM) Hertz() float64

Hertz returns the frequency of bpm as bpm / 2.

type ByWT

type ByWT []*Input

func (ByWT) Len

func (a ByWT) Len() int

func (ByWT) Less

func (a ByWT) Less(i, j int) bool

func (ByWT) Slice

func (a ByWT) Slice() (sl [][]*Input)

func (ByWT) Swap

func (a ByWT) Swap(i, j int)

type Comb

type Comb struct {
	// contains filtered or unexported fields
}

Comb adds a delayed version of a signal onto itself.

func NewComb

func NewComb(gain float64, d time.Duration, in Sound) *Comb

func (Comb) At

func (sd Comb) At(t float64) float64

func (Comb) Channels

func (sd Comb) Channels() int

func (Comb) Index

func (sd Comb) Index(i int) float64

func (Comb) Inputs

func (sd Comb) Inputs() []Sound

func (Comb) Interp

func (sd Comb) Interp(t float64) float64

func (Comb) IsOff

func (sd Comb) IsOff() bool

func (Comb) Off

func (sd Comb) Off()

func (Comb) On

func (sd Comb) On()

func (*Comb) Prepare

func (cmb *Comb) Prepare(uint64)

func (Comb) SampleRate

func (sd Comb) SampleRate() float64

func (Comb) Samples

func (sd Comb) Samples() Discrete

type Continuous

type Continuous func(t float64) float64

Continuous represents a continuous-time signal.

Effectively, many things may be represented as continuous. A function returning math.Sin(2*math.Pi*t) samples a sine wave while Discrete.Interpolate returns an interpolated value from its table, with both satisfying this type.

func (Continuous) Sample

func (fn Continuous) Sample(src Continuous, interval, phase float64) float64

Sample satisfies Sampler interface.

The side effect of fn sampling src can not be known, so this returns phase+interval.

type Damp

type Damp struct {
	// contains filtered or unexported fields
}

func NewDamp

func NewDamp(d time.Duration, in Sound) *Damp

func (Damp) At

func (sd Damp) At(t float64) float64

func (Damp) Channels

func (sd Damp) Channels() int

func (Damp) Index

func (sd Damp) Index(i int) float64

func (Damp) Inputs

func (sd Damp) Inputs() []Sound

func (Damp) Interp

func (sd Damp) Interp(t float64) float64

func (Damp) IsOff

func (sd Damp) IsOff() bool

func (Damp) Off

func (sd Damp) Off()

func (Damp) On

func (sd Damp) On()

func (*Damp) Prepare

func (dmp *Damp) Prepare(uint64)

func (Damp) SampleRate

func (sd Damp) SampleRate() float64

func (Damp) Samples

func (sd Damp) Samples() Discrete

type Decibel

type Decibel float64

Decibel is relative to full scale; anything over 0dB will clip.

func (Decibel) Amp

func (db Decibel) Amp() float64

Amp converts dB to amplitude multiplier.

func (Decibel) String

func (db Decibel) String() string

type Delay

type Delay struct {
	// contains filtered or unexported fields
}

Delay represents a signal delayed by a given duration.

func NewDelay

func NewDelay(d time.Duration, in Sound) *Delay

NewDelay returns Delay with sample buffer of a length approximated by d.

func (Delay) At

func (sd Delay) At(t float64) float64

func (Delay) Channels

func (sd Delay) Channels() int

func (Delay) Index

func (sd Delay) Index(i int) float64

func (Delay) Inputs

func (sd Delay) Inputs() []Sound

func (Delay) Interp

func (sd Delay) Interp(t float64) float64

func (Delay) IsOff

func (sd Delay) IsOff() bool

func (Delay) Off

func (sd Delay) Off()

func (Delay) On

func (sd Delay) On()

func (*Delay) Prepare

func (dly *Delay) Prepare(uint64)

func (Delay) SampleRate

func (sd Delay) SampleRate() float64

func (Delay) Samples

func (sd Delay) Samples() Discrete

type Discrete

type Discrete []float64

Discrete represents a discrete-time signal.

If building a lookup table, let sampling interval equal the recipricol of len(Discrete).

const n = 1024
sig := make(Discrete, n)
sig.Sample(SineFunc, 1/n, 0)

If samples are intended to be played back in sequence, provide normalized frequency against output sample rate; e.g. to sample four seconds of 440Hz sine wave at 44.1kHz

r := 44100.0
t := 4.0
out := make(Discrete, int(r*t)) // allocate four seconds of space
out.Sample(SineFunc, 440/r, 0)  // sample 440Hz sine wave

To play these samples over four second period, use an oscillator as clock.

osc := NewOscil(out, 1/t, nil)

TODO document sampling at different rates.

func ExpDecay

func ExpDecay() Discrete

func ExpDrive

func ExpDrive() Discrete

func LinearDecay

func LinearDecay() Discrete

func LinearDrive

func LinearDrive() Discrete

func Sawtooth

func Sawtooth() Discrete

Sawtooth returns a discrete sample of SawtoothFunc.

func SawtoothSynthesis

func SawtoothSynthesis(n int) Discrete

SawtoothSynthesis adds all partial harmonics belonging to [2..n], creating a sinusoidal wave that is the inverse of a sawtooth.

func Sine

func Sine() Discrete

Sine returns a discrete sample of SineFunc.

func Square

func Square() Discrete

Square returns a discrete sample of SquareFunc.

func SquareSynthesis

func SquareSynthesis(n int) Discrete

SquareSynthesis adds odd partial harmonics belonging to [3..n], creating a sinusoidal wave.

func Triangle

func Triangle() Discrete

Triangle returns a discrete sample of TriangleFunc.

func (Discrete) AdditiveInverse

func (sig Discrete) AdditiveInverse()

AdditiveInverse sets each sample to -x.

func (Discrete) AdditiveSynthesis

func (sig Discrete) AdditiveSynthesis(fd Discrete, pth int)

AdditiveSynthesis adds the fundamental, fd, for the partial harmonic, pth, to sig.

func (Discrete) At

func (sig Discrete) At(t float64) float64

At uses the fractional component of t to return the sample at the truncated index.

func (Discrete) Index

func (sig Discrete) Index(i int) float64

func (Discrete) Interp

func (sig Discrete) Interp(t float64) float64

Interp uses the fractional component of t to return an interpolated sample.

TODO currently does linear interpolation...

func (Discrete) Multiply

func (sig Discrete) Multiply(xs Discrete)

func (Discrete) MultiplyScalar

func (sig Discrete) MultiplyScalar(x float64)

func (Discrete) Normalize

func (sig Discrete) Normalize()

Normalize alters sig so values belong to [-1..1].

func (Discrete) NormalizeRange

func (sig Discrete) NormalizeRange(s, e float64)

NormalizeRange alters sig so values belong to [s..e].

Calling this method for values that already occupy [s..e] will degrade values further due to round-off error.

func (Discrete) Reverse

func (sig Discrete) Reverse()

Reverse sig in place so the first element becomes the last and the last element becomes the first.

func (Discrete) Sample

func (sig Discrete) Sample(src Continuous, interval, phase float64) float64

Sample satisfies Sampler interface.

func (Discrete) UnitInverse

func (sig Discrete) UnitInverse()

UnitInverse sets each sample to 1 - x.

type Dispatcher

type Dispatcher struct{ sync.WaitGroup }

func (*Dispatcher) Dispatch

func (dp *Dispatcher) Dispatch(tc uint64, inps ...*Input)

Dispatch blocks until all inputs are prepared.

type Drive

type Drive struct {
	// contains filtered or unexported fields
}

func NewDrive

func NewDrive(d time.Duration, in Sound) *Drive

func (Drive) At

func (sd Drive) At(t float64) float64

func (Drive) Channels

func (sd Drive) Channels() int

func (Drive) Index

func (sd Drive) Index(i int) float64

func (Drive) Inputs

func (sd Drive) Inputs() []Sound

func (Drive) Interp

func (sd Drive) Interp(t float64) float64

func (Drive) IsOff

func (sd Drive) IsOff() bool

func (Drive) Off

func (sd Drive) Off()

func (Drive) On

func (sd Drive) On()

func (*Drive) Prepare

func (drv *Drive) Prepare(uint64)

func (Drive) SampleRate

func (sd Drive) SampleRate() float64

func (Drive) Samples

func (sd Drive) Samples() Discrete

type Freeze

type Freeze struct {
	// contains filtered or unexported fields
}

func NewFreeze

func NewFreeze(d time.Duration, in Sound) *Freeze

func (Freeze) At

func (sd Freeze) At(t float64) float64

func (Freeze) Channels

func (sd Freeze) Channels() int

func (Freeze) Index

func (sd Freeze) Index(i int) float64

func (Freeze) Inputs

func (sd Freeze) Inputs() []Sound

func (Freeze) Interp

func (sd Freeze) Interp(t float64) float64

func (Freeze) IsOff

func (sd Freeze) IsOff() bool

func (*Freeze) Off

func (frz *Freeze) Off()

func (Freeze) On

func (sd Freeze) On()

func (*Freeze) Prepare

func (frz *Freeze) Prepare(uint64)

func (*Freeze) Restart

func (frz *Freeze) Restart()

func (Freeze) SampleRate

func (sd Freeze) SampleRate() float64

func (Freeze) Samples

func (sd Freeze) Samples() Discrete

type Gain

type Gain struct {
	// contains filtered or unexported fields
}

func NewGain

func NewGain(a float64, in Sound) *Gain

func (Gain) At

func (sd Gain) At(t float64) float64

func (Gain) Channels

func (sd Gain) Channels() int

func (Gain) Index

func (sd Gain) Index(i int) float64

func (Gain) Inputs

func (sd Gain) Inputs() []Sound

func (Gain) Interp

func (sd Gain) Interp(t float64) float64

func (Gain) IsOff

func (sd Gain) IsOff() bool

func (Gain) Off

func (sd Gain) Off()

func (Gain) On

func (sd Gain) On()

func (*Gain) Prepare

func (gn *Gain) Prepare(uint64)

func (Gain) SampleRate

func (sd Gain) SampleRate() float64

func (Gain) Samples

func (sd Gain) Samples() Discrete

func (*Gain) SetAmp

func (gn *Gain) SetAmp(a float64)

type Hertz

type Hertz float64

Hertz is defined as cycles per second and is synonymous with frequency.

func (Hertz) Angular

func (hz Hertz) Angular() float64

Angular returns the angular frequency as 2 * pi * hz and is synonymous with radians.

func (Hertz) Normalized

func (hz Hertz) Normalized(sr float64) float64

Normalized returns the angular frequency of hz divided by the sample rate sr.

func (Hertz) Period

func (hz Hertz) Period() float64

func (Hertz) String

func (hz Hertz) String() string

type Input

type Input struct {
	// contains filtered or unexported fields
}

func GetInputs

func GetInputs(sd Sound) []*Input

type Instrument

type Instrument struct {
	// contains filtered or unexported fields
}

func NewInstrument

func NewInstrument(in Sound) *Instrument

func (Instrument) At

func (sd Instrument) At(t float64) float64

func (Instrument) Channels

func (sd Instrument) Channels() int

func (Instrument) Index

func (sd Instrument) Index(i int) float64

func (Instrument) Inputs

func (sd Instrument) Inputs() []Sound

func (Instrument) Interp

func (sd Instrument) Interp(t float64) float64

func (Instrument) IsOff

func (sd Instrument) IsOff() bool

func (Instrument) Off

func (sd Instrument) Off()

func (*Instrument) OffIn

func (nst *Instrument) OffIn(d time.Duration)

func (*Instrument) On

func (nst *Instrument) On()

func (*Instrument) Prepare

func (nst *Instrument) Prepare(uint64)

func (Instrument) SampleRate

func (sd Instrument) SampleRate() float64

func (Instrument) Samples

func (sd Instrument) Samples() Discrete

type Loop

type Loop struct {
	// contains filtered or unexported fields
}

Loop records a signal by a given duration, repeating the recording in subsequent playback.

TODO cross-fade

func NewLoop

func NewLoop(d time.Duration, in Sound) *Loop

NewLoop returns a Loop with sample buffer of a length approximated by d.

func NewLoopFrames

func NewLoopFrames(nframes int, in Sound) *Loop

NewLoopFrames return a Loop with sample buffer of length nframes.

func (Loop) At

func (sd Loop) At(t float64) float64

func (Loop) Channels

func (sd Loop) Channels() int

func (Loop) Index

func (sd Loop) Index(i int) float64

func (Loop) Inputs

func (sd Loop) Inputs() []Sound

func (Loop) Interp

func (sd Loop) Interp(t float64) float64

func (Loop) IsOff

func (sd Loop) IsOff() bool

func (Loop) Off

func (sd Loop) Off()

func (Loop) On

func (sd Loop) On()

func (*Loop) Prepare

func (lp *Loop) Prepare(tc uint64)

func (*Loop) Record

func (lp *Loop) Record()

func (*Loop) Recording

func (lp *Loop) Recording() bool

func (Loop) SampleRate

func (sd Loop) SampleRate() float64

func (Loop) Samples

func (sd Loop) Samples() Discrete

func (*Loop) SetBPM

func (lp *Loop) SetBPM(bpm BPM)

func (*Loop) Stop

func (lp *Loop) Stop()

func (*Loop) Syncing

func (lp *Loop) Syncing() bool

type LowPass

type LowPass struct {
	// contains filtered or unexported fields
}

LowPass is a 3rd order IIR filter.

Recursive implementation of the Gaussian filter.

func NewLowPass

func NewLowPass(freq float64, in Sound) *LowPass

func (LowPass) At

func (sd LowPass) At(t float64) float64

func (LowPass) Channels

func (sd LowPass) Channels() int

func (LowPass) Index

func (sd LowPass) Index(i int) float64

func (LowPass) Inputs

func (sd LowPass) Inputs() []Sound

func (LowPass) Interp

func (sd LowPass) Interp(t float64) float64

func (LowPass) IsOff

func (sd LowPass) IsOff() bool

func (LowPass) Off

func (sd LowPass) Off()

func (LowPass) On

func (sd LowPass) On()

func (*LowPass) Passthrough

func (lp *LowPass) Passthrough() bool

func (*LowPass) Prepare

func (lp *LowPass) Prepare(uint64)

func (LowPass) SampleRate

func (sd LowPass) SampleRate() float64

func (LowPass) Samples

func (sd LowPass) Samples() Discrete

func (*LowPass) SetPassthrough

func (lp *LowPass) SetPassthrough(b bool)

type Mixer

type Mixer struct {
	// contains filtered or unexported fields
}

TODO should mixer be stereo out? TODO perhaps this class is unnecessary, any sound could be a mixer if you can set multiple inputs, but might get confusing. TODO consider embedding Gain type

func NewMixer

func NewMixer(ins ...Sound) *Mixer

func (*Mixer) Append

func (mix *Mixer) Append(s ...Sound)

func (Mixer) At

func (sd Mixer) At(t float64) float64

func (Mixer) Channels

func (sd Mixer) Channels() int

func (*Mixer) Empty

func (mix *Mixer) Empty()

func (Mixer) Index

func (sd Mixer) Index(i int) float64

func (*Mixer) Inputs

func (mix *Mixer) Inputs() []Sound

func (Mixer) Interp

func (sd Mixer) Interp(t float64) float64

func (Mixer) IsOff

func (sd Mixer) IsOff() bool

func (Mixer) Off

func (sd Mixer) Off()

func (Mixer) On

func (sd Mixer) On()

func (*Mixer) Prepare

func (mix *Mixer) Prepare(uint64)

func (Mixer) SampleRate

func (sd Mixer) SampleRate() float64

func (Mixer) Samples

func (sd Mixer) Samples() Discrete

type Notes

type Notes []float64

Notes is a collection of note function evaluations.

func EqualTempermant

func EqualTempermant(tones int, freq float64, pos int) Notes

EqualTempermant is a helper function for returning an evaluated Notes.

func (*Notes) Eval

func (ns *Notes) Eval(tones int, freq float64, pos int, fn NotesFunc)

Eval evaluates fn over the length of ns. If ns is nil, ns will be allocated with length DefaultNotesLen.

type NotesFunc

type NotesFunc func(ns Notes, tones int, freq float64, pos int)

NotesFunc defines a note function to be evaluated over the length of ns.

type Oscil

type Oscil struct {
	// contains filtered or unexported fields
}

func NewOscil

func NewOscil(in Discrete, freq float64, freqmod Sound) *Oscil

func (Oscil) At

func (sd Oscil) At(t float64) float64

func (Oscil) Channels

func (sd Oscil) Channels() int

func (Oscil) Index

func (sd Oscil) Index(i int) float64

func (*Oscil) Inputs

func (osc *Oscil) Inputs() []Sound

func (Oscil) Interp

func (sd Oscil) Interp(t float64) float64

func (Oscil) IsOff

func (sd Oscil) IsOff() bool

func (Oscil) Off

func (sd Oscil) Off()

func (Oscil) On

func (sd Oscil) On()

func (*Oscil) Prepare

func (osc *Oscil) Prepare(tc uint64)

func (Oscil) SampleRate

func (sd Oscil) SampleRate() float64

func (Oscil) Samples

func (sd Oscil) Samples() Discrete

func (*Oscil) SetAmp

func (osc *Oscil) SetAmp(fac float64, mod Sound)

func (*Oscil) SetFreq

func (osc *Oscil) SetFreq(hz float64, mod Sound)

func (*Oscil) SetPhase

func (osc *Oscil) SetPhase(mod Sound)

type Pan

type Pan struct {
	// contains filtered or unexported fields
}

func NewPan

func NewPan(xf float64, in Sound) *Pan

func (Pan) At

func (sd Pan) At(t float64) float64

func (Pan) Channels

func (sd Pan) Channels() int

func (Pan) Index

func (sd Pan) Index(i int) float64

func (Pan) Inputs

func (sd Pan) Inputs() []Sound

func (Pan) Interp

func (sd Pan) Interp(t float64) float64

func (Pan) IsOff

func (sd Pan) IsOff() bool

func (Pan) Off

func (sd Pan) Off()

func (Pan) On

func (sd Pan) On()

func (*Pan) Prepare

func (pan *Pan) Prepare(uint64)

Prepare interleaves the left and right channels.

func (Pan) SampleRate

func (sd Pan) SampleRate() float64

func (Pan) Samples

func (sd Pan) Samples() Discrete

func (*Pan) SetAmount

func (pan *Pan) SetAmount(xf float64)

SetAmount sets amount an input is panned across two outputs where amt belongs to [-1..1].

type Ring

type Ring struct {
	// contains filtered or unexported fields
}

Ring modulator

func NewRing

func NewRing(in0, in1 Sound) *Ring

func (Ring) At

func (sd Ring) At(t float64) float64

func (Ring) Channels

func (sd Ring) Channels() int

func (Ring) Index

func (sd Ring) Index(i int) float64

func (*Ring) Inputs

func (ng *Ring) Inputs() []Sound

func (Ring) Interp

func (sd Ring) Interp(t float64) float64

func (Ring) IsOff

func (sd Ring) IsOff() bool

func (Ring) Off

func (sd Ring) Off()

func (Ring) On

func (sd Ring) On()

func (*Ring) Prepare

func (ng *Ring) Prepare(uint64)

func (Ring) SampleRate

func (sd Ring) SampleRate() float64

func (Ring) Samples

func (sd Ring) Samples() Discrete

type Sampler

type Sampler interface {
	// Sample reads values from src at phase by interval and returns next phase to sample.
	//
	// The side effect resulting from sampling is implementation specific.
	Sample(src Continuous, interval, phase float64) float64
}

type Sound

type Sound interface {

	// Channels returns the frame size in samples of the internal buffer.
	Channels() int

	// SampleRate returns the number of digital samples of sound pressure per second.
	SampleRate() float64

	// Prepare is when a sound should prepare sample frames.
	Prepare(uint64)

	// Inputs should return all inputs a Sound wants discovered by a dispatcher.
	// TODO consider other methods for handling this, check book multidimensional data structures
	Inputs() []Sound

	// Samples returns prepared samples slice.
	//
	// TODO maybe ditch this, point of architecture is you can't mess
	// with an input's output but a slice exposes that. Or, discourage
	// use by making a copy of data.
	// TODO rename to Data()? So, Buffer.Data()
	Samples() Discrete

	Interp(t float64) float64

	At(t float64) float64

	Index(i int) float64
}

TODO rename as Buffer? TODO what about handling []byte instead of []float? Sound represents a type capable of producing sound data.

type Tap

type Tap struct {
	// contains filtered or unexported fields
}

Tap is a tapped delay line, essentially a shorter delay within a larger one.

TODO consider some type of method on Delay instead of a separate type. For example, Tap intentionally does not expose dly via Inputs() so why is it its own type? Conversely, that'd make Delay a mixer of sorts.

func NewTap

func NewTap(d time.Duration, in *Delay) *Tap

func (Tap) At

func (sd Tap) At(t float64) float64

func (Tap) Channels

func (sd Tap) Channels() int

func (Tap) Index

func (sd Tap) Index(i int) float64

func (Tap) Inputs

func (sd Tap) Inputs() []Sound

func (Tap) Interp

func (sd Tap) Interp(t float64) float64

func (Tap) IsOff

func (sd Tap) IsOff() bool

func (Tap) Off

func (sd Tap) Off()

func (Tap) On

func (sd Tap) On()

func (*Tap) Prepare

func (tap *Tap) Prepare(uint64)

func (Tap) SampleRate

func (sd Tap) SampleRate() float64

func (Tap) Samples

func (sd Tap) Samples() Discrete

Directories

Path Synopsis
example
exp