@hoanghong/speaking-core 0.4.3 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## 0.5.0
2
+
3
+ - Optional multi-criteria local pronunciation diagnostics with methods, limitations and unavailable scores.
4
+ - Compatible with older service responses.
5
+
1
6
  ## 0.4.3
2
7
 
3
8
  - Remove service addresses from public integration examples; no runtime changes.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @hoanghong/speaking-core
2
2
 
3
- SDK online cho người tự làm UI. Bản test 0.4.3 cài bằng `npm install ./vendor/hoanghong-speaking-core-0.4.3.tgz` từ bộ ZIP, chưa publish registry. Angular dùng @hoanghong/speaking-angular với component có sẵn; Flutter dùng fsel_speaking. MIT.
3
+ SDK online cho người tự làm UI. Bản test 0.5.0 cài bằng `npm install ./vendor/hoanghong-speaking-core-0.5.0.tgz` từ bộ ZIP, chưa publish registry. Angular dùng @hoanghong/speaking-angular với component có sẵn; Flutter dùng fsel_speaking. MIT.
4
4
 
5
5
  ## Đánh giá phát âm tiếng Anh Mỹ
6
6
 
@@ -87,3 +87,27 @@ App keys identify an application and are visible in browser/mobile applications.
87
87
  ```ts
88
88
  createSpeakingService({ appKey: 'YOUR_APP_KEY' });
89
89
  ```
90
+
91
+
92
+ ## Multi-criteria pronunciation diagnostics (0.5.0)
93
+
94
+ Optional `breakdown` contains accuracy, completeness, fluency, prosody, pronunciation,
95
+ vocabulary, grammar and topic. Each has score (0–100 or null), status
96
+ (estimated/unavailable), method and reason. These are local diagnostics, not Azure
97
+ scores or calibrated grades. Older services may omit breakdown.
98
+
99
+ - Accuracy = 100 * matches / (matches + substitutions + insertions), at phoneme level.
100
+ - Completeness = 100 * (reference phonemes - omissions) / reference phonemes.
101
+ Substitutions count as covered; this is coverage, not correctness.
102
+ - Fluency is an energy continuity proxy = 100 * (1 - internal pause seconds / active span).
103
+ 20 ms RMS windows, threshold=max(0.005, 0.1*peak RMS), internal gaps >=250 ms.
104
+ Excludes leading/trailing silence; requires >=2 s audio and >=1 s active span.
105
+ Noise may inflate the value and intentional pauses may lower it; this is not VAD/native fluency.
106
+ - Prosody has no score. Pitch P90-P10 and standard deviation (semitones) are reported
107
+ with >=20 voiced frames and >=2 s audio. Variation does not imply correct intonation.
108
+ - Overall pronunciation and content scores remain null: no calibrated composite,
109
+ stress model, transcript/grammar evaluator or topic evaluator is configured.
110
+
111
+ errors counts phoneme matches/substitutions/omissions/insertions. signal.pauses are
112
+ acoustic intervals, not linguistic unexpected/missing breaks. Consult limitations
113
+ and version=local-diagnostics-v1 before interpreting estimates.
@@ -26,6 +26,47 @@ export interface PronunciationAcousticFrame {
26
26
  intensity_db: number | null;
27
27
  psd_power_per_hz: number[];
28
28
  }
29
+ /** Local estimates, not Azure-equivalent or calibrated educational scores. */
30
+ export interface PronunciationCriterion {
31
+ score: number | null;
32
+ status: 'estimated' | 'unavailable';
33
+ method: string;
34
+ reason: string | null;
35
+ }
36
+ export interface PronunciationBreakdown {
37
+ version: 'local-diagnostics-v1';
38
+ scope: 'scripted_phoneme_diagnostics';
39
+ calibrated: false;
40
+ accuracy: PronunciationCriterion;
41
+ completeness: PronunciationCriterion;
42
+ fluency: PronunciationCriterion;
43
+ prosody: PronunciationCriterion;
44
+ pronunciation: PronunciationCriterion;
45
+ vocabulary: PronunciationCriterion;
46
+ grammar: PronunciationCriterion;
47
+ topic: PronunciationCriterion;
48
+ errors: {
49
+ matches: number;
50
+ substitutions: number;
51
+ omissions: number;
52
+ insertions: number;
53
+ };
54
+ signal: {
55
+ speech_span_seconds: number;
56
+ internal_pause_seconds: number;
57
+ pause_ratio: number | null;
58
+ pauses: Array<{
59
+ start: number;
60
+ end: number;
61
+ duration: number;
62
+ }>;
63
+ energy_threshold: number;
64
+ pitch_range_semitones: number | null;
65
+ pitch_std_semitones: number | null;
66
+ voiced_frames: number;
67
+ };
68
+ limitations: string[];
69
+ }
29
70
  export interface PronunciationAssessment {
30
71
  reference_text: string;
31
72
  language: 'en-US';
@@ -41,6 +82,8 @@ export interface PronunciationAssessment {
41
82
  psd_frequencies_hz: number[];
42
83
  model: string;
43
84
  warnings: string[];
85
+ /** Optional for compatibility with older service versions. */
86
+ breakdown?: PronunciationBreakdown | null;
44
87
  }
45
88
  export interface AssessPronunciationOptions {
46
89
  referenceText: string;
@@ -42,6 +42,21 @@ export class PronunciationClient {
42
42
  typeof body.phoneme_similarity !== 'number' || !Array.isArray(body.comparisons)) {
43
43
  throw new SpeakingError('INVALID_RESPONSE', 'Invalid pronunciation assessment response');
44
44
  }
45
+ if (body.breakdown != null) {
46
+ const breakdown = body.breakdown;
47
+ const names = ['accuracy', 'completeness', 'fluency', 'prosody', 'pronunciation', 'vocabulary', 'grammar', 'topic'];
48
+ if (breakdown.version !== 'local-diagnostics-v1' || breakdown.calibrated !== false ||
49
+ breakdown.scope !== 'scripted_phoneme_diagnostics' || !breakdown.signal || !breakdown.errors ||
50
+ !Array.isArray(breakdown.limitations) || names.some(name => {
51
+ const criterion = breakdown[name];
52
+ return !criterion || typeof criterion.method !== 'string' ||
53
+ (criterion.status !== 'estimated' && criterion.status !== 'unavailable') ||
54
+ (criterion.status === 'unavailable' ? criterion.score !== null :
55
+ typeof criterion.score !== 'number' || !Number.isFinite(criterion.score) || criterion.score < 0 || criterion.score > 100);
56
+ })) {
57
+ throw new SpeakingError('INVALID_RESPONSE', 'Invalid pronunciation diagnostic breakdown');
58
+ }
59
+ }
45
60
  return body;
46
61
  }
47
62
  finally {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hoanghong/speaking-core",
3
- "version": "0.4.3",
3
+ "version": "0.5.0",
4
4
  "description": "Online speaking SDK: gateway configuration, realtime microphone and audio upload",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",