import Foundation enum WhisperError: Error { case couldNotInitializeContext } // Meet Whisper C++ constraint: Don't access from more than one thread at a time. actor WhisperContext { private var context: OpaquePointer init(context: OpaquePointer) { self.context = context } deinit { whisper_free(context) } func fullTranscribe(samples: [Float]) { // Leave 2 processors free (i.e. the high-efficiency cores). let maxThreads = max(1, min(8, cpuCount() - 2)) print("Selecting \(maxThreads) threads") var params = whisper_full_default_params(WHISPER_SAMPLING_GREEDY) "en".withCString { en in // Adapted from whisper.objc params.print_realtime = true params.print_progress = false params.print_timestamps = true params.print_special = false params.translate = false params.language = en params.n_threads = Int32(maxThreads) params.offset_ms = 0 params.no_context = true params.single_segment = false whisper_reset_timings(context) print("About to run whisper_full") samples.withUnsafeBufferPointer { samples in if (whisper_full(context, params, samples.baseAddress, Int32(samples.count)) != 0) { print("Failed to run the model") } else { whisper_print_timings(context) } } } } func getTranscription() -> String { var transcription = "" for i in 0.. WhisperContext { let context = whisper_init_from_file(path) if let context { return WhisperContext(context: context) } else { print("Couldn't load model at \(path)") throw WhisperError.couldNotInitializeContext } } } fileprivate func cpuCount() -> Int { ProcessInfo.processInfo.processorCount }