|
| 1 | +# Sichuan Voice Input / 四川话语音输入 |
| 2 | + |
| 3 | +A macOS menu bar app that converts speech to text and types it at your cursor — 100% locally, no cloud, no subscription. |
| 4 | + |
| 5 | +Powered by [Qwen3-ASR-0.6B](https://huggingface.co/Qwen/Qwen3-ASR-0.6B), a state-of-the-art speech recognition model that runs entirely on your Mac. Originally built for Sichuan dialect, but supports 30+ languages and 20+ Chinese dialects. |
| 6 | + |
| 7 | +## How It Works |
| 8 | + |
| 9 | +1. Press **Right Option** key to start recording |
| 10 | +2. Speak naturally in any supported language |
| 11 | +3. Release the key — text appears at your cursor within a second |
| 12 | + |
| 13 | +The app runs a pure C inference engine locally. Your audio never leaves your machine. No API keys, no internet connection needed (after initial model download). |
| 14 | + |
| 15 | +## Features |
| 16 | + |
| 17 | +- **Fully local speech recognition** — Qwen3-ASR-0.6B (~1.7GB) runs natively via a custom C inference engine with Apple Accelerate BLAS optimization |
| 18 | +- **Instant text injection** — transcribed text is typed directly at your cursor position in any app (via clipboard + simulated Cmd+V, with automatic clipboard restoration) |
| 19 | +- **Two input modes**: |
| 20 | + - **Hold mode** (default): hold Right Option to talk, release to transcribe |
| 21 | + - **Toggle mode**: tap Right Option to start, tap again to stop |
| 22 | +- **Menu bar app** — lives quietly in your status bar, always one hotkey away |
| 23 | +- **Bilingual UI** — switch between Chinese and English interface in Settings |
| 24 | +- **Auto model download** — downloads the model (~1.7GB) from HuggingFace on first launch |
| 25 | +- **Smart audio handling** — automatically mutes system audio during recording to avoid interference, restores when done |
| 26 | +- **Auto-start** — registers as a login item so it's always available |
| 27 | +- **Remote access** (optional) — Cloudflare Tunnel + Bonjour for accessing from other devices on the network |
| 28 | + |
| 29 | +## Supported Languages |
| 30 | + |
| 31 | +**30 languages**: Chinese, English, Japanese, Korean, French, German, Spanish, Portuguese, Italian, Russian, Arabic, Thai, Vietnamese, Indonesian, Turkish, Hindi, Malay, Dutch, Swedish, Danish, Finnish, Polish, Czech, Filipino, Persian, Greek, Hungarian, Macedonian, Romanian, Cantonese |
| 32 | + |
| 33 | +**22 Chinese dialects**: Sichuan, Dongbei, Anhui, Fujian, Gansu, Guizhou, Hebei, Henan, Hubei, Hunan, Jiangxi, Ningxia, Shandong, Shaanxi, Shanxi, Tianjin, Yunnan, Zhejiang, Cantonese (Hong Kong), Cantonese (Guangdong), Wu, Minnan |
| 34 | + |
| 35 | +## System Requirements |
| 36 | + |
| 37 | +| Requirement | Detail | |
| 38 | +|---|---| |
| 39 | +| **macOS** | 14.0 (Sonoma) or later | |
| 40 | +| **Processor** | Apple Silicon (M1+) or Intel (universal binary) | |
| 41 | +| **RAM** | ~3GB free (model loads into memory) | |
| 42 | +| **Disk** | ~2GB (model ~1.7GB + app) | |
| 43 | +| **Permissions** | Microphone + Accessibility | |
| 44 | + |
| 45 | +## Installation |
| 46 | + |
| 47 | +### Option 1: Download DMG (Recommended) |
| 48 | + |
| 49 | +1. Download `方言语音输入.dmg` from [Releases](../../releases) |
| 50 | +2. Open the DMG and drag the app to **Applications** |
| 51 | +3. First launch: right-click the app → **Open** → **Open** (Gatekeeper bypass for unsigned app) |
| 52 | + - Or run: `xattr -cr /Applications/方言语音输入.app` |
| 53 | +4. Grant **Microphone** and **Accessibility** permissions when prompted |
| 54 | +5. The model (~1.7GB) downloads automatically on first launch — wait for the menu bar icon to show a solid microphone |
| 55 | + |
| 56 | +### Option 2: Build from Source |
| 57 | + |
| 58 | +Requires Xcode Command Line Tools (`xcode-select --install`). |
| 59 | + |
| 60 | +```bash |
| 61 | +git clone https://github.com/liusqu/AudiotoTextTool_Sichuanhua-Input.git |
| 62 | +cd AudiotoTextTool_Sichuanhua-Input |
| 63 | + |
| 64 | +# Build the C inference library (universal binary) |
| 65 | +./build-lib.sh |
| 66 | + |
| 67 | +# Build the Swift app |
| 68 | +swift build |
| 69 | + |
| 70 | +# Run |
| 71 | +.build/debug/SichuanVoiceInput |
| 72 | +``` |
| 73 | + |
| 74 | +To build a distributable DMG: |
| 75 | + |
| 76 | +```bash |
| 77 | +./make-dmg.sh |
| 78 | +# Output: dist/方言语音输入.dmg |
| 79 | +``` |
| 80 | + |
| 81 | +### Granting Permissions |
| 82 | + |
| 83 | +The app needs two macOS permissions to function: |
| 84 | + |
| 85 | +- **Microphone** — to capture your speech |
| 86 | +- **Accessibility** — to type text at your cursor (simulates Cmd+V) |
| 87 | + |
| 88 | +Go to **System Settings → Privacy & Security** to manage these. The app will prompt you on first use, but you may need to manually add it in Accessibility settings. |
| 89 | + |
| 90 | +> **Note**: If you move the app to a different location, macOS treats it as a new app and you'll need to re-grant Accessibility permission. |
| 91 | +
|
| 92 | +## Usage |
| 93 | + |
| 94 | +### Basic |
| 95 | + |
| 96 | +1. Launch the app — a microphone icon appears in the menu bar |
| 97 | +2. **Hold Right Option** and speak |
| 98 | +3. Release — text is typed at your cursor |
| 99 | + |
| 100 | +### Menu Bar |
| 101 | + |
| 102 | +Click the menu bar icon to access: |
| 103 | + |
| 104 | +| Item | Description | |
| 105 | +|---|---| |
| 106 | +| Status indicator | Shows current state (Ready / Recording / Transcribing / Loading) | |
| 107 | +| Recent transcriptions | Click any to copy to clipboard | |
| 108 | +| Hold / Toggle mode | Switch between input modes | |
| 109 | +| Reload Model | Re-initialize the ASR engine | |
| 110 | +| Remote Tunnel | Enable Cloudflare Tunnel for remote access | |
| 111 | +| Settings → Language | Switch UI between Chinese and English | |
| 112 | +| Settings → Accessibility / Microphone | Quick links to system permission settings | |
| 113 | + |
| 114 | +### Tips |
| 115 | + |
| 116 | +- **System audio is muted during recording** to prevent notification sounds from being captured. It's restored automatically when you stop. |
| 117 | +- **Clipboard is preserved** — the app temporarily uses the clipboard for text injection, but restores your previous clipboard content afterward. |
| 118 | +- The app **auto-starts at login** as a menu bar item. |
| 119 | + |
| 120 | +## Project Structure |
| 121 | + |
| 122 | +``` |
| 123 | +├── Package.swift # Swift Package Manager configuration |
| 124 | +├── build-lib.sh # Builds libqwen_asr.a (universal static library) |
| 125 | +├── make-dmg.sh # Packages into distributable DMG |
| 126 | +├── generate-icon.swift # Generates app icon |
| 127 | +├── Sources/ |
| 128 | +│ ├── App/ |
| 129 | +│ │ ├── SichuanVoiceInputApp.swift # Entry point |
| 130 | +│ │ └── AppDelegate.swift # Menu bar UI, recording lifecycle |
| 131 | +│ ├── Services/ |
| 132 | +│ │ ├── QwenASREngine.swift # Qwen3-ASR C library Swift wrapper |
| 133 | +│ │ ├── ModelManager.swift # Model download & caching |
| 134 | +│ │ ├── AudioCaptureService.swift # 16kHz mono PCM recording |
| 135 | +│ │ ├── HotkeyService.swift # Right Option key detection (30ms polling) |
| 136 | +│ │ ├── TextInjectionService.swift # Clipboard + Cmd+V injection |
| 137 | +│ │ ├── CloudflaredManager.swift # Optional Cloudflare Tunnel |
| 138 | +│ │ └── BonjourBroadcaster.swift # mDNS service discovery |
| 139 | +│ ├── Localization/ |
| 140 | +│ │ └── AppStrings.swift # Bilingual string management |
| 141 | +│ ├── Views/ # SwiftUI views |
| 142 | +│ ├── Design/ # Design tokens |
| 143 | +│ └── CQwenASR/ # C bridge module |
| 144 | +└── vendor/ |
| 145 | + └── qwen-asr/ # Pure C Qwen3-ASR inference engine |
| 146 | + ├── *.c, *.h # Source files |
| 147 | + ├── Makefile # Standalone build |
| 148 | + ├── LICENSE # Apache 2.0 |
| 149 | + └── include/ # Public headers |
| 150 | +``` |
| 151 | + |
| 152 | +## Technical Details |
| 153 | + |
| 154 | +- **ASR Engine**: Pure C implementation of Qwen3-ASR transformer, no Python/PyTorch dependency |
| 155 | +- **Acceleration**: Apple Accelerate framework (BLAS/LAPACK) for matrix operations, ARM NEON SIMD kernels |
| 156 | +- **Audio**: 16kHz mono PCM via AudioQueue API, 0.3–60s recording duration |
| 157 | +- **Inference speed**: ~8x realtime on Apple Silicon (e.g., 1.4s to transcribe 11s of audio on M3 Max) |
| 158 | +- **Memory**: ~3GB RSS when model is loaded |
| 159 | +- **Model storage**: `~/Library/Application Support/SichuanVoiceHost/qwen3-asr-0.6b/` |
| 160 | + |
| 161 | +## License |
| 162 | + |
| 163 | +MIT |
| 164 | + |
| 165 | +The bundled `vendor/qwen-asr/` inference engine is licensed under Apache 2.0. |
| 166 | +The Qwen3-ASR model weights (downloaded at runtime) are subject to the [Qwen License](https://huggingface.co/Qwen/Qwen3-ASR-0.6B/blob/main/LICENSE). |
| 167 | + |
| 168 | +## Acknowledgments |
| 169 | + |
| 170 | +- [Qwen3-ASR](https://huggingface.co/Qwen/Qwen3-ASR-0.6B) by Alibaba Qwen team — the speech recognition model |
| 171 | +- Built with Swift, C, and Apple Accelerate framework |
0 commit comments