Documentation ¶
Index ¶
- Constants
- func AddDecorator(decorator Decorator)
- func SampleRate() int
- func SetSampleRate(rate int)
- type Context
- type ContextOptions
- type Decorator
- type Time
- func (t Time) After(t2 Time) bool
- func (t Time) Before(t2 Time) bool
- func (t Time) Decrement() Time
- func (t Time) Duration(t2 Time) time.Duration
- func (t Time) Empty() bool
- func (t Time) Equal(t2 Time) bool
- func (t Time) Increment() Time
- func (t Time) Sample() int
- func (t Time) SampleRate() int
- func (t Time) Second() int
- func (t Time) ShiftBy(samples int) Time
- func (t Time) String() string
Examples ¶
Constants ¶
const (
// DefaultSampleRate is the default number of samples output per second (Hz).
DefaultSampleRate = 44_100
)
Variables ¶
This section is empty.
Functions ¶
func AddDecorator ¶
func AddDecorator(decorator Decorator)
AddDecorator adds a decorator to the list of decorators. These are run in the order they are added when setting up a new context. This allows for adding additional data to a context as it's created.
Example ¶
package main import ( "fmt" "github.com/green-aloe/enobox/context" ) func main() { type ctxKey struct{} var minFreqKey ctxKey context.AddDecorator(func(ctx context.Context) context.Context { return ctx.WithValue(minFreqKey, 22.22) }) ctx := context.NewContext() minFreq := ctx.Value(minFreqKey) fmt.Println(minFreq) }
Output: 22.22
func SampleRate ¶
func SampleRate() int
SampleRate returns the global sample rate.
Example ¶
package main import ( "fmt" "github.com/green-aloe/enobox/context" ) func main() { sampleRate := context.SampleRate() fmt.Println(sampleRate) }
Output: 44100
func SetSampleRate ¶
func SetSampleRate(rate int)
SetSampleRate sets the global sample rate (number of samples per second (Hz) in the output). The rate must be greater than zero.
Example ¶
package main import ( "fmt" "github.com/green-aloe/enobox/context" ) func main() { defer context.SetSampleRate(context.DefaultSampleRate) sampleRate1 := context.SampleRate() context.SetSampleRate(48_000) sampleRate2 := context.SampleRate() fmt.Println(sampleRate1, sampleRate2) }
Output: 44100 48000
Types ¶
type Context ¶
type Context interface { gocontext.Context WithValue(key, value any) Context Time() Time SetTime(time Time) SampleRate() int NyqistFrequency() float32 }
A Context holds the context for a single sample of audio.
func NewContext ¶
func NewContext() Context
NewContext sets up and returns a context for a single sample of audio using default/global values.
Example ¶
package main import ( "fmt" "github.com/green-aloe/enobox/context" ) func main() { ctx := context.NewContext() time := ctx.Time() sampleRate := ctx.SampleRate() fmt.Println(time) fmt.Println(sampleRate) }
Output: 0 seconds, sample 1/44100 44100
func NewContextWith ¶
func NewContextWith(options ContextOptions) Context
NewContextWith sets up and returns a context for a single sample of audio using the options provided. If a necessary option is not set, the default/global value is used. Any decorators provided are run after the global decorators set with AddDecorator.
Example ¶
package main import ( gocontext "context" "fmt" "github.com/green-aloe/enobox/context" ) func main() { ctx := context.NewContextWith(context.ContextOptions{}) time := ctx.Time() sampleRate := ctx.SampleRate() value := ctx.Value("key") fmt.Println(time) fmt.Println(sampleRate) fmt.Println(value) ctx = context.NewContextWith(context.ContextOptions{ Context: gocontext.WithoutCancel(gocontext.Background()), Time: context.NewTimeWith(35_000).ShiftBy(400), SampleRate: 35_000, Decorators: []context.Decorator{ func(ctx context.Context) context.Context { return ctx.WithValue("key", "value") }, }, }) time = ctx.Time() sampleRate = ctx.SampleRate() value = ctx.Value("key") fmt.Println(time) fmt.Println(sampleRate) fmt.Println(value) }
Output: 0 seconds, sample 1/44100 44100 <nil> 0 seconds, sample 401/35000 35000 value
func NewTestContext ¶
func NewTestContext() Context
NewTestContext returns an empty, non-nil context that does not have any default values set. It returns nil if not called from a test. This is meant for testing purposes only.
Example ¶
package main import ( "fmt" "github.com/green-aloe/enobox/context" ) func main() { ctx := context.NewTestContext() time := ctx.Time() sampleRate := ctx.SampleRate() fmt.Println(time) fmt.Println(sampleRate) }
Output: invalid time: 0 seconds, sample 0/0 0
type ContextOptions ¶
type ContextOptions struct { Context gocontext.Context Time Time SampleRate int Decorators []Decorator }
ContextOptions is the set of configurations that can be used when building a new custom context.
type Time ¶
type Time struct {
// contains filtered or unexported fields
}
Time is a timestamp of a single sample of audio data.
func NewTime ¶
func NewTime() Time
NewTime returns a timestamp with the lowest value. It uses the global sample rate to know how many samples are in one second.
Example ¶
package main import ( "fmt" "github.com/green-aloe/enobox/context" ) func main() { time := context.NewTime() fmt.Println(time) }
Output: 0 seconds, sample 1/44100
func NewTimeAt ¶
NewTimeAt returns a timestamp with the provided data. It panics if second is less than 0, sample is less than 1, or sample is greater than sampleRate.
Example ¶
package main import ( "fmt" "github.com/green-aloe/enobox/context" ) func main() { time := context.NewTimeAt(3, 25, context.DefaultSampleRate) fmt.Println(time) }
Output: 3 seconds, sample 25/44100
func NewTimeWith ¶
NewTimeWith returns a timestamp with the lowest value. It uses the provided sample rate to know how many samples are in one second.
Example ¶
package main import ( "fmt" "github.com/green-aloe/enobox/context" ) func main() { time := context.NewTimeWith(48_000) fmt.Println(time) }
Output: 0 seconds, sample 1/48000
func (Time) After ¶
After returns true if t represents a time that is later/higher than t2 does. This returns false if the timestamps do not have the same sample rate.
Example ¶
package main import ( "fmt" "github.com/green-aloe/enobox/context" ) func main() { time1 := context.NewTime() time2 := context.NewTime() after1a := time1.After(time2) after1b := time2.After(time1) time2 = time2.Increment() after2a := time1.After(time2) after2b := time2.After(time1) fmt.Println(after1a, after1b) fmt.Println(after2a, after2b) }
Output: false false false true
func (Time) Before ¶
Before returns true if t represents a time that is earlier/lower than t2 does. This returns false if the timestamps do not have the same sample rate.
Example ¶
package main import ( "fmt" "github.com/green-aloe/enobox/context" ) func main() { time1 := context.NewTime() time2 := context.NewTime() before1a := time1.Before(time2) before1b := time2.Before(time1) time2 = time2.Increment() before2a := time1.Before(time2) before2b := time2.Before(time1) fmt.Println(before1a, before1b) fmt.Println(before2a, before2b) }
Output: false false true false
func (Time) Decrement ¶
Decrement decrements the timestamp by one sample and returns the new timestamp. This does not modify the receiver. The timestamp can never go below 0. This is an alias for t.ShiftBy(-1).
Example ¶
package main import ( "fmt" "github.com/green-aloe/enobox/context" ) func main() { time1 := context.NewTime() fmt.Println(time1) time2 := time1.ShiftBy(10).Decrement() fmt.Println(time2) // The original time does not change. fmt.Println(time1) }
Output: 0 seconds, sample 1/44100 0 seconds, sample 10/44100 0 seconds, sample 1/44100
func (Time) Duration ¶
Duration calculates the duration between two timestamps to the nearest microsecond. The returned duration is always positive. This returns 0 if the timestamps do not have the same sample rate.
Example ¶
package main import ( "fmt" "github.com/green-aloe/enobox/context" ) func main() { time1 := context.NewTime() time2 := context.NewTime().ShiftBy(context.SampleRate()) duration1 := time1.Duration(time2) duration2 := time2.Duration(time1) fmt.Println(duration1, duration2) }
Output: 1s 1s
func (Time) Equal ¶
Equal returns true if the two timestamps are equal.
Example ¶
package main import ( "fmt" "github.com/green-aloe/enobox/context" ) func main() { time1 := context.NewTime() time2 := context.NewTime() isEqual1 := time1.Equal(time2) time2 = time2.Increment() isEqual2 := time1.Equal(time2) fmt.Println(isEqual1, isEqual2) }
Output: true false
func (Time) Increment ¶
Increment increments the timestamp by one sample and returns the new timestamp. This does not modify the receiver. This is an alias for t.ShiftBy(1).
Example ¶
package main import ( "fmt" "github.com/green-aloe/enobox/context" ) func main() { time1 := context.NewTime() fmt.Println(time1) time2 := time1.Increment() fmt.Println(time2) // The original time does not change. fmt.Println(time1) }
Output: 0 seconds, sample 1/44100 0 seconds, sample 2/44100 0 seconds, sample 1/44100
func (Time) Sample ¶
Sample returns the sample number in the current second. For example, if the generator is playing the 14th sample of the 4th second, then Sample will return 14 and Second will return 3.
This field is 1-based, i.e. the first sample is 1, the second sample is 2, etc. This value can never exceed the global sample rate.
Example ¶
package main import ( "fmt" "github.com/green-aloe/enobox/context" ) func main() { time := context.NewTime() sample := time.Sample() fmt.Println(sample) }
Output: 1
func (Time) SampleRate ¶
SampleRate returns the number of samples in one second.
func (Time) Second ¶
Second returns the number of complete seconds that have elapsed so far. For example, if three seconds have elapsed and the generator is on the fourth second of audio data, then Second will return 3.
Example ¶
package main import ( "fmt" "github.com/green-aloe/enobox/context" ) func main() { time := context.NewTime() second := time.Second() fmt.Println(second) }
Output: 0
func (Time) ShiftBy ¶
ShiftBy shifts the timestamp by the number of samples and returns the new timestamp. This does not modify the receiver. The number of samples can be positive or negative.
Example ¶
package main import ( "fmt" "github.com/green-aloe/enobox/context" ) func main() { time1 := context.NewTime() fmt.Println(time1) time2 := time1.ShiftBy(context.SampleRate() + 100) fmt.Println(time2) // The original time does not change. fmt.Println(time1) }
Output: 0 seconds, sample 1/44100 1 second, sample 101/44100 0 seconds, sample 1/44100
func (Time) String ¶
String returns the human-readable representation of t.
Example ¶
package main import ( "fmt" "github.com/green-aloe/enobox/context" ) func main() { time1 := context.NewTime() time2 := time1.ShiftBy(context.SampleRate()).ShiftBy(100) time3 := time2.ShiftBy(context.SampleRate()).ShiftBy(100) fmt.Println(time1) fmt.Println(time2) fmt.Println(time3) }
Output: 0 seconds, sample 1/44100 1 second, sample 101/44100 2 seconds, sample 201/44100