-
Notifications
You must be signed in to change notification settings - Fork 4
/
freeze.go
82 lines (68 loc) · 1.34 KB
/
freeze.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
package snd
import (
"math"
"time"
"dasa.cc/signal"
)
type Freeze struct {
*mono
sig, prv signal.Discrete
r int
}
func NewFreeze(d time.Duration, in Sound) *Freeze {
f := Dtof(d, in.SampleRate())
n := f
if n == 0 || n&(n-1) != 0 {
_, e := math.Frexp(float64(n))
n = int(math.Ldexp(1, e))
}
frz := &Freeze{mono: newmono(nil), prv: make(signal.Discrete, n)}
frz.sig = frz.prv[:f]
inps := GetInputs(in)
dp := new(Dispatcher)
// t := time.Now()
buflen := len(in.Samples())
for i := 0; i < n; i += buflen {
dp.Dispatch(1, inps...)
ringcopy(frz.sig[i:i+buflen], in.Samples(), 0)
}
// log.Println("freeze took", time.Now().Sub(t))
return frz
}
func (frz *Freeze) Restart() { frz.r = 0 }
var empty = make([]float64, 256)
func ringcopy(dst, src []float64, r int) int {
dn, sn := len(dst), len(src)
for w := 0; w < dn; {
x := copy(dst[w:], src[r:])
w += x
r += x
if r == sn {
r = 0
}
}
return r
}
func (frz *Freeze) Off() {
frz.mono.Off()
copy(frz.out, empty)
}
func (frz *Freeze) Prepare(uint64) {
if frz.off {
n := len(frz.out)
frz.r = (frz.r + n) & (n - 1)
} else {
frz.r = ringcopy(frz.out, frz.sig, frz.r)
}
// for i := range frz.out {
// if frz.off {
// frz.out[i] = 0
// } else {
// frz.out[i] = frz.sig[frz.pos]
// frz.pos++
// if frz.pos == frz.nfr {
// frz.pos = 0
// }
// }
// }
}