Skip to content

Commit 86f829c

Browse files
Merge pull request #175 from NickCulbertson/Vocoder
Vocoder & Talkbox recipes added
2 parents 1b2cf4a + f0ffa97 commit 86f829c

File tree

4 files changed

+141
-1
lines changed

4 files changed

+141
-1
lines changed

Cookbook/CookbookCommon/Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ let package = Package(
1313
.package(url: "https://github.com/AudioKit/Controls", from: "1.0.0"),
1414
.package(url: "https://github.com/AudioKit/DunneAudioKit", from: "5.6.0"),
1515
.package(url: "https://github.com/AudioKit/Keyboard", from: "1.3.0"),
16-
.package(url: "https://github.com/AudioKit/SoundpipeAudioKit", from: "5.6.0"),
16+
.package(url: "https://github.com/AudioKit/SoundpipeAudioKit", from: "5.7.1"),
1717
.package(url: "https://github.com/AudioKit/SporthAudioKit", from: "5.5.0"),
1818
.package(url: "https://github.com/AudioKit/STKAudioKit", from: "5.5.0"),
1919
.package(url: "https://github.com/AudioKit/Tonic", from: "1.0.0"),

Cookbook/CookbookCommon/Sources/CookbookCommon/ContentView.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,12 @@ struct MasterView: View {
103103
NavigationLink("String Resonator", destination: StringResonatorView())
104104
}
105105
Group {
106+
NavigationLink("Talkbox", destination: TalkboxView())
106107
NavigationLink("Time / Pitch", destination: TimePitchView())
107108
NavigationLink("Transient Shaper", destination: TransientShaperView())
108109
NavigationLink("Tremolo", destination: TremoloView())
109110
NavigationLink("Variable Delay", destination: VariableDelayView())
111+
NavigationLink("Vocoder", destination: VocoderView())
110112
}
111113
}
112114
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import AudioKit
2+
import AudioKitEX
3+
import AudioKitUI
4+
import AVFoundation
5+
import SoundpipeAudioKit
6+
import SwiftUI
7+
import Tonic
8+
9+
class TalkboxConductor: ObservableObject, ProcessesPlayerInput {
10+
let engine = AudioEngine()
11+
let player = AudioPlayer()
12+
let talkbox: Talkbox
13+
let buffer: AVAudioPCMBuffer
14+
var osc = DynamicOscillator()
15+
16+
func noteOn(pitch: Pitch, point _: CGPoint) {
17+
isPlaying = true
18+
osc.frequency = AUValue(pitch.midiNoteNumber).midiNoteToFrequency()
19+
}
20+
21+
func noteOff(pitch _: Pitch) {
22+
isPlaying = false
23+
}
24+
25+
@Published var isPlaying: Bool = false {
26+
didSet { isPlaying ? osc.start() : osc.stop() }
27+
}
28+
29+
init() {
30+
buffer = Cookbook.sourceBuffer
31+
player.buffer = buffer
32+
player.isLooping = true
33+
osc.amplitude = 0.5
34+
35+
talkbox = Talkbox(player, excitation: osc)
36+
engine.output = talkbox
37+
}
38+
}
39+
40+
struct TalkboxView: View {
41+
@StateObject var conductor = TalkboxConductor()
42+
@Environment(\.colorScheme) var colorScheme
43+
44+
var body: some View {
45+
VStack {
46+
PlayerControls(conductor: conductor)
47+
HStack {
48+
ForEach(conductor.talkbox.parameters) {
49+
ParameterRow(param: $0)
50+
}
51+
}
52+
NodeOutputView(conductor.player)
53+
CookbookKeyboard(noteOn: conductor.noteOn,
54+
noteOff: conductor.noteOff)
55+
}
56+
.padding()
57+
.cookbookNavBarTitle("Talkbox")
58+
.onAppear {
59+
conductor.start()
60+
}
61+
.onDisappear {
62+
conductor.stop()
63+
}
64+
.background(colorScheme == .dark ?
65+
Color.clear : Color(red: 0.9, green: 0.9, blue: 0.9))
66+
}
67+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import AudioKit
2+
import AudioKitEX
3+
import AudioKitUI
4+
import AVFoundation
5+
import SoundpipeAudioKit
6+
import SwiftUI
7+
import Tonic
8+
9+
class VocoderConductor: ObservableObject, ProcessesPlayerInput {
10+
let engine = AudioEngine()
11+
let player = AudioPlayer()
12+
let vocoder: Vocoder
13+
let buffer: AVAudioPCMBuffer
14+
var osc = MorphingOscillator(index: 2.5)
15+
16+
func noteOn(pitch: Pitch, point _: CGPoint) {
17+
isPlaying = true
18+
osc.frequency = AUValue(pitch.midiNoteNumber).midiNoteToFrequency()
19+
}
20+
21+
func noteOff(pitch _: Pitch) {
22+
isPlaying = false
23+
}
24+
25+
@Published var isPlaying: Bool = false {
26+
didSet { isPlaying ? osc.start() : osc.stop() }
27+
}
28+
29+
init() {
30+
buffer = Cookbook.sourceBuffer
31+
player.buffer = buffer
32+
player.isLooping = true
33+
osc.amplitude = 0.5
34+
35+
vocoder = Vocoder(player, excitation: osc)
36+
engine.output = vocoder
37+
38+
vocoder.attackTime = 0.001
39+
vocoder.releaseTime = 0.02
40+
vocoder.bandwidthRatio = 0.1
41+
}
42+
}
43+
44+
struct VocoderView: View {
45+
@StateObject var conductor = VocoderConductor()
46+
@Environment(\.colorScheme) var colorScheme
47+
48+
var body: some View {
49+
VStack {
50+
PlayerControls(conductor: conductor)
51+
HStack {
52+
ForEach(conductor.vocoder.parameters) {
53+
ParameterRow(param: $0)
54+
}
55+
}
56+
NodeOutputView(conductor.player)
57+
CookbookKeyboard(noteOn: conductor.noteOn,
58+
noteOff: conductor.noteOff)
59+
}
60+
.padding()
61+
.cookbookNavBarTitle("Vocoder")
62+
.onAppear {
63+
conductor.start()
64+
}
65+
.onDisappear {
66+
conductor.stop()
67+
}
68+
.background(colorScheme == .dark ?
69+
Color.clear : Color(red: 0.9, green: 0.9, blue: 0.9))
70+
}
71+
}

0 commit comments

Comments
 (0)