Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions OpenWhisp/Services/WhisperEngine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -183,14 +183,21 @@ class WhisperEngine: FileTranscriptionEngine {

let process = Process()
process.executableURL = URL(fileURLWithPath: binaryPath)
// Map the Language setting to whisper's (source language, translate)
// params. "en" => translate speech to English (-l auto --translate);
// see WhisperTask. The app previously sent -l en and never translated.
let task = WhisperTask.resolve(languageSetting: language)
var arguments = [
"-m", modelPath,
"-f", wavPath,
"-l", language == "auto" ? "auto" : language,
"-l", task.language,
"--no-timestamps",
"-otxt",
"-nt"
]
if task.translate {
arguments.append("--translate")
}
let trimmedPrompt = prompt.trimmingCharacters(in: .whitespacesAndNewlines)
if !trimmedPrompt.isEmpty {
arguments.append(contentsOf: ["--prompt", trimmedPrompt])
Expand Down Expand Up @@ -558,12 +565,18 @@ class WhisperEngine: FileTranscriptionEngine {
data.append("\(value)\r\n".data(using: .utf8)!)
}

// Same mapping as the CLI path (see WhisperTask): "en" => translate to
// English with source auto-detected, sent as translate=true + language=auto.
let task = WhisperTask.resolve(languageSetting: language)
appendField("response_format", "json")
appendField("temperature", "0.0")
appendField("temperature_inc", "0.2")
appendField("no_speech_thold", "0.6")
appendField("no_timestamps", "true")
appendField("language", language == "auto" ? "auto" : language)
appendField("language", task.language)
if task.translate {
appendField("translate", "true")
}
appendField("suppress_non_speech", "true")
let trimmedPrompt = prompt.trimmingCharacters(in: .whitespacesAndNewlines)
if !trimmedPrompt.isEmpty {
Expand Down
29 changes: 29 additions & 0 deletions OpenWhisp/Services/WhisperTask.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import Foundation

/// Resolves the user's Language setting into the two parameters whisper actually
/// needs: the source language code and whether to translate to English.
///
/// The Language picker's "English — Whisper translate to English" is special:
/// whisper's `--translate` ALWAYS targets English and needs the SOURCE language
/// auto-detected, so "en" must map to (language: "auto", translate: true), NOT
/// (language: "en"), which would tell whisper the source is English and skip
/// translation. Every other choice ("auto", "ru", …) transcribes in that language
/// with no translation.
///
/// Pure Foundation, so it lives in OpenWhispCore and is unit-tested — this is the
/// branch that was wrong (the app sent `-l en` and never translated).
enum WhisperTask {
struct Resolved: Equatable {
/// Source language code to pass to whisper ("auto" or a specific code).
var language: String
/// Whether to pass --translate (CLI) / translate=true (server).
var translate: Bool
}

static func resolve(languageSetting: String) -> Resolved {
if languageSetting == "en" {
return Resolved(language: "auto", translate: true)
}
return Resolved(language: languageSetting.isEmpty ? "auto" : languageSetting, translate: false)
}
}
3 changes: 2 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ let package = Package(
"LiveChunkPipeline.swift",
"ConfigBundle.swift",
"ConfigPack.swift",
"ScriptPostProcessor.swift"
"ScriptPostProcessor.swift",
"WhisperTask.swift"
]
),
.testTarget(
Expand Down
28 changes: 28 additions & 0 deletions Tests/OpenWhispCoreTests/WhisperTaskTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import XCTest
@testable import OpenWhispCore

final class WhisperTaskTests: XCTestCase {
func testEnglishMeansTranslateWithAutoSource() {
// The bug: "en" must become (auto, translate=true), NOT (en, translate=false)
// — otherwise whisper treats the source as English and never translates.
XCTAssertEqual(WhisperTask.resolve(languageSetting: "en"),
.init(language: "auto", translate: true))
}

func testAutoTranscribesNoTranslate() {
XCTAssertEqual(WhisperTask.resolve(languageSetting: "auto"),
.init(language: "auto", translate: false))
}

func testSpecificLanguageTranscribesNoTranslate() {
XCTAssertEqual(WhisperTask.resolve(languageSetting: "ru"),
.init(language: "ru", translate: false))
XCTAssertEqual(WhisperTask.resolve(languageSetting: "de"),
.init(language: "de", translate: false))
}

func testEmptyFallsBackToAuto() {
XCTAssertEqual(WhisperTask.resolve(languageSetting: ""),
.init(language: "auto", translate: false))
}
}
Loading