A language learning app focused on pronunciation practice.
Users listen to native speaker audio, record their own pronunciation, and receive feedback based on speech recognition accuracy.
Standard speech-to-text APIs are optimized for transcription, not pronunciation assessment, and often accept poor pronunciations as correct. We developed a custom deep learning model for Mandarin Chinese trained on the AISHELL dataset, specifically architected to evaluate syllable-level pronunciation accuracy rather than just recognize speech.
# 1. Set up Python tool
make setup
# 2. Install repo git hooks (pre-commit formatting)
make install-hooks
# 3. Add your OpenAI API key
echo "OPENAI__API_KEY=sk-your-key" > tools/text_gen/.env
# 4. Generate content (text + audio) and export to Flutter
make generate
# 5. Run the app
make runspeaktolearn/
├── apps/
│ └── mobile_flutter/ # Flutter mobile app (iOS/Android)
├── tools/
│ └── text_gen/ # Python CLI for generating learning content
├── shared/
│ └── data_schema/ # JSON schemas for data contracts
└── .doc/ # Architecture documentation
| Tool | Version | Purpose |
|---|---|---|
| Flutter SDK | 3.8.1+ | Mobile app development |
| Python | 3.11+ | Content generation tool |
| uv | latest | Python package manager |
| Android Studio | latest | Android emulator & SDK |
| Xcode | latest | iOS simulator (macOS only) |
- Flutter: https://docs.flutter.dev/get-started/install
- Python: https://www.python.org/downloads/
- uv: https://docs.astral.sh/uv/getting-started/installation/
- Android Studio: https://developer.android.com/studio
git clone <repository-url>
cd speaktolearn# Navigate to the Flutter project
cd apps/mobile_flutter
# Get dependencies
flutter pub get
# Generate code (freezed, json_serializable)
dart run build_runner build --delete-conflicting-outputs
# Verify setup
flutter doctor# Navigate to the Python tool
cd tools/text_gen
# Create virtual environment with uv
uv venv .venv
# Activate the virtual environment
# Windows (PowerShell):
.venv\Scripts\Activate.ps1
# Windows (Git Bash/MSYS2):
source .venv/Scripts/activate
# macOS/Linux:
source .venv/bin/activate
# Install dependencies
uv pip install -e ".[dev]"Create a .env file in tools/text_gen/:
cd tools/text_gen
cp .env.example .envEdit .env and add your OpenAI API key:
OPENAI__API_KEY=sk-your-api-key-here
OPENAI__MODEL=gpt-4o
TTS__PROVIDER=openaiOption A: From Android Studio
- Open Android Studio
- Go to Tools > Device Manager
- Click the play button next to your virtual device
Option B: From Command Line
# List available emulators
emulator -list-avds
# Start an emulator (replace with your AVD name)
emulator -avd Pixel_7_API_34flutter devicesYou should see your emulator listed:
sdk gphone64 x86 64 (mobile) • emulator-5554 • android-x64 • Android 14 (API 34)
cd apps/mobile_flutter
flutter run# Open Simulator app
open -a Simulator
# Or start a specific device
xcrun simctl boot "iPhone 15 Pro"cd apps/mobile_flutter
flutter runWhile the app is running:
- Press
rfor hot reload (preserves state) - Press
Rfor hot restart (resets state) - Press
qto quit
cd tools/text_gen
# Activate virtual environment
source .venv/Scripts/activate # or .venv\Scripts\Activate.ps1 on Windows
# Generate 50 Chinese sentences (HSK1 level)
text-gen generate --language zh-CN --count 50 --tags hsk1,daily --difficulty 1
# Generate with different difficulty
text-gen generate --language zh-CN --count 20 --tags hsk2 --difficulty 2# Generate audio for existing dataset
text-gen audio output/sentences.zh.json --voices female,maletext-gen full --language zh-CN --count 50 --tags hsk1text-gen export --input output/ --flutter-assets ../apps/mobile_flutter/assets/text-gen validate output/sentences.zh.jsoncd apps/mobile_flutter
# Run in debug mode
flutter run
# Run with specific device
flutter run -d emulator-5554
# Build APK
flutter build apk
# Build iOS
flutter build ios
# Run tests
flutter test
# Analyze code
flutter analyzeRun once per clone to enable pre-commit checks:
make install-hooksThe hook formats staged apps/mobile_flutter/**/*.dart files before commit and re-stages them automatically. This prevents CI failures from dart format --set-exit-if-changed.
cd tools/text_gen
# Run tests
pytest -v
# Type checking
mypy text_gen/
# Linting
ruff check text_gen/
# Format code
ruff format text_gen/"No devices found"
# Check Flutter setup
flutter doctor -v
# Ensure emulator is running
flutter devicesBuild errors after pulling changes
cd apps/mobile_flutter
flutter clean
flutter pub get
dart run build_runner build --delete-conflicting-outputs"ModuleNotFoundError"
# Ensure virtual environment is activated
source .venv/Scripts/activate
# Reinstall package
uv pip install -e ".[dev]""UnicodeDecodeError" on Windows
- Already fixed in codebase - uses UTF-8 encoding for prompt files
API Authentication Error
- Verify
.envfile exists with correctOPENAI__API_KEY - Check API key is valid at https://platform.openai.com/api-keys
- Listen to native speaker audio examples
- Record your own pronunciation
- Get pronunciation feedback via speech recognition
- Track learning progress
- Browse and select practice sentences
- Generate sentences using GPT-4
- Multiple difficulty levels (HSK1-5)
- Tag-based content filtering
- Pinyin romanization included
- TTS audio generation (OpenAI voices)
- JSON Schema validation
MIT
