-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
/
AKPlayer+Fader.swift
114 lines (96 loc) · 3.84 KB
/
AKPlayer+Fader.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
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
//
// AKPlayer+Fader.swift
// AudioKit
//
// Created by Ryan Francesconi on 6/12/18.
// Copyright © 2018 AudioKit. All rights reserved.
//
/// The Fader is also used for the gain stage of the player
extension AKPlayer {
internal func createFader() {
// AKLog("Creating fader AKBooster")
faderNode = AKBooster()
faderNode?.gain = gain
faderNode?.rampType = rampType
initialize()
}
internal func initFader(at audioTime: AVAudioTime?, hostTime: UInt64?) {
guard faderNode != nil else { return }
// AKLog(fade, faderNode.rampDuration, faderNode.gain, audioTime, hostTime)
guard fade.inTime != 0 || fade.outTime != 0 else {
return
}
guard let hostTime = hostTime, var triggerTime = audioTime?.toSeconds(hostTime: hostTime) else {
startFade()
return
}
triggerTime /= rate
// AKLog("starting fade in", triggerTime, "seconds")
DispatchQueue.main.async {
self.faderTimer?.invalidate()
self.faderTimer = Timer.scheduledTimer(timeInterval: triggerTime,
target: self,
selector: #selector(self.startFade),
userInfo: nil,
repeats: false)
}
}
internal func resetFader(_ state: Bool) {
guard let faderNode = faderNode else { return }
var state = state
if fade.inTime == 0 {
state = true
}
faderNode.rampType = fade.inRampType
faderNode.rampDuration = AKSettings.rampDuration
faderNode.gain = state ? fade.maximumGain : Fade.minimumGain
}
@objc private func startFade() {
guard let faderNode = faderNode else { return }
let inTime = fade.inTime - fade.inTimeOffset
// AKLog("Fading in to", fade.maximumGain, ", shape:", fade.inRampType.rawValue)
faderNode.rampDuration = AKSettings.rampDuration
if inTime > 0 {
faderNode.gain = Fade.minimumGain
faderNode.rampDuration = inTime / rate
}
// set target gain and begin ramping
faderNode.gain = fade.maximumGain
faderTimer?.invalidate()
guard fade.outTime > 0 else { return }
if fade.outTimeOffset > 0 {
// just fade now the remainder of the segment
var midFadeDuration = duration - startTime
if endTime < duration {
midFadeDuration -= (duration - endTime)
}
fadeOutWithTime(midFadeDuration)
} else {
var when = (duration - startTime) - (duration - endTime) - fade.outTime
when /= rate
DispatchQueue.main.async {
self.faderTimer?.invalidate()
self.faderTimer = Timer.scheduledTimer(timeInterval: when,
target: self,
selector: #selector(self.fadeOut),
userInfo: nil,
repeats: false)
}
}
}
@objc private func fadeOut() {
if fade.outTime > 0 {
fadeOutWithTime(fade.outTime)
}
}
@objc internal func fadeOutWithTime(_ time: Double) {
guard let faderNode = faderNode else { return }
if time > 0 {
// at this point init the faderNode with the correct settings for fade out
faderNode.rampType = fade.outRampType
faderNode.rampDuration = time / rate
faderNode.gain = Fade.minimumGain
// AKLog("Fading out to", Fade.minimumGain, ", shape:", fade.outRampType.rawValue)
}
}
}