Skip to content

Instantly share code, notes, and snippets.

@NickCulbertson
Last active November 2, 2023 21:04
Show Gist options
  • Save NickCulbertson/9873b9142a36cb8090e3af7bf6642643 to your computer and use it in GitHub Desktop.
Save NickCulbertson/9873b9142a36cb8090e3af7bf6642643 to your computer and use it in GitHub Desktop.
Looping audio test with AudioKit using Timer & CADisplayLink
///This loops between two audio files that are two seconds long.
///The audio files are longer than two seconds to include the fade between files
///
///Using CADisplayLink
import AudioKit
import AVFoundation
import SwiftUI
class InstrumentEXSConductor: ObservableObject, HasAudioEngine {
let engine = AudioEngine()
let player1 = AudioPlayer()
let player2 = AudioPlayer()
var loopNumber = 1
var _lastCallTime = NSDate()
var _currentCallTime = NSDate()
var firstPlayer = true
var displayLink: CADisplayLink?
init() {
engine.output = Mixer(player1,player2)
let link = CADisplayLink(target: self, selector: #selector(update))
link.add(to: .main, forMode: .common)
displayLink = link
try! self.player2.load(url: (Bundle.main.resourceURL?.appendingPathComponent("Sounds/loop2.wav"))!,buffered: true)
self.player2.play()
try! self.player1.load(url: (Bundle.main.resourceURL?.appendingPathComponent("Sounds/loop1.wav"))!,buffered: true)
self.player1.play()
player1.stop()
player2.stop()
}
@objc func update() {
_currentCallTime = Date.now as NSDate
let differenceInSeconds = Int(_currentCallTime.timeIntervalSince(_lastCallTime as Date))
print(differenceInSeconds)
if differenceInSeconds > 1 {
self._lastCallTime = self._currentCallTime
if self.firstPlayer {
self.player1.stop()
try! self.player1.load(url: (Bundle.main.resourceURL?.appendingPathComponent("Sounds/loop\(loopNumber).wav"))!,buffered: true)
self.player1.play()
} else {
self.player2.stop()
try! self.player2.load(url: (Bundle.main.resourceURL?.appendingPathComponent("Sounds/loop\(loopNumber).wav"))!,buffered: true)
self.player2.play()
}
self.firstPlayer = !self.firstPlayer
}
}
}
struct InstrumentEXSView: View {
@StateObject var conductor = InstrumentEXSConductor()
@Environment(\.colorScheme) var colorScheme
var body: some View {
Button(action: {conductor.loopNumber = 1} , label: {
Text("Loop1")
})
Button(action: {conductor.loopNumber = 2}, label: {
Text("Loop2")
}).cookbookNavBarTitle("Instrument EXS")
.onAppear {
conductor.start()
}
.onDisappear {
conductor.stop()
conductor.displayLink?.invalidate()
}
}
}
///Using Timer
/*
class InstrumentEXSConductor: ObservableObject, HasAudioEngine {
let engine = AudioEngine()
let player1 = AudioPlayer()
let player2 = AudioPlayer()
var loopNumber = 1
var firstPlayer = true
var timer = Timer()
init() {
engine.output = Mixer(player1,player2)
timer = Timer.scheduledTimer(timeInterval: 2, target: self, selector: #selector(self.update), userInfo: nil, repeats: true)
try! self.player2.load(url: (Bundle.main.resourceURL?.appendingPathComponent("Sounds/loop2.wav"))!,buffered: true)
self.player2.play()
try! self.player1.load(url: (Bundle.main.resourceURL?.appendingPathComponent("Sounds/loop1.wav"))!,buffered: true)
self.player1.play()
player1.stop()
player2.stop()
}
@objc func update() {
if self.firstPlayer {
self.player1.stop()
try! self.player1.load(url: (Bundle.main.resourceURL?.appendingPathComponent("Sounds/loop\(loopNumber).wav"))!,buffered: true)
self.player1.play()
} else {
self.player2.stop()
try! self.player2.load(url: (Bundle.main.resourceURL?.appendingPathComponent("Sounds/loop\(loopNumber).wav"))!,buffered: true)
self.player2.play()
}
self.firstPlayer = !self.firstPlayer
}
}
struct InstrumentEXSView: View {
@StateObject var conductor = InstrumentEXSConductor()
@Environment(\.colorScheme) var colorScheme
var body: some View {
Button(action: {conductor.loopNumber = 1} , label: {
Text("Loop1")
})
Button(action: {conductor.loopNumber = 2}, label: {
Text("Loop2")
}).cookbookNavBarTitle("Instrument EXS")
.onAppear {
conductor.start()
}
.onDisappear {
conductor.stop()
conductor.timer.invalidate()
}
}
}
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment