@lanlinling/pronunciation-providers
v0.1.2
Published
Multi-provider pronunciation assessment adapter registry (Xunfei ISE) — ported from the english_testing MVP's ise_client.py.
Readme
@lanlinling/pronunciation-providers
Multi-provider pronunciation assessment adapter registry — currently Xunfei
ISE (讯飞语音评测), ported from the english_testing MVP project's
mvp/ise_client.py.
This is a separate capability from TTS/ASR in @bluemomo/audio-providers:
given a reference text and a recording of someone reading it aloud, it
returns a structured pronunciation score (accuracy/fluency/completeness,
down to the word/syllable/phoneme level) — not synthesized audio or a plain
transcript.
Install
{
"dependencies": {
"@lanlinling/pronunciation-providers": "0.1.0"
}
}# pnpm-workspace.yaml
onlyBuiltDependencies:
- "@lanlinling/pronunciation-providers"Does it read API keys from my environment?
No. Credentials are always passed explicitly via the credentials
field — nothing here reads process.env.
Usage
Xunfei ISE needs three credential fields (not the {apiKey, baseUrl} shape
used elsewhere in this repo — see src/types.ts for why):
import { assessPronunciation } from '@lanlinling/pronunciation-providers';
const result = await assessPronunciation(
{
providerId: 'xunfei-ise',
credentials: {
appId: process.env.XF_APPID!,
apiKey: process.env.XF_APIKey!,
apiSecret: process.env.XF_APISecret!,
},
refText: 'The quick brown fox jumps over the lazy dog.',
category: 'read_sentence', // or 'read_word' / 'read_chapter'
},
pcmBuffer, // 16kHz/16-bit/mono PCM
);
console.log(result.totalScore, result.accuracyScore, result.fluencyScore);
for (const word of result.words) {
console.log(word.word, word.accuracyScore, word.errorType);
}assessPronunciation() is a batch convenience wrapper (hand over the whole
recording, await one result). For lower-latency "score as the user speaks"
UIs, use the streaming session directly:
import { createPronunciationSession } from '@lanlinling/pronunciation-providers';
const session = await createPronunciationSession({
providerId: 'xunfei-ise',
credentials: { appId, apiKey, apiSecret },
refText: 'The quick brown fox jumps over the lazy dog.',
});
// as PCM chunks arrive from the mic:
session.feed(pcmChunk);
// ...
session.finish();
const result = await session.getResult();This exact round trip — Doubao TTS synthesizes a sentence, ffmpeg converts it to 16k/16-bit/mono PCM, this package scores it against the same reference text — is what this package was smoke-tested with against a live Xunfei account (real API call, not a fixture).
See TROUBLESHOOTING.md for protocol quirks (the duplicate result-tag XML shape, frame sizing, etc.).
