feat(languages): expand speech catalog with Hungarian and more (#616)

Expose Hungarian and other high-demand Whisper languages in Settings/CLI,
wire official VOSK models where Alphacephei ships them, keep CLI choices
derived from SUPPORTED_LANGUAGES, and update the languages marketing page
with honest per-engine support.

Fixes #565

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Jatin K Malik <jatinkrmalik@users.noreply.github.com>
This commit is contained in:
Jatin K Malik
2026-07-29 07:32:37 +05:30
committed by GitHub
co-authored by Cursor Agent Jatin K Malik
parent ca24264c85
commit 28bed4c1fd
5 changed files with 488 additions and 123 deletions
+7 -18
View File
@@ -8,6 +8,7 @@ import atexit
import logging
import sys
from .utils.vosk_model_info import SUPPORTED_LANGUAGES
from .version import __version__
# Configure logging
@@ -20,6 +21,9 @@ logger = logging.getLogger(__name__)
# Note: GTK-dependent modules (tray_indicator) are imported lazily after
# dependency checking to provide better error messages for pip/pipx users
# Keep CLI --language choices in sync with the Settings catalog.
LANGUAGE_CHOICES = tuple(SUPPORTED_LANGUAGES.keys())
def _should_append_trailing_space() -> bool:
"""Return whether completed transcriptions should get a trailing space.
@@ -68,25 +72,10 @@ def parse_arguments():
parser.add_argument(
"--language",
type=str,
choices=[
"auto",
"en-us",
"en-in",
"hi",
"es",
"fr",
"de",
"it",
"pt",
"ru",
"zh",
"ja",
"ko",
"ar",
],
choices=LANGUAGE_CHOICES,
help=(
"Speech recognition language (auto for auto-detect, en-us, "
"hi, es, fr, de, it, pt, ru, zh, etc.)"
"Speech recognition language (auto for auto-detect, or a code "
"from the Settings language catalog such as en-us, hu, ja, …)"
),
)
parser.add_argument(
+187 -24
View File
@@ -1,5 +1,10 @@
# Language definitions with display names and Whisper/VOSK codes
# Supported languages for speech recognition
#
# Whisper / whisper.cpp / remote_api use the catalog key (or the "whisper"
# code for English-only model checks). VOSK uses per-language model zips from
# VOSK_MODEL_INFO; set "vosk" to None when no official Alphacephei model exists.
# Medium/large must cover every language present in small (see issue #550).
SUPPORTED_LANGUAGES = {
"auto": {
"name": "Auto-detect",
@@ -12,15 +17,50 @@ SUPPORTED_LANGUAGES = {
"whisper": "en",
"vosk": "vosk-model-small-en-us-0.15",
},
"hi": {
"name": "Hindi",
"whisper": "hi",
"vosk": "vosk-model-small-hi-0.22",
"en-in": {
"name": "English (India)",
"whisper": "en",
"vosk": "vosk-model-small-en-in-0.4",
},
"es": {
"name": "Spanish",
"whisper": "es",
"vosk": "vosk-model-small-es-0.42",
"ar": {
"name": "Arabic",
"whisper": "ar",
"vosk": "vosk-model-small-ar-0.3",
},
"bn": {
"name": "Bengali",
"whisper": "bn",
"vosk": None,
},
"ca": {
"name": "Catalan",
"whisper": "ca",
"vosk": "vosk-model-small-ca-0.4",
},
"zh": {
"name": "Chinese",
"whisper": "zh",
"vosk": "vosk-model-small-cn-0.22",
},
"cs": {
"name": "Czech",
"whisper": "cs",
"vosk": "vosk-model-small-cs-0.4-rhasspy",
},
"da": {
"name": "Danish",
"whisper": "da",
"vosk": None,
},
"nl": {
"name": "Dutch",
"whisper": "nl",
"vosk": "vosk-model-small-nl-0.22",
},
"fi": {
"name": "Finnish",
"whisper": "fi",
"vosk": None,
},
"fr": {
"name": "French",
@@ -32,30 +72,117 @@ SUPPORTED_LANGUAGES = {
"whisper": "de",
"vosk": "vosk-model-small-de-0.15",
},
"el": {
"name": "Greek",
"whisper": "el",
"vosk": None,
},
"he": {
"name": "Hebrew",
"whisper": "he",
"vosk": None,
},
"hi": {
"name": "Hindi",
"whisper": "hi",
"vosk": "vosk-model-small-hi-0.22",
},
"hu": {
"name": "Hungarian",
"whisper": "hu",
"vosk": None,
},
"id": {
"name": "Indonesian",
"whisper": "id",
"vosk": None,
},
"it": {
"name": "Italian",
"whisper": "it",
"vosk": "vosk-model-small-it-0.22",
},
"ja": {
"name": "Japanese",
"whisper": "ja",
"vosk": "vosk-model-small-ja-0.22",
},
"ko": {
"name": "Korean",
"whisper": "ko",
"vosk": "vosk-model-small-ko-0.22",
},
"no": {
"name": "Norwegian",
"whisper": "no",
"vosk": None,
},
"fa": {
"name": "Persian",
"whisper": "fa",
"vosk": "vosk-model-small-fa-0.42",
},
"pl": {
"name": "Polish",
"whisper": "pl",
"vosk": "vosk-model-small-pl-0.22",
},
"pt": {
"name": "Portuguese",
"whisper": "pt",
"vosk": "vosk-model-small-pt-0.3",
},
"ro": {
"name": "Romanian",
"whisper": "ro",
"vosk": None,
},
"ru": {
"name": "Russian",
"whisper": "ru",
"vosk": "vosk-model-small-ru-0.22",
},
"zh": {
"name": "Chinese",
"whisper": "zh",
"vosk": "vosk-model-small-cn-0.22",
"es": {
"name": "Spanish",
"whisper": "es",
"vosk": "vosk-model-small-es-0.42",
},
"sv": {
"name": "Swedish",
"whisper": "sv",
"vosk": "vosk-model-small-sv-rhasspy-0.15",
},
"ta": {
"name": "Tamil",
"whisper": "ta",
"vosk": None,
},
"th": {
"name": "Thai",
"whisper": "th",
"vosk": None,
},
"tr": {
"name": "Turkish",
"whisper": "tr",
"vosk": "vosk-model-small-tr-0.3",
},
"uk": {
"name": "Ukrainian",
"whisper": "uk",
"vosk": "vosk-model-small-uk-v3-small",
},
"vi": {
"name": "Vietnamese",
"whisper": "vi",
"vosk": "vosk-model-small-vn-0.4",
},
}
# VOSK model metadata for display
# VOSK model metadata for display and download path resolution.
# When Alphacephei only ships a small model, medium/large point at that same
# zip so size selection never resolves to None (issue #550).
VOSK_MODEL_INFO = {
"small": {
"size_mb": 40,
@@ -63,14 +190,26 @@ VOSK_MODEL_INFO = {
"languages": {
"en-us": "vosk-model-small-en-us-0.15",
"en-in": "vosk-model-small-en-in-0.4",
"hi": "vosk-model-small-hi-0.22",
"es": "vosk-model-small-es-0.42",
"ar": "vosk-model-small-ar-0.3",
"ca": "vosk-model-small-ca-0.4",
"zh": "vosk-model-small-cn-0.22",
"cs": "vosk-model-small-cs-0.4-rhasspy",
"nl": "vosk-model-small-nl-0.22",
"fr": "vosk-model-small-fr-0.22",
"de": "vosk-model-small-de-0.15",
"hi": "vosk-model-small-hi-0.22",
"it": "vosk-model-small-it-0.22",
"ja": "vosk-model-small-ja-0.22",
"ko": "vosk-model-small-ko-0.22",
"fa": "vosk-model-small-fa-0.42",
"pl": "vosk-model-small-pl-0.22",
"pt": "vosk-model-small-pt-0.3",
"ru": "vosk-model-small-ru-0.22",
"zh": "vosk-model-small-cn-0.22",
"es": "vosk-model-small-es-0.42",
"sv": "vosk-model-small-sv-rhasspy-0.15",
"tr": "vosk-model-small-tr-0.3",
"uk": "vosk-model-small-uk-v3-small",
"vi": "vosk-model-small-vn-0.4",
},
},
"medium": {
@@ -79,14 +218,26 @@ VOSK_MODEL_INFO = {
"languages": {
"en-us": "vosk-model-en-us-0.22",
"en-in": "vosk-model-en-in-0.5",
"ar": "vosk-model-ar-0.22-linto-1.1.0",
"ca": "vosk-model-small-ca-0.4",
"zh": "vosk-model-cn-0.22",
"cs": "vosk-model-small-cs-0.4-rhasspy",
"nl": "vosk-model-nl-spraakherkenning-0.6",
"fr": "vosk-model-fr-0.22",
"de": "vosk-model-de-0.21",
"it": "vosk-model-it-0.22",
"ru": "vosk-model-ru-0.22",
"hi": "vosk-model-hi-0.22",
"es": "vosk-model-es-0.42",
"it": "vosk-model-it-0.22",
"ja": "vosk-model-ja-0.22",
"ko": "vosk-model-small-ko-0.22",
"fa": "vosk-model-fa-0.42",
"pl": "vosk-model-small-pl-0.22",
"pt": "vosk-model-pt-0.4",
"zh": "vosk-model-cn-0.22",
"ru": "vosk-model-ru-0.22",
"es": "vosk-model-es-0.42",
"sv": "vosk-model-small-sv-rhasspy-0.15",
"tr": "vosk-model-small-tr-0.3",
"uk": "vosk-model-uk-v3",
"vi": "vosk-model-vn-0.4",
},
},
"large": {
@@ -95,14 +246,26 @@ VOSK_MODEL_INFO = {
"languages": {
"en-us": "vosk-model-en-us-0.22",
"en-in": "vosk-model-en-in-0.5",
"ar": "vosk-model-ar-0.22-linto-1.1.0",
"ca": "vosk-model-small-ca-0.4",
"zh": "vosk-model-cn-0.22",
"cs": "vosk-model-small-cs-0.4-rhasspy",
"nl": "vosk-model-nl-spraakherkenning-0.6",
"fr": "vosk-model-fr-0.22",
"de": "vosk-model-de-0.21",
"it": "vosk-model-it-0.22",
"ru": "vosk-model-ru-0.22",
"hi": "vosk-model-hi-0.22",
"es": "vosk-model-es-0.42",
"it": "vosk-model-it-0.22",
"ja": "vosk-model-ja-0.22",
"ko": "vosk-model-small-ko-0.22",
"fa": "vosk-model-fa-0.42",
"pl": "vosk-model-small-pl-0.22",
"pt": "vosk-model-pt-0.4",
"zh": "vosk-model-cn-0.22",
"ru": "vosk-model-ru-0.22",
"es": "vosk-model-es-0.42",
"sv": "vosk-model-small-sv-rhasspy-0.15",
"tr": "vosk-model-small-tr-0.3",
"uk": "vosk-model-uk-v3",
"vi": "vosk-model-vn-0.4",
},
},
}
+8 -17
View File
@@ -90,23 +90,14 @@ class TestMainModule(unittest.TestCase):
self.assertEqual(args.engine, "whisper")
def test_parse_arguments_language_choices(self):
"""Test that language only accepts valid choices."""
for lang in [
"auto",
"en-us",
"en-in",
"hi",
"es",
"fr",
"de",
"it",
"pt",
"ru",
"zh",
"ja",
"ko",
"ar",
]:
"""Test that language only accepts valid choices from the catalog."""
from vocalinux.main import LANGUAGE_CHOICES
from vocalinux.utils.vosk_model_info import SUPPORTED_LANGUAGES
self.assertEqual(LANGUAGE_CHOICES, tuple(SUPPORTED_LANGUAGES.keys()))
# Spot-check newly exposed languages (issue #565 and catalog expansion).
for lang in ["auto", "en-us", "hu", "ja", "ko", "ar", "nl", "pl", "uk"]:
self.assertIn(lang, LANGUAGE_CHOICES)
with patch("sys.argv", ["vocalinux", "--language", lang]):
args = parse_arguments()
self.assertEqual(args.language, lang)
+30
View File
@@ -275,6 +275,36 @@ class TestSpeechRecognition(unittest.TestCase):
"otherwise initialization crashes with a NoneType path error.",
)
def test_supported_languages_vosk_entries_match_model_tables(self):
"""Every catalog language with a VOSK model must appear in size tables."""
from vocalinux.utils.vosk_model_info import SUPPORTED_LANGUAGES
for lang_code, lang_info in SUPPORTED_LANGUAGES.items():
vosk_model = lang_info.get("vosk")
if not vosk_model:
continue
self.assertEqual(
VOSK_MODEL_INFO["small"]["languages"].get(lang_code),
vosk_model,
f"SUPPORTED_LANGUAGES['{lang_code}']['vosk'] must match "
f"VOSK_MODEL_INFO['small']['languages']['{lang_code}']",
)
for size in ("medium", "large"):
self.assertIn(
lang_code,
VOSK_MODEL_INFO[size]["languages"],
f"VOSK language '{lang_code}' missing from '{size}' table",
)
def test_hungarian_is_whisper_only_in_catalog(self):
"""Hungarian (issue #565) is exposed for Whisper engines, not VOSK."""
from vocalinux.utils.vosk_model_info import SUPPORTED_LANGUAGES
hu = SUPPORTED_LANGUAGES["hu"]
self.assertEqual(hu["whisper"], "hu")
self.assertIsNone(hu["vosk"])
self.assertNotIn("hu", VOSK_MODEL_INFO["small"]["languages"])
def test_vosk_init_italian_medium_model_resolves_correctly(self):
"""Selecting Italian + the 'medium' VOSK model must not crash (issue #550)."""
manager = SpeechRecognitionManager(engine="vosk", language="it", model_size="medium")
+256 -64
View File
@@ -4,6 +4,9 @@ import { CheckCircle2, ChevronRight, Globe, Languages, Mic } from "lucide-react"
import { SeoSubpageShell } from "@/components/seo-subpage-shell";
import { absoluteUrl, buildPageMetadata } from "@/lib/seo";
const WHISPER_ENGINES = ["whisper.cpp", "Whisper"] as const;
const ALL_ENGINES = ["whisper.cpp", "Whisper", "VOSK"] as const;
const supportedLanguages = [
{
code: "en",
@@ -11,62 +14,39 @@ const supportedLanguages = [
nativeName: "English",
flag: "🇺🇸",
description: "Full support across all engines (whisper.cpp, Whisper, VOSK)",
engines: ["whisper.cpp", "Whisper", "VOSK"],
modelSizes: ["tiny", "base", "small", "medium", "large"],
engines: [...ALL_ENGINES],
},
{
code: "es",
name: "Spanish",
nativeName: "Español",
flag: "🇪🇸",
description: "Complete Spanish language support for dictation",
engines: ["whisper.cpp", "Whisper", "VOSK"],
modelSizes: ["tiny", "base", "small", "medium", "large"],
code: "en-in",
name: "English (India)",
nativeName: "English (India)",
flag: "🇮🇳",
description: "Indian English dictation with a dedicated VOSK model",
engines: [...ALL_ENGINES],
},
{
code: "fr",
name: "French",
nativeName: "Français",
flag: "🇫🇷",
description: "French language voice typing and transcription",
engines: ["whisper.cpp", "Whisper", "VOSK"],
modelSizes: ["tiny", "base", "small", "medium", "large"],
code: "ar",
name: "Arabic",
nativeName: "العربية",
flag: "🇸🇦",
description: "Arabic speech recognition across Whisper and VOSK",
engines: [...ALL_ENGINES],
},
{
code: "de",
name: "German",
nativeName: "Deutsch",
flag: "🇩🇪",
description: "German dictation with high accuracy",
engines: ["whisper.cpp", "Whisper", "VOSK"],
modelSizes: ["tiny", "base", "small", "medium", "large"],
code: "bn",
name: "Bengali",
nativeName: "বাংলা",
flag: "🇧🇩",
description: "Bengali dictation with multilingual Whisper models",
engines: [...WHISPER_ENGINES],
},
{
code: "it",
name: "Italian",
nativeName: "Italiano",
flag: "🇮🇹",
description: "Italian voice recognition and text dictation",
engines: ["whisper.cpp", "Whisper", "VOSK"],
modelSizes: ["tiny", "base", "small", "medium", "large"],
},
{
code: "pt",
name: "Portuguese",
nativeName: "Português",
flag: "🇧🇷",
description: "Brazilian and European Portuguese support",
engines: ["whisper.cpp", "Whisper", "VOSK"],
modelSizes: ["tiny", "base", "small", "medium", "large"],
},
{
code: "ru",
name: "Russian",
nativeName: "Русский",
flag: "🇷🇺",
description: "Russian language speech-to-text transcription",
engines: ["whisper.cpp", "Whisper", "VOSK"],
modelSizes: ["tiny", "base", "small", "medium", "large"],
code: "ca",
name: "Catalan",
nativeName: "Català",
flag: "🇦🇩",
description: "Catalan voice typing with Whisper and VOSK",
engines: [...ALL_ENGINES],
},
{
code: "zh",
@@ -74,8 +54,71 @@ const supportedLanguages = [
nativeName: "中文",
flag: "🇨🇳",
description: "Mandarin Chinese voice dictation support",
engines: ["whisper.cpp", "Whisper", "VOSK"],
modelSizes: ["tiny", "base", "small", "medium", "large"],
engines: [...ALL_ENGINES],
},
{
code: "cs",
name: "Czech",
nativeName: "Čeština",
flag: "🇨🇿",
description: "Czech dictation with Whisper and VOSK",
engines: [...ALL_ENGINES],
},
{
code: "da",
name: "Danish",
nativeName: "Dansk",
flag: "🇩🇰",
description: "Danish speech-to-text with multilingual Whisper models",
engines: [...WHISPER_ENGINES],
},
{
code: "nl",
name: "Dutch",
nativeName: "Nederlands",
flag: "🇳🇱",
description: "Dutch voice recognition across Whisper and VOSK",
engines: [...ALL_ENGINES],
},
{
code: "fi",
name: "Finnish",
nativeName: "Suomi",
flag: "🇫🇮",
description: "Finnish dictation with multilingual Whisper models",
engines: [...WHISPER_ENGINES],
},
{
code: "fr",
name: "French",
nativeName: "Français",
flag: "🇫🇷",
description: "French language voice typing and transcription",
engines: [...ALL_ENGINES],
},
{
code: "de",
name: "German",
nativeName: "Deutsch",
flag: "🇩🇪",
description: "German dictation with high accuracy",
engines: [...ALL_ENGINES],
},
{
code: "el",
name: "Greek",
nativeName: "Ελληνικά",
flag: "🇬🇷",
description: "Greek speech recognition with multilingual Whisper models",
engines: [...WHISPER_ENGINES],
},
{
code: "he",
name: "Hebrew",
nativeName: "עברית",
flag: "🇮🇱",
description: "Hebrew dictation with multilingual Whisper models",
engines: [...WHISPER_ENGINES],
},
{
code: "hi",
@@ -83,11 +126,156 @@ const supportedLanguages = [
nativeName: "हिन्दी",
flag: "🇮🇳",
description: "Hindi language voice typing and transcription",
engines: ["whisper.cpp", "Whisper", "VOSK"],
modelSizes: ["tiny", "base", "small", "medium", "large"],
engines: [...ALL_ENGINES],
},
{
code: "hu",
name: "Hungarian",
nativeName: "Magyar",
flag: "🇭🇺",
description: "Hungarian dictation with multilingual Whisper models",
engines: [...WHISPER_ENGINES],
},
{
code: "id",
name: "Indonesian",
nativeName: "Bahasa Indonesia",
flag: "🇮🇩",
description: "Indonesian voice typing with multilingual Whisper models",
engines: [...WHISPER_ENGINES],
},
{
code: "it",
name: "Italian",
nativeName: "Italiano",
flag: "🇮🇹",
description: "Italian voice recognition and text dictation",
engines: [...ALL_ENGINES],
},
{
code: "ja",
name: "Japanese",
nativeName: "日本語",
flag: "🇯🇵",
description: "Japanese speech-to-text across Whisper and VOSK",
engines: [...ALL_ENGINES],
},
{
code: "ko",
name: "Korean",
nativeName: "한국어",
flag: "🇰🇷",
description: "Korean dictation with Whisper and VOSK",
engines: [...ALL_ENGINES],
},
{
code: "no",
name: "Norwegian",
nativeName: "Norsk",
flag: "🇳🇴",
description: "Norwegian speech recognition with multilingual Whisper models",
engines: [...WHISPER_ENGINES],
},
{
code: "fa",
name: "Persian",
nativeName: "فارسی",
flag: "🇮🇷",
description: "Persian (Farsi) dictation with Whisper and VOSK",
engines: [...ALL_ENGINES],
},
{
code: "pl",
name: "Polish",
nativeName: "Polski",
flag: "🇵🇱",
description: "Polish voice typing with Whisper and VOSK",
engines: [...ALL_ENGINES],
},
{
code: "pt",
name: "Portuguese",
nativeName: "Português",
flag: "🇧🇷",
description: "Brazilian and European Portuguese support",
engines: [...ALL_ENGINES],
},
{
code: "ro",
name: "Romanian",
nativeName: "Română",
flag: "🇷🇴",
description: "Romanian dictation with multilingual Whisper models",
engines: [...WHISPER_ENGINES],
},
{
code: "ru",
name: "Russian",
nativeName: "Русский",
flag: "🇷🇺",
description: "Russian language speech-to-text transcription",
engines: [...ALL_ENGINES],
},
{
code: "es",
name: "Spanish",
nativeName: "Español",
flag: "🇪🇸",
description: "Complete Spanish language support for dictation",
engines: [...ALL_ENGINES],
},
{
code: "sv",
name: "Swedish",
nativeName: "Svenska",
flag: "🇸🇪",
description: "Swedish voice recognition with Whisper and VOSK",
engines: [...ALL_ENGINES],
},
{
code: "ta",
name: "Tamil",
nativeName: "தமிழ்",
flag: "🇮🇳",
description: "Tamil dictation with multilingual Whisper models",
engines: [...WHISPER_ENGINES],
},
{
code: "th",
name: "Thai",
nativeName: "ไทย",
flag: "🇹🇭",
description: "Thai speech-to-text with multilingual Whisper models",
engines: [...WHISPER_ENGINES],
},
{
code: "tr",
name: "Turkish",
nativeName: "Türkçe",
flag: "🇹🇷",
description: "Turkish dictation with Whisper and VOSK",
engines: [...ALL_ENGINES],
},
{
code: "uk",
name: "Ukrainian",
nativeName: "Українська",
flag: "🇺🇦",
description: "Ukrainian voice typing with Whisper and VOSK",
engines: [...ALL_ENGINES],
},
{
code: "vi",
name: "Vietnamese",
nativeName: "Tiếng Việt",
flag: "🇻🇳",
description: "Vietnamese speech recognition with Whisper and VOSK",
engines: [...ALL_ENGINES],
},
];
const languageCount = supportedLanguages.length;
const features = [
{
title: "Automatic Language Detection",
@@ -96,9 +284,9 @@ const features = [
icon: Globe,
},
{
title: "Multi-Engine Support",
title: "Engine-Aware Catalog",
description:
"All supported languages work across whisper.cpp, OpenAI Whisper, and VOSK engines.",
"Whisper engines cover the full language list. VOSK appears only where an official model exists.",
icon: Mic,
},
{
@@ -110,15 +298,19 @@ const features = [
];
export const metadata: Metadata = buildPageMetadata({
title: "Multilingual Voice Dictation - Spanish, French, German, & More | Vocalinux",
title: "Multilingual Voice Dictation - 30+ Languages | Vocalinux",
description:
"Dictate in 9+ languages including Spanish, French, German, Italian, Portuguese, Russian, Chinese, and Hindi. Free offline multilingual voice typing for Linux.",
"Dictate in 30+ languages including Spanish, French, German, Hungarian, Japanese, Korean, Arabic, and more. Free offline multilingual voice typing for Linux.",
path: "/languages",
keywords: [
"multilingual voice dictation",
"Spanish voice typing",
"French speech to text",
"German dictation software",
"Hungarian voice recognition",
"Japanese speech to text",
"Korean voice typing",
"Arabic dictation",
"Italian voice recognition",
"Portuguese voice typing",
"Russian speech recognition",
@@ -132,10 +324,10 @@ export default function LanguagesPage() {
const articleJsonLd = {
"@context": "https://schema.org",
"@type": "Article",
headline: "Multilingual Voice Dictation for Linux - 9+ Languages Supported",
headline: `Multilingual Voice Dictation for Linux - ${languageCount}+ Languages Supported`,
description:
"Complete guide to Vocalinux multilingual voice dictation. Dictate in Spanish, French, German, Italian, Portuguese, Russian, Chinese, Hindi, and more.",
dateModified: "2026-02-22",
"Complete guide to Vocalinux multilingual voice dictation. Dictate in Spanish, French, German, Hungarian, Japanese, Korean, Arabic, Hindi, and more.",
dateModified: "2026-07-29",
author: {
"@type": "Person",
name: "Jatin K Malik",
@@ -162,14 +354,14 @@ export default function LanguagesPage() {
<section>
<p className="subpage-kicker">
<Languages className="h-4 w-4" />
9+ Languages
{languageCount}+ Languages
</p>
<h1 className="mb-5 font-display text-4xl font-semibold tracking-tight sm:text-5xl">
Multilingual Voice Dictation for Linux
</h1>
<p className="mb-8 max-w-4xl text-lg text-muted-foreground">
Dictate in your native language. Vocalinux supports 9+ languages with full offline
processing - no cloud required, no data leaves your machine.
Dictate in your native language. Vocalinux lists {languageCount} languages in Settings,
and whisper.cpp / Whisper can auto-detect many more - all offline, with no cloud upload.
</p>
</section>
@@ -232,7 +424,7 @@ export default function LanguagesPage() {
</li>
<li className="flex items-start gap-2">
<CheckCircle2 className="mt-0.5 h-4 w-4 flex-shrink-0 text-primary" />
Use "Auto" for automatic language detection (whisper.cpp/Whisper)
Use &quot;Auto&quot; for automatic language detection (whisper.cpp/Whisper)
</li>
<li className="flex items-start gap-2">
<CheckCircle2 className="mt-0.5 h-4 w-4 flex-shrink-0 text-primary" />
@@ -249,7 +441,7 @@ export default function LanguagesPage() {
</li>
<li className="flex items-start gap-2">
<CheckCircle2 className="mt-0.5 h-4 w-4 flex-shrink-0 text-primary" />
"tiny" model works for all supported languages
Use a Standard multilingual whisper.cpp model for non-English dictation
</li>
<li className="flex items-start gap-2">
<CheckCircle2 className="mt-0.5 h-4 w-4 flex-shrink-0 text-primary" />