forked from eugene-eeo/orchid
/
stream.go
100 lines (85 loc) · 1.67 KB
/
stream.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
95
96
97
98
99
100
package liborchid
import (
"sync"
"time"
"github.com/faiface/beep"
"github.com/faiface/beep/effects"
"github.com/faiface/beep/speaker"
)
type VolumeInfo struct {
V float64
Min float64
Max float64
}
func (v VolumeInfo) Volume() float64 {
if v.V > v.Max {
return v.Max
}
if v.V < v.Min {
return v.Min
}
return v.V
}
func (v VolumeInfo) Silent() bool {
return v.V <= v.Min
}
type Stream struct {
stream beep.StreamSeekCloser
format beep.Format
volume *effects.Volume
ctrl *beep.Ctrl
done chan bool
finishOnce sync.Once
}
func NewStream(stream beep.StreamSeekCloser, format beep.Format) *Stream {
volume := &effects.Volume{
Streamer: stream,
Volume: 0,
Base: 2,
Silent: false,
}
return &Stream{
stream: stream,
format: format,
volume: volume,
ctrl: &beep.Ctrl{Streamer: volume},
done: make(chan bool),
}
}
func (s *Stream) finish(completed bool) {
s.finishOnce.Do(func() {
_ = s.stream.Close()
s.done <- completed
})
}
func (s *Stream) Stop() {
s.finish(false)
}
func (s *Stream) Play() {
_ = speaker.Init(s.format.SampleRate, s.format.SampleRate.N(time.Second/10))
speaker.Play(beep.Seq(
s.ctrl,
beep.Callback(func() {
s.finish(true)
}),
))
}
func (s *Stream) Toggle() bool {
speaker.Lock()
defer speaker.Unlock()
s.ctrl.Paused = !s.ctrl.Paused
return s.ctrl.Paused
}
func (s *Stream) Paused() bool {
return s.ctrl.Paused
}
func (s *Stream) Complete() <-chan bool {
return s.done
}
func (s *Stream) SetVolume(v VolumeInfo) {
s.volume.Volume = v.Volume()
s.volume.Silent = v.Silent()
}
func (s *Stream) Progress() float64 {
return float64(s.stream.Position()) / float64(s.stream.Len())
}