/
Recorder.swift
89 lines (80 loc) · 2.11 KB
/
Recorder.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
import AudioKit
import AudioKitEX
import AudioKitUI
import AVFoundation
import SwiftUI
struct RecorderData {
var isRecording = false
var isPlaying = false
}
class RecorderConductor: ObservableObject, HasAudioEngine {
let engine = AudioEngine()
var recorder: NodeRecorder?
let player = AudioPlayer()
var silencer: Fader?
let mixer = Mixer()
@Published var data = RecorderData() {
didSet {
if data.isRecording {
do {
try recorder?.record()
} catch let err {
print(err)
}
} else {
recorder?.stop()
}
if data.isPlaying {
if let file = recorder?.audioFile {
try? player.load(file: file)
player.play()
}
} else {
player.stop()
}
}
}
init() {
guard let input = engine.input else {
fatalError()
}
do {
recorder = try NodeRecorder(node: input)
} catch let err {
fatalError("\(err)")
}
let silencer = Fader(input, gain: 0)
self.silencer = silencer
mixer.addInput(silencer)
mixer.addInput(player)
engine.output = mixer
}
}
struct RecorderView: View {
@StateObject var conductor = RecorderConductor()
var body: some View {
VStack {
Spacer()
Text(conductor.data.isRecording ? "STOP RECORDING" : "RECORD")
.foregroundColor(.blue)
.onTapGesture {
conductor.data.isRecording.toggle()
}
Spacer()
Text(conductor.data.isPlaying ? "STOP" : "PLAY")
.foregroundColor(.blue)
.onTapGesture {
conductor.data.isPlaying.toggle()
}
Spacer()
}
.padding()
.cookbookNavBarTitle("Recorder")
.onAppear {
conductor.start()
}
.onDisappear {
conductor.stop()
}
}
}