| name | speak-core-workflow-b |
| description | Execute Speak secondary workflow: Pronunciation Training with detailed phoneme analysis.
Use when implementing pronunciation drills, speech scoring,
or targeted pronunciation improvement features.
Trigger with phrases like "speak pronunciation training",
"speak speech scoring", "secondary speak workflow".
|
| allowed-tools | Read, Write, Edit, Bash(npm:*), Grep |
| version | 1.0.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
Speak Core Workflow B: Pronunciation Training
Overview
Secondary workflow for Speak: Detailed pronunciation training with phoneme-level analysis and targeted practice.
Prerequisites
- Completed
speak-install-auth setup
- Familiarity with
speak-core-workflow-a
- Valid API credentials configured
- High-quality audio input capabilities
Instructions
Step 1: Initialize Pronunciation Session
import {
SpeakClient,
PronunciationTrainer,
PhonemeAnalyzer,
} from '@speak/language-sdk';
interface PronunciationConfig {
targetLanguage: string;
difficulty: 'beginner' | 'intermediate' | 'advanced';
focusPhonemes?: string[];
category?: 'vowels' | 'consonants' | 'tones' | 'all';
}
async function initializePronunciationTraining(
client: SpeakClient,
config: PronunciationConfig
): Promise<PronunciationTrainer> {
const trainer = new PronunciationTrainer(client, {
language: config.targetLanguage,
difficulty: config.difficulty,
adaptiveMode: true,
});
await trainer.initialize();
if (config.) {
trainer.(config.);
}
trainer;
}
Step 2: Implement Drill Session
interface DrillItem {
id: string;
text: string;
romanization?: string;
translation: string;
audioUrl: string;
targetPhonemes: string[];
difficulty: number;
}
interface DrillResult {
item: DrillItem;
userAudio: ArrayBuffer;
scores: PronunciationScores;
phonemeDetails: PhonemeResult[];
feedback: string[];
}
async function runPronunciationDrill(
trainer: PronunciationTrainer,
drillCount: number = 10
): Promise<DrillSession> {
const session = await trainer.startDrillSession({
itemCount: drillCount,
repeatOnMistake: true,
minScore: 70,
});
const results: DrillResult[] = [];
(!session.) {
item = session.();
.();
.();
(item.) {
.();
}
.();
.();
(item.);
userAudio = ();
result = session.({
: item.,
: userAudio,
});
results.({
item,
userAudio,
: result.,
: result.,
: result.,
});
(result);
(result.. < && session.) {
.();
}
}
session.();
}
Step 3: Phoneme-Level Analysis
interface PhonemeResult {
phoneme: string;
expected: string;
actual: string;
score: number;
issues: PhonemeIssue[];
visualGuide?: string;
}
interface PhonemeIssue {
type: 'substitution' | 'omission' | 'addition' | 'distortion';
description: string;
tip: string;
}
function displayPronunciationFeedback(result: DrillResult) {
console.log(`\n📊 Pronunciation Score: ${result.scores.overall}/100`);
console.log(` Accuracy: ${result.scores.accuracy}/100`);
console.log(` Fluency: ${result.scores.fluency}/100`);
console.log(` Intonation: ${result.scores.intonation}/100`);
const problemPhonemes = result.phonemeDetails.( p. < );
(problemPhonemes. > ) {
.();
( p problemPhonemes) {
.();
( issue p.) {
.();
.();
}
}
}
(result.. > ) {
.();
result..( .());
}
}
Step 4: Adaptive Practice Generation
interface WeaknessAnalysis {
phoneme: string;
averageScore: number;
attemptCount: number;
trend: 'improving' | 'stable' | 'declining';
suggestedDrills: DrillItem[];
}
async function generateAdaptivePractice(
trainer: PronunciationTrainer,
userHistory: DrillResult[]
): Promise<AdaptivePracticeSession> {
const weaknesses = analyzeWeaknesses(userHistory);
const adaptiveSession = await trainer.createAdaptiveSession({
targetWeaknesses: weaknesses.map(w => w.phoneme),
intensity: 'focused',
maxDuration: 15 * 60 * 1000,
});
console.log('\n🎯 Adaptive Practice Plan:');
console.log(`Focus areas: `);
adaptiveSession;
}
(): [] {
phonemeStats = <, []>();
( result results) {
( p result.) {
(!phonemeStats.(p.)) {
phonemeStats.(p., []);
}
phonemeStats.(p.)!.(p.);
}
}
: [] = [];
( [phoneme, scores] phonemeStats) {
avg = scores.( a + b, ) / scores.;
(avg < ) {
weaknesses.({
phoneme,
: avg,
: scores.,
: (scores),
: [],
});
}
}
weaknesses.( a. - b.);
}
Complete Workflow Example
async function pronunciationTrainingWorkflow() {
const client = getSpeakClient();
const config: PronunciationConfig = {
targetLanguage: 'ko',
difficulty: 'intermediate',
focusPhonemes: ['ㄱ', 'ㅋ', 'ㄲ'],
category: 'consonants',
};
console.log('Starting pronunciation training...');
console.log(`Language: ${config.targetLanguage}`);
console.log(`Focus: ${config.focusPhonemes?.join(', ') || 'General'}`);
const trainer = await initializePronunciationTraining(client, config);
console.log('\n📝 Initial Assessment...');
const assessment = await trainer.runAssessment();
console.log(`Baseline score: /100`);
drillResults = (trainer, );
adaptiveSession = (
trainer,
drillResults.
);
adaptiveSession.();
summary = trainer.();
.();
.();
.();
.();
summary;
}
Workflow Comparison
| Aspect | Workflow A (Conversation) | Workflow B (Pronunciation) |
|---|
| Primary Focus | Communication | Accuracy |
| Feedback Type | Holistic | Phoneme-level |
| Session Style | Free-form dialogue | Structured drills |
| Pacing | User-driven | System-driven |
| Best For | Fluency building | Accent reduction |
Output
- Detailed phoneme-level scores
- Visual pronunciation guides
- Adaptive practice recommendations
- Progress tracking over time
- Weakness identification
Error Handling
| Error | Cause | Solution |
|---|
| Audio Too Short | Brief recording | Minimum 0.5s audio |
| Background Noise | Poor recording conditions | Prompt for quieter environment |
| Phoneme Not Detected | Unclear speech | Slow down and articulate |
| Model Loading Failed | Network issue | Retry with fallback |
Resources
Next Steps
For common errors, see speak-common-errors.