-
Notifications
You must be signed in to change notification settings - Fork 13
/
generator.go
94 lines (80 loc) · 2.09 KB
/
generator.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// Generate audio samples
package generators
import (
"github.com/bspaans/bleep/audio"
)
type Generator interface {
// GetSamples is the meat of each Generator and returns `n` samples.
//
// There are two important variables in cfg that should be considered:
// * cfg.SampleRate: the number of samples per second; affects pitch
// * cfg.Stereo: whether or not the output is stereo - should return n*2 samples if so
//
// `Pitch`, `PitchbendFactor` and `Gain` can in theory all be ignored
// (see WhiteNoiseGenerator for one such generator).
//
GetSamples(cfg *audio.AudioConfig, n int) []float64 // return samples between -1.0 and 1.0
SetPitch(float64)
SetPitchbend(float64)
SetGain(float64)
}
type BaseGenerator struct {
Pitch float64
PitchbendFactor float64
Gain float64
Phase int // needs to be updated from GetSamplesFunc
GetSamplesFunc func(cfg *audio.AudioConfig, n int) []float64
SetPitchFunc func(float64)
}
func NewBaseGenerator() *BaseGenerator {
return &BaseGenerator{
Pitch: 440.0,
Gain: 1.0,
PitchbendFactor: 0.0,
}
}
func (s *BaseGenerator) GetPitch() float64 {
if s.PitchbendFactor == 0.0 {
return s.Pitch
}
return s.Pitch * s.PitchbendFactor
}
func (s *BaseGenerator) GetSamples(cfg *audio.AudioConfig, n int) []float64 {
if s.GetSamplesFunc == nil {
return GetEmptySampleArray(cfg, n)
}
return s.GetSamplesFunc(cfg, n)
}
func (s *BaseGenerator) SetPitch(f float64) {
if s.SetPitchFunc != nil {
s.SetPitchFunc(f)
} else {
s.Pitch = f
}
}
func (s *BaseGenerator) SetGain(f float64) {
s.Gain = f
}
func (s *BaseGenerator) SetPitchbend(f float64) {
s.PitchbendFactor = f
}
func (g *BaseGenerator) IncrementPhase(waveLength int) {
if g.Phase == MaxInt {
g.Phase = MaxInt % waveLength
}
g.Phase++
}
func SetResult(cfg *audio.AudioConfig, result []float64, i int, v float64) {
if !cfg.Stereo {
result[i] = v
} else {
result[i*2] = v
result[i*2+1] = v
}
}
func GetEmptySampleArray(cfg *audio.AudioConfig, n int) []float64 {
if cfg.Stereo {
return make([]float64, n*2)
}
return make([]float64, n)
}