-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathaudio.go
71 lines (59 loc) · 1.29 KB
/
audio.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
package chip8
import "C"
import (
"math"
"github.com/gordonklaus/portaudio"
)
const sampleRate = 44100
func NewAudioController() *AudioController {
portaudio.Initialize()
s := newStereoSine(256, 320, sampleRate)
return &AudioController{
stereoSine: s,
}
}
type AudioController struct {
stereoSine *stereoSine
isOn bool
}
func (a *AudioController) Destroy() {
portaudio.Terminate()
a.stereoSine.Close()
}
func (a *AudioController) Start() {
if !a.isOn {
a.isOn = true
chk(a.stereoSine.Start())
}
}
func (a *AudioController) Stop() {
if a.isOn {
a.isOn = false
chk(a.stereoSine.Stop())
}
}
type stereoSine struct {
*portaudio.Stream
stepL, phaseL float64
stepR, phaseR float64
}
func newStereoSine(freqL, freqR, sampleRate float64) *stereoSine {
s := &stereoSine{nil, freqL / sampleRate, 0, freqR / sampleRate, 0}
var err error
s.Stream, err = portaudio.OpenDefaultStream(0, 2, sampleRate, 0, s.processAudio)
chk(err)
return s
}
func (g *stereoSine) processAudio(out [][]float32) {
for i := range out[0] {
out[0][i] = float32(math.Sin(2 * math.Pi * g.phaseL))
_, g.phaseL = math.Modf(g.phaseL + g.stepL)
out[1][i] = float32(math.Sin(2 * math.Pi * g.phaseR))
_, g.phaseR = math.Modf(g.phaseR + g.stepR)
}
}
func chk(err error) {
if err != nil {
panic(err)
}
}