-
Notifications
You must be signed in to change notification settings - Fork 13
/
panning.go
68 lines (60 loc) · 1.66 KB
/
panning.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
package derived
import (
"math"
"github.com/bspaans/bleep/audio"
"github.com/bspaans/bleep/generators"
"github.com/bspaans/bleep/theory"
)
func NewPitchControlledPanningGenerator(g generators.Generator) generators.Generator {
result := NewWrappedGenerator(g)
minPitch := theory.NoteToPitch[theory.C1]
maxPitch := theory.NoteToPitch[theory.A7]
maxPitchLog2 := math.Log2(maxPitch)
pitch := 0.0
result.GetSamplesFunc = func(cfg *audio.AudioConfig, n int) []float64 {
if !cfg.Stereo {
return g.GetSamples(cfg, n)
}
samples := g.GetSamples(cfg, n)
panning := 0.5
if pitch < minPitch {
panning = 0.0
} else if pitch > maxPitch {
panning = 1.0
} else {
panning = math.Log2(pitch) / maxPitchLog2
}
result := generators.GetEmptySampleArray(cfg, n)
for i := 0; i < n; i++ {
v1, v2 := SinusoidalPanning(samples[i*2], samples[i*2+1], panning)
result[i*2] = v1
result[i*2+1] = v2
}
return samples
}
result.SetPitchFunc = func(f float64) {
pitch = f
g.SetPitch(f)
}
return result
}
func LinearPanning(input1, input2, panning float64) (float64, float64) {
left := input1*(1-panning) + input2*(1-panning)
right := input1*panning + input2*panning
return left, right
}
func SquareRootPanning(input1, input2, panning float64) (float64, float64) {
pan1 := math.Sqrt(1 - panning)
pan2 := math.Sqrt(panning)
left := input1*pan1 + input2*pan1
right := input1*pan2 + input2*pan2
return left, right
}
func SinusoidalPanning(input1, input2, panning float64) (float64, float64) {
panning *= math.Pi / 2
pan1 := math.Cos(panning)
pan2 := math.Sin(panning)
left := input1*pan1 + input2*pan1
right := input1*pan2 + input2*pan2
return left, right
}