-
Notifications
You must be signed in to change notification settings - Fork 1
/
Modulators.swift
69 lines (54 loc) · 1.28 KB
/
Modulators.swift
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
//
// Modulators.swift
// GrainSwift
//
// Created by lucas kuzma on 1/20/21.
//
import Foundation
protocol Modulator {
var level: Double { get }
mutating func reset()
mutating func step()
var hold: Bool { get set }
}
protocol Envelope: Modulator {
mutating func release()
}
enum EnvelopeStage {
case attack
case sustain
case decay
case release
}
struct ASREnvelope: Envelope {
var hold: Bool = false {
willSet {
level = newValue ? 1.0 : 0.0
}
}
public var attackTime = 0.0
public var releaseTime = 0.0
var offset = 0.0
var level = 0.0
var stage = EnvelopeStage.decay
mutating func reset() {
offset = 0
stage = .attack
}
mutating func release() {
offset = 0
stage = .release
}
mutating func step() {
guard !hold else { return }
if stage == .attack {
level = attackTime > 0 ? min(offset / attackTime, 1) : 1
if offset >= attackTime {
stage = .sustain
}
} else if stage == .release && level > 0.0 {
level = releaseTime > 0 ? min((releaseTime - offset) / releaseTime, 1) : 0
}
offset += 1
}
}