[Cog Audio] Make the Swift Vis Controller work

And this is the actual meat of getting it to work properly, the changes
the Swift code needed to actually be fully functional.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
xcode15
Christopher Snowhill 2022-08-05 21:38:13 -07:00
parent aed52840ca
commit 41a04760eb
1 changed files with 52 additions and 35 deletions

View File

@ -8,27 +8,30 @@
import Foundation import Foundation
@objc(VisualizationController) @objc(VisualizationController)
class VisualizationController { class VisualizationController : NSObject {
var serialQueue = DispatchQueue(label: "Visualization Queue") var serialQueue = DispatchQueue(label: "Visualization Queue")
var sampleRate = 44100.0 var sampleRate = 0.0
var latency = 0.0 var latency = 0.0
var visAudio: [Float] = Array(repeating: 0.0, count: 44100 * 45) var visAudio: [Float] = Array(repeating: 0.0, count: 44100 * 45)
var visAudioCursor = 0 var visAudioCursor = 0
var visAudioSize = 0 var visAudioSize = 0
private static var sharedController: VisualizationController = { private static var sharedVisualizationController: VisualizationController = {
let visualizationController = VisualizationController() let visualizationController = VisualizationController()
return visualizationController return visualizationController
}() }()
class func sharedVisualizationController() -> VisualizationController { @objc
return sharedController class func sharedController() -> VisualizationController {
return sharedVisualizationController
} }
@objc
func postLatency(_ latency: Double) { func postLatency(_ latency: Double) {
self.latency = latency self.latency = latency
} }
@objc
func postSampleRate(_ sampleRate: Double) { func postSampleRate(_ sampleRate: Double) {
serialQueue.sync { serialQueue.sync {
if(self.sampleRate != sampleRate) { if(self.sampleRate != sampleRate) {
@ -40,57 +43,71 @@ class VisualizationController {
} }
} }
@objc
func postVisPCM(_ inPCM: UnsafePointer<Float>?, amount: Int) { func postVisPCM(_ inPCM: UnsafePointer<Float>?, amount: Int) {
serialQueue.sync { serialQueue.sync {
let bufferPointer = UnsafeBufferPointer(start: inPCM, count: amount) let bufferPointer = UnsafeBufferPointer<Float>(start: inPCM, count: amount)
if let bptr = bufferPointer { var j = self.visAudioCursor
let dataArray = bptr.assumingMemoryBound(to: Float.self) let k = self.visAudioSize
var j = self.visAudioCursor for i in 0..<amount {
var k = self.visAudioSize let x = bufferPointer[i]
for i in 0..<amount { self.visAudio[j] = x
let x = Float(dataArray[i]) j += 1; if j >= k { j = 0 }
self.visAudio[j] = x
j++; if j >= k { j = 0 }
}
self.visAudioCursor = j
} }
self.visAudioCursor = j
} }
} }
@objc
func readSampleRate() -> Double { func readSampleRate() -> Double {
serialQueue.sync { serialQueue.sync {
return self.sampleRate return self.sampleRate
} }
} }
func copyVisPCM(_ outPCM: UnsafeMutablePointer<Float>?, visFFT: UnsafeMutablePointer<Float>?, latencyoffset: Double) { @objc
let outPCMCopy = Array<Float>(repeating: 0.0, count: 4096) func copyVisPCM(_ outPCM: UnsafeMutablePointer<Float>?, visFFT: UnsafeMutablePointer<Float>?, latencyOffset: Double) {
if(self.visAudioSize == 0) {
if(outPCM != nil) {
let pcmPointer = UnsafeMutableBufferPointer<Float>(start: outPCM, count: 4096)
for i in 0...4095 {
pcmPointer[i] = 0.0
}
}
if(visFFT != nil) {
let fftPointer = UnsafeMutableBufferPointer<Float>(start: visFFT, count: 2048)
for i in 0...2047 {
fftPointer[i] = 0.0
}
}
return
}
var outPCMCopy = Array<Float>(repeating: 0.0, count: 4096)
serialQueue.sync { serialQueue.sync {
var latencySamples = (Int)(self.latency * self.sampleRate) let latencySamples = (Int)(self.latency * self.sampleRate)
var j = self.visAudioCursor - latencySamples var j = self.visAudioCursor - latencySamples
var k = self.visAudioSize let k = self.visAudioSize
if j < 0 { j += k } if j < 0 { j += k }
for i in 0..4095 { for i in 0...4095 {
let x = self.visAudio[j] let x = self.visAudio[j]
outPCMCopy[i] = x outPCMCopy[i] = x
j++; if j >= k { j = 0 } j += 1; if j >= k { j = 0 }
} }
} }
let pcmPointer = UnsafeMutableBufferPointer(start: outPCM, count: 4096) if(outPCM != nil) {
if let bptr = pcmPointer { let pcmPointer = UnsafeMutableBufferPointer<Float>(start: outPCM, count: 4096)
let dataArray = bptr.assumingMemoryBound(to: Float.self) for i in 0...4095 {
for i in 0..4095 {
let x = outPCMCopy[i] let x = outPCMCopy[i]
dataArray[i] = x pcmPointer[i] = x
} }
} }
let fftPointer = UnsafeMutablePointer(start: visFFT, count: 2048) if(visFFT != nil) {
if let bptr = fftPointer {
serialQueue.sync { serialQueue.sync {
fft_calculate(outPCMCopy, bptr, 2048) fft_calculate(outPCMCopy, visFFT, 2048)
} }
} }
} }