This code crashed when running startApplianceListener()
when using onAppear() on a swiftui view
import AVFAudio
import CoreML
import SoundAnalysis
/// An observer that receives results from a classify sound request.
class ResultsObserver: NSObject, SNResultsObserving {
/// Notifies the observer when a request generates a prediction.
func request(_ request: SNRequest, didProduce result: SNResult) {
// Downcast the result to a classification result.
guard let result = result as? SNClassificationResult else { return }
// Get the prediction with the highest confidence.
guard let classification = result.classifications.first else { return }
// Get the starting time.
let timeInSeconds = result.timeRange.start.seconds
// Convert the time to a human-readable string.
let formattedTime = String(format: "%.2f", timeInSeconds)
print("Analysis result for audio at time: \(formattedTime)")
// Convert the confidence to a percentage string.
let percent = classification.confidence * 100.0
let percentString = String(format: "%.2f%%", percent)
// Print the classification's name (label) with its confidence.
print("\(classification.identifier): \(percentString) confidence.\n")
}
/// Notifies the observer when a request generates an error.
func request(_ request: SNRequest, didFailWithError error: Error) {
print("The the analysis failed: \(error.localizedDescription)")
}
/// Notifies the observer when a request is complete.
func requestDidComplete(_ request: SNRequest) {
print("The request completed successfully!")
}
}
func startApplianceListener() {
do {
var audioEngine: AVAudioEngine?
var inputBus: Int?
var inputFormat: AVAudioFormat?
var streamAnalyzer: SNAudioStreamAnalyzer
func startAudioEngine() {
audioEngine = AVAudioEngine()
inputBus = AVAudioNodeBus(0)
inputFormat = audioEngine!.inputNode.inputFormat(forBus: inputBus!)
do {
try audioEngine!.start()
} catch {
print("Unable to start AVAudioEngine \(error.localizedDescription)")
exit(1)
}
}
startAudioEngine()
streamAnalyzer = SNAudioStreamAnalyzer(format: inputFormat!)
let version1 = SNClassifierIdentifier.version1
let request = try SNClassifySoundRequest(classifierIdentifier: version1)
let resultsObserver = ResultsObserver()
try streamAnalyzer.add(request,
withObserver: resultsObserver)
func installAudioTap() {
audioEngine!.inputNode.installTap(onBus: inputBus!,
bufferSize: 8192,
format: inputFormat,
block: analyzeAudio(buffer:at:))
}
let analysisQueue = DispatchQueue(label: "dev.paulwalker.AnalysisQueue")
func analyzeAudio(buffer: AVAudioBuffer, at time: AVAudioTime) {
analysisQueue.async {
streamAnalyzer.analyze(buffer,
atAudioFramePosition: time.sampleTime)
}
}
installAudioTap()
} catch {}
}