You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
71 lines
2.2 KiB
71 lines
2.2 KiB
2 years ago
|
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..<whisper_full_n_segments(context) {
|
||
|
transcription += String.init(cString: whisper_full_get_segment_text(context, i))
|
||
|
}
|
||
|
return transcription
|
||
|
}
|
||
|
|
||
|
static func createContext(path: String) throws -> WhisperContext {
|
||
|
let context = whisper_init(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
|
||
|
}
|