@hoanghong/speaking-angular 0.5.0 → 0.6.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.
Files changed (3) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +166 -130
  3. package/package.json +9 -3
package/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 0.6.0
2
+
3
+ - Versioned overall local pronunciation score (harmonic mean of accuracy and completeness).
4
+ - Explicit score scale, availability, components, exclusions and calibration status.
5
+ - New clients accept older servers without inventing an overall score.
6
+
1
7
  ## 0.5.0
2
8
 
3
9
  - Optional multi-criteria local pronunciation diagnostics with methods, limitations and unavailable scores.
package/README.md CHANGED
@@ -1,192 +1,228 @@
1
1
  # @hoanghong/speaking-angular
2
2
 
3
- Component nhận dạng lời nói online dùng ngay. Chỉ cài package, chọn `serviceType`, ngôn ngữ và nhận callback **text + file audio**. Không khai báo URL, không tạo gateway, không nhập token, không copy worklet. Model chạy tại dịch vụ FSEL, không tải xuống máy người dùng. MIT. Angular 18.x, RxJS 7.8.
3
+ Angular 18 / RxJS 7.8 SDK for realtime transcription, audio upload and US English pronunciation diagnostics. Service connections, sessions and worklet loading are automatic; no service URL or service token is required. Models run on the service. MIT license.
4
4
 
5
- ## 1. Cài đặt
5
+ ## Install from npm
6
6
 
7
7
  ```bash
8
- npm install ./vendor/hoanghong-speaking-core-0.5.0.tgz ./vendor/hoanghong-speaking-angular-0.5.0.tgz
8
+ npm install @hoanghong/speaking-core@0.6.0 @hoanghong/speaking-angular@0.6.0
9
9
  ```
10
10
 
11
- Core được cài tự động. Với ứng dụng mới: `npx @angular/cli@18 new speaking-demo --standalone --routing=false --style=css`, rồi `cd speaking-demo` và chạy lệnh trên.
11
+ ## 1. Install from the version 0.6.0 release ZIP
12
12
 
13
- Bản 0.5.0 là bộ cài test local: giải nén ZIP và copy hai tarball vào `vendor/` trước.
14
- Chưa publish 0.5.0 lên registry. Các tính năng nhận dạng cũ vẫn dùng được.
13
+ Copy both npm tarballs into your application's vendor directory:
15
14
 
16
- ## Đánh giá phát âm tiếng Anh Mỹ (0.5.0)
15
+ ```bash
16
+ npm install ./vendor/hoanghong-speaking-core-0.6.0.tgz ./vendor/hoanghong-speaking-angular-0.6.0.tgz
17
+ ```
18
+
19
+ For a new application, first run npx @angular/cli@18 new speaking-demo --standalone --routing=false --style=css, then cd speaking-demo. These instructions use local archives and do not assume registry publication.
20
+
21
+ ## 2. Configure an application key, if supplied
17
22
 
18
- Thêm `SpeakingService` vào `providers` của component dùng để test, import từ
19
- `@hoanghong/speaking-angular`, rồi gọi trong class component:
23
+ Use the following src/app/app.config.ts when FSEL has provided a key. Without a key, use an empty providers array for the basic anonymous quota.
20
24
 
21
25
  ```ts
22
- constructor(private readonly speaking: SpeakingService) {}
23
-
24
- async assessPronunciation(file: File): Promise<void> {
25
- const result = await this.speaking.pronunciation.assessAudio(file, {
26
- referenceText: 'cat',
27
- expectedPhonemes: ['k', 'æ', 't'],
28
- filename: file.name,
29
- });
30
- console.log(result.phoneme_similarity, result.comparisons, result.warnings);
31
- }
26
+ import { ApplicationConfig } from '@angular/core';
27
+ import { provideSpeakingApp } from '@hoanghong/speaking-angular';
28
+
29
+ export const appConfig: ApplicationConfig = {
30
+ providers: [provideSpeakingApp({ appKey: 'YOUR_APP_KEY' })],
31
+ };
32
32
  ```
33
33
 
34
- Gọi bằng file vừa chọn hoặc `result.audio` trong callback `completed` của component hiện có.
35
- Có thể dùng câu/đoạn đọc: thay referenceText bằng đúng nội dung cần đọc và bỏ
36
- expectedPhonemes nếu server đã cài eSpeak; không dùng chuỗi âm của `cat` cho đoạn khác.
37
- Hỗ trợ audio tối đa 120 giây/25 MiB, reference 4096 ký tự, client chờ tối đa 11 phút.
38
- Thêm `signal: controller.signal` để hủy request. Hàm reject khi lỗi; UI cần catch và hiển thị.
39
- `calibrated=false`: similarity chỉ là đối chiếu âm vị, chưa phải điểm phát âm chính thức.
40
- Kết quả có timestamp, âm thiếu/thừa/thay thế, formant/pitch/intensity/PSD và warnings.
34
+ Use src/main.ts:
41
35
 
42
- Dùng `provideSpeakingApp` hiện có nếu có appKey. SDK tự cấp phiên riêng cho mỗi lần đánh giá,
43
- không nhập service token. Dịch vụ đánh giá phát âm và model phải
44
- được triển khai trước; 404/503 nghĩa là server chưa sẵn sàng. Bộ cài không triển khai server.
45
- Không đưa service credential vào ứng dụng.
36
+ ```ts
37
+ import { bootstrapApplication } from '@angular/platform-browser';
38
+ import { AppComponent } from './app/app.component';
39
+ import { appConfig } from './app/app.config';
46
40
 
47
- ## 2. Thêm component — ví dụ đầy đủ
41
+ bootstrapApplication(AppComponent, appConfig).catch(console.error);
42
+ ```
43
+
44
+ Application keys are visible application identifiers, not administrative credentials. Key quotas/status are managed server-side. An invalid/disabled key returns INVALID_APP_KEY rather than falling back to anonymous access. Never embed service credentials.
48
45
 
49
- Thay `src/app/app.component.ts` bằng:
46
+ ## 3. Complete pronunciation example
47
+
48
+ Replace src/app/app.component.ts below. The learner reads the displayed passage, selects a recording and clicks Assess pronunciation. Alternatively, record with the existing speaking component; its completed callback supplies the same audio File. Assessment is a separate explicit action.
50
49
 
51
50
  ```ts
52
51
  import { Component, OnDestroy } from '@angular/core';
53
- import { FselSpeakingComponent, SpeakingResult } from '@hoanghong/speaking-angular';
52
+ import {
53
+ FselSpeakingComponent, PronunciationAssessment, SpeakingError,
54
+ SpeakingResult, SpeakingService,
55
+ } from '@hoanghong/speaking-angular';
54
56
 
55
57
  @Component({
56
- selector: 'app-root', standalone: true,
58
+ selector: 'app-root',
59
+ standalone: true,
57
60
  imports: [FselSpeakingComponent],
61
+ providers: [SpeakingService],
58
62
  template: `
59
- <main style="max-width:800px;margin:auto;padding:20px">
60
- <h1>Luyện nói</h1>
61
- <fsel-speaking serviceType="realtime" initialLanguage="vi"
62
- (completed)="onCompleted($event)" (failed)="onFailed($event)" />
63
- <p>{{ text }}</p>
63
+ <main>
64
+ <h1>US English pronunciation practice</h1>
65
+ <p>Read this passage: {{ referenceText }}</p>
66
+ <label for="recording">Choose an audio recording (maximum 120 seconds)</label>
67
+ <input id="recording" type="file" accept="audio/*"
68
+ [disabled]="busy" (change)="selectFile($event)" />
69
+ <p>Or record the passage, then stop before 120 seconds:</p>
70
+ @if (!busy) {
71
+ <fsel-speaking serviceType="realtime" initialLanguage="en"
72
+ (completed)="onCompleted($event)" (failed)="onFailed($event)" />
73
+ }
64
74
  @if (audioUrl) {
65
75
  <audio controls [src]="audioUrl"></audio>
66
- <p><a [href]="audioUrl" [download]="filename">Tải file bài nói</a></p>
76
+ }
77
+ <button type="button" [disabled]="!audio || busy" (click)="assess()">
78
+ Assess pronunciation
79
+ </button>
80
+ <button type="button" [disabled]="!busy" (click)="cancel()">Cancel</button>
81
+ @if (busy) { <p role="status">Assessing pronunciation...</p> }
82
+ @if (assessment) {
83
+ <p>Phoneme similarity: {{ assessment.phoneme_similarity }} (uncalibrated)</p>
84
+ <p>Phoneme accuracy: {{ accuracy }}</p>
85
+ <p>Overall local pronunciation score: {{ overall }}</p>
86
+ @for (warning of assessment.warnings; track $index) { <p>{{ warning }}</p> }
67
87
  }
68
88
  <p role="alert">{{ error }}</p>
69
89
  </main>
70
90
  `,
71
91
  })
72
92
  export class AppComponent implements OnDestroy {
73
- text = ''; error = ''; filename = ''; audioUrl = '';
74
- onCompleted(result: SpeakingResult): void {
75
- if (this.audioUrl) URL.revokeObjectURL(this.audioUrl);
76
- this.text = result.text;
77
- this.filename = result.audio.name;
78
- this.audioUrl = URL.createObjectURL(result.audio);
79
- // result.audio là File: có thể đưa vào FormData để lưu ở hệ thống của bạn.
93
+ readonly referenceText = 'The cat is sitting on the mat.';
94
+ audio: File | null = null;
95
+ audioUrl = '';
96
+ assessment: PronunciationAssessment | null = null;
97
+ error = '';
98
+ busy = false;
99
+ private controller?: AbortController;
100
+ private destroyed = false;
101
+
102
+ constructor(private readonly speaking: SpeakingService) {}
103
+
104
+ get overall(): string {
105
+ const value = this.assessment?.overall;
106
+ return value?.status === 'estimated' && value.score != null
107
+ ? value.score.toFixed(1) + ' / ' + value.scale + ' (local estimate)'
108
+ : value?.reason ?? 'Unavailable: upgrade the server if needed';
80
109
  }
81
- onFailed(error: Error): void { this.error = error.message; }
82
- ngOnDestroy(): void { if (this.audioUrl) URL.revokeObjectURL(this.audioUrl); }
83
- }
84
- ```
85
110
 
86
- Giữ `src/main.ts` chuẩn Angular CLI; nếu cần tạo lại:
87
-
88
- ```ts
89
- import { bootstrapApplication } from '@angular/platform-browser';
90
- import { AppComponent } from './app/app.component';
91
- bootstrapApplication(AppComponent).catch(console.error);
92
- ```
111
+ get accuracy(): string {
112
+ const value = this.assessment?.breakdown?.accuracy;
113
+ return value?.status === 'estimated' && value.score != null
114
+ ? value.score.toFixed(1) + ' / 100 (estimate)'
115
+ : 'Unavailable';
116
+ }
93
117
 
94
- Không cần `provideSpeakingGateway` hoặc chỉnh assets trong `angular.json` khi dùng dịch vụ public. Nếu nâng cấp từ 0.2, bỏ provider gateway cũ để sử dụng dịch vụ public mặc định.
118
+ selectFile(event: Event): void {
119
+ this.setAudio((event.target as HTMLInputElement).files?.[0] ?? null);
120
+ }
95
121
 
96
- ## Key riêng của ứng dụng (cấu hình một lần)
122
+ onCompleted(result: SpeakingResult): void { this.setAudio(result.audio); }
123
+ onFailed(error: Error): void { this.error = error.message; }
97
124
 
98
- Nếu được FSEL cấp key riêng, thêm vào `src/app/app.config.ts`:
125
+ private setAudio(file: File | null): void {
126
+ if (this.audioUrl) URL.revokeObjectURL(this.audioUrl);
127
+ this.audio = file;
128
+ this.audioUrl = file ? URL.createObjectURL(file) : '';
129
+ this.assessment = null;
130
+ this.error = '';
131
+ }
99
132
 
100
- ```ts
101
- import { ApplicationConfig } from '@angular/core';
102
- import { provideSpeakingApp } from '@hoanghong/speaking-angular';
103
- export const appConfig: ApplicationConfig = {
104
- providers: [provideSpeakingApp({ appKey: 'KEY_DUOC_FSEL_CAP' })],
105
- };
106
- ```
133
+ async assess(): Promise<void> {
134
+ if (!this.audio || this.busy) return;
135
+ this.busy = true;
136
+ this.error = '';
137
+ this.assessment = null;
138
+ this.controller = new AbortController();
139
+ try {
140
+ const result = await this.speaking.pronunciation.assessAudio(this.audio, {
141
+ referenceText: this.referenceText,
142
+ filename: this.audio.name,
143
+ signal: this.controller.signal,
144
+ });
145
+ if (!this.destroyed) this.assessment = result;
146
+ } catch (error) {
147
+ if (!this.destroyed) {
148
+ this.error = error instanceof SpeakingError
149
+ ? error.code + ': ' + error.message
150
+ : 'Pronunciation assessment failed.';
151
+ }
152
+ } finally {
153
+ if (!this.destroyed) this.busy = false;
154
+ this.controller = undefined;
155
+ }
156
+ }
107
157
 
108
- Khi có appConfig, `main.ts` cần truyền nó cho bootstrap:
158
+ cancel(): void { this.controller?.abort(); }
109
159
 
110
- ```ts
111
- import { bootstrapApplication } from '@angular/platform-browser';
112
- import { AppComponent } from './app/app.component';
113
- import { appConfig } from './app/app.config';
114
- bootstrapApplication(AppComponent, appConfig).catch(console.error);
160
+ ngOnDestroy(): void {
161
+ this.destroyed = true;
162
+ this.cancel();
163
+ if (this.audioUrl) URL.revokeObjectURL(this.audioUrl);
164
+ }
165
+ }
115
166
  ```
116
167
 
117
- Component và callback text/audio không đổi; không cần URL. Đây là key định danh có thể quan sát trong frontend, không phải khóa quản trị. Hạn mức của key được FSEL quản lý phía server, thay đổi không cần build lại ứng dụng. Key sai/bị khóa trả INVALID_APP_KEY; không tự chuyển sang dùng ẩn danh. Bỏ cấu hình key thì dùng hạn mức public cơ bản.
168
+ Run npx ng serve and open the local address printed by Angular. Microphone capture requires HTTPS or localhost and user permission. The SDK does not automatically record on page load. The component currently uses its built-in interface labels; the example's own labels and comments are English.
118
169
 
119
- ## 3. Chạy
170
+ SpeakingService must be provided at the screen/component level as shown. provideSpeakingApp configures application identity; it does not replace that provider. The fsel-speaking component owns its recording/transcription lifecycle. Assessment consumes an additional session after recording/transcription. For upload-only pronunciation, the file input calls the pronunciation client directly without first creating a transcription job.
120
171
 
121
- ```bash
122
- npx ng serve
123
- ```
172
+ ## 4. Reference text and optional phonemes
124
173
 
125
- Mở localhost do CLI in ra → chọn ngôn ngữ → Bắt đầu nói → cho phép microphone → chờ “Đang nghe…” → nói → Dừng và lấy kết quả. Callback nhận text và WAV, ví dụ trên cho nghe lại/tải file. Production phải dùng HTTPS. Không ghi âm tự động.
174
+ Pronunciation supports en-US only. referenceText is the exact word, sentence or paragraph being read (1–4096 characters). Omit expectedPhonemes for normal passages; server-side text-to-phoneme support must be installed.
126
175
 
127
- ## 4. Chọn dịch vụ
176
+ For a specific word, add expectedPhonemes: ['k', 'æ', 't'] and set referenceText: 'cat' in the assessment options. These are complete model vocabulary tokens, not individual IPA characters. Do not include enclosing slashes or reuse this sequence for another passage.
128
177
 
129
- - `serviceType="realtime"`: microphone, text tạm khi nói, kết quả cuối kèm WAV PCM16 mono 16 kHz.
130
- - `serviceType="upload"`: chọn file audio, trả transcript và chính File đầu vào, giữ tên/định dạng.
131
- - Không đặt `serviceType`: hiện cả hai cách. `uploadEnabled=false` ẩn upload.
132
- - `initialLanguage`: `en` (Anh), `ja` (Nhật), `ko` (Hàn), `zh` (Trung), `vi` (Việt, mặc định).
178
+ Audio must be nonempty, at most 120 seconds and 25 MiB. WAV PCM16 mono at 16 kHz is suitable; the service validates duration/formats. Realtime transcription itself permits 300 seconds, so stop within 120 seconds for pronunciation. The assessment request timeout defaults to 11 minutes. AbortSignal cancels the client request; it does not refund quota or guarantee server inference cancellation. There is no automatic retry.
133
179
 
134
- Ví dụ upload: thay `serviceType="realtime"` bằng `serviceType="upload"`. Callback không đổi.
180
+ ## 5. Read the assessment
135
181
 
136
- ## 5. Kết quả trả về
182
+ | Field | Use |
183
+ | --- | --- |
184
+ | phoneme_similarity / phoneme_error_rate | Edit-based phoneme comparison, not an official grade |
185
+ | comparisons | match/substitution/deletion/insertion; expected/observed tokens and approximate seconds |
186
+ | observed_phonemes | Recognized tokens and approximate times |
187
+ | breakdown | Optional criteria, errors, signal and limitations |
188
+ | acoustic_frames / psd_frequencies_hz | Formants, pitch, intensity and spectral data |
189
+ | warnings | Interpretation and model limitations |
137
190
 
138
- `completed` nhận `SpeakingResult`:
191
+ breakdown may be absent or null with older services. Each criterion has score (0–100 or null), status (estimated/unavailable), method and reason. Display unavailable as "Unavailable", never zero. Display methods/reasons/limitations alongside estimates. Missing sounds can have null timestamps; counts refer to phonemes, not words.
139
192
 
140
- | Trường | Kiểu / ý nghĩa |
141
- | --- | --- |
142
- | `text` | String nhận dạng cuối; rỗng khi không có lời nói |
143
- | `audio` | File, dùng createObjectURL/FormData/arrayBuffer; realtime có tên speaking.wav |
144
- | `language` | en/ja/ko/zh/vi |
145
- | `serviceType` | realtime/upload |
146
- | `status` | succeeded/no_speech; các metadata gốc vẫn được giữ |
147
- | `result` | Transcript chi tiết từ server nếu có |
193
+ Accuracy = 100*M/(M+S+I); completeness = 100*(N-D)/N, with matches/substitutions/omissions/insertions M/S/D/I and reference count N. Completeness includes substitutions as covered. Similarity = 100*max(0, 1-(S+D+I)/N) and differs from accuracy. Fluency is an acoustic energy-continuity proxy affected by noise/intentional pauses. Prosody has pitch measurements without a score. Overall pronunciation is the harmonic mean of Accuracy and Completeness. Vocabulary, grammar and topic scores are unavailable. calibrated=false; approximate timing is not forced alignment. Do not use these diagnostics as educational grades, Azure scores or pass/fail thresholds.
148
194
 
149
- File realtime chứa âm thanh người dùng vừa nói, đã chuẩn hóa cho nhận dạng; không phải giọng AI đọc text. File không tự được lưu vĩnh viễn lên S3 hoặc cấp URL tải công khai. Ứng dụng sở hữu File sau callback, tự lưu nếu cần. Revoke object URL khi thay file/rời trang như ví dụ để tránh giữ RAM. Hủy/lỗi không phát callback thành công.
195
+ ## 6. Existing transcription component
150
196
 
151
- ## 6. Giới hạn và lỗi
197
+ Use serviceType="realtime" for microphone transcription; serviceType="upload" for audio-file transcription. Omitting serviceType displays both; [uploadEnabled]="false" hides upload. initialLanguage supports en/ja/ko/zh/vi (default vi).
152
198
 
153
- Dịch vụ public tự cấp phiên ngắn hạn. Mặc định server giới hạn 5 lượt/IP/ngày và 100 lượt/ngày cho mỗi instance, tính theo UTC; hạn mức có thể được FSEL điều chỉnh. Một phiên cấp mới tính một lượt kể cả khi nhận dạng thất bại. Người dùng cùng mạng có thể chung IP. Realtime tối đa 5 phút; buffer PCM tối đa khoảng 9,6 MB trước khi tạo WAV. Upload UI tối đa 25 MiB, server có thể giới hạn thấp hơn; chờ job tối đa 10 phút. Không tự reconnect/replay audio sau mất mạng. Rời màn ngừng thu/polling; job đã upload có thể còn chạy trên server.
199
+ completed emits SpeakingResult with text, audio (File), language, serviceType, status and optional detailed result. Realtime audio is WAV PCM16 mono at 16 kHz; upload preserves the selected file. An empty transcript may indicate no_speech. failed emits an Error; cancellation/failure does not emit successful audio. Use object URLs for playback/download and revoke them when no longer needed. Use FormData to store audio; files are not automatically persisted to permanent storage.
154
200
 
155
- `failed` nhận Error; lỗi dịch vụ có `code`/`status` qua SpeakingError. QUOTA_EXCEEDED/429: hết lượt, chờ ngày mới. 503: dịch vụ/model chưa sẵn sàng. 404: server chưa triển khai phiên bản dịch vụ public. Microphone denied: bật quyền site và dùng HTTPS/localhost. Mạng/CSP: cho phép kết nối, worklet tới dịch vụ FSEL theo chính sách ứng dụng. Server phải chạy bản hỗ trợ public SDK trước khi dùng 0.3.
201
+ ## 7. Quotas and troubleshooting
156
202
 
157
- API thấp của 0.2 vẫn có sẵn cho tích hợp tùy chỉnh; không cần dùng trong luồng trên. Microphone thiết bị và khả năng truy cập mạng cần kiểm tra trong ứng dụng triển khai thực tế.
203
+ Basic quota defaults to 5 sessions per IP/day and 100 per instance/day (UTC), subject to operator changes. New sessions consume quota even on processing failure. Application-key quota is managed by FSEL. Realtime buffers approximately 9.6 MB PCM; upload UI accepts up to 25 MiB and polls up to 10 minutes. Leaving the component stops capture/polling, although accepted server jobs may continue. There is no automatic reconnect/replay.
158
204
 
205
+ Handle SpeakingError.code/status/message: INVALID_REFERENCE/INVALID_AUDIO for input, INVALID_APP_KEY/401 for key issues, QUOTA_EXCEEDED/429 for quota, 415 for unsupported formats, 422 for validation/no recognized phonemes, 404 for missing functionality and 503 for service/model readiness. Check browser microphone permissions and application network/CSP policies for capture/connection failures.
159
206
 
160
- ## Application key
207
+ The bundle installs clients; it does not deploy models or prove hosted readiness. Physical microphone/playback and real learner scoring require separate device/service verification.
161
208
 
162
- Pass the application key provided by FSEL as `appKey`. The SDK handles service
163
- connections automatically. Quotas and key status are managed by the service.
164
- App keys identify an application and are visible in browser/mobile applications.
165
209
 
166
- ```ts
167
- provideSpeakingApp({ appKey: environment.speakingAppKey });
168
- ```
210
+ ## Overall pronunciation output (0.6.0)
211
+
212
+ Use `result.overall?.score` for the overall chart.
213
+ It is a local estimate, the harmonic mean of unrounded Accuracy and Completeness:
214
+ `2*A*C/(A+C)`, or 0 if A+C=0. Fluency and Prosody are excluded. This is not an
215
+ Azure or calibrated educational grade. `phoneme_similarity` is a separate legacy
216
+ edit-distance diagnostic and can be zero while the overall score is positive.
169
217
 
218
+ The overall object includes `version=local-accuracy-completeness-v1`, `scale=100`,
219
+ `calibrated=false`, `status`, `method`, `reason`, `components` and
220
+ `excluded_components` (Flutter: `excludedComponents`).
221
+ Render null/unavailable scores as unavailable; preserve valid zero values.
222
+ An older server can omit `overall`; the SDK never computes a replacement score.
223
+ `breakdown.pronunciation` mirrors the overall criterion for compatibility.
224
+ The server must be upgraded as well as the SDK.
170
225
 
171
- ## Multi-criteria pronunciation diagnostics (0.5.0)
172
-
173
- Optional `breakdown` contains accuracy, completeness, fluency, prosody, pronunciation,
174
- vocabulary, grammar and topic. Each has score (0–100 or null), status
175
- (estimated/unavailable), method and reason. These are local diagnostics, not Azure
176
- scores or calibrated grades. Older services may omit breakdown.
177
-
178
- - Accuracy = 100 * matches / (matches + substitutions + insertions), at phoneme level.
179
- - Completeness = 100 * (reference phonemes - omissions) / reference phonemes.
180
- Substitutions count as covered; this is coverage, not correctness.
181
- - Fluency is an energy continuity proxy = 100 * (1 - internal pause seconds / active span).
182
- 20 ms RMS windows, threshold=max(0.005, 0.1*peak RMS), internal gaps >=250 ms.
183
- Excludes leading/trailing silence; requires >=2 s audio and >=1 s active span.
184
- Noise may inflate the value and intentional pauses may lower it; this is not VAD/native fluency.
185
- - Prosody has no score. Pitch P90-P10 and standard deviation (semitones) are reported
186
- with >=20 voiced frames and >=2 s audio. Variation does not imply correct intonation.
187
- - Overall pronunciation and content scores remain null: no calibrated composite,
188
- stress model, transcript/grammar evaluator or topic evaluator is configured.
189
-
190
- errors counts phoneme matches/substitutions/omissions/insertions. signal.pauses are
191
- acoustic intervals, not linguistic unexpected/missing breaks. Consult limitations
192
- and version=local-diagnostics-v1 before interpreting estimates.
226
+ ```json
227
+ {"overall":{"score":50,"status":"estimated","method":"accuracy_completeness_hmean: 2*A*C/(A+C); zero if A+C=0","reason":null,"version":"local-accuracy-completeness-v1","scale":100,"calibrated":false,"components":["accuracy","completeness"],"excluded_components":["fluency","prosody"]}}
228
+ ```
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hoanghong/speaking-angular",
3
- "version": "0.5.0",
4
- "description": "Ready-to-use online speaking: five languages, microphone realtime and audio upload",
3
+ "version": "0.6.0",
4
+ "description": "Angular 18 SDK for speech transcription, audio upload and versioned local pronunciation assessment with typed overall and component scores.",
5
5
  "type": "module",
6
6
  "peerDependencies": {
7
7
  "@angular/common": ">=18 <19",
@@ -11,13 +11,19 @@
11
11
  "sideEffects": false,
12
12
  "license": "MIT",
13
13
  "dependencies": {
14
- "@hoanghong/speaking-core": "^0.5.0",
14
+ "@hoanghong/speaking-core": "^0.6.0",
15
15
  "tslib": "^2.3.0"
16
16
  },
17
17
  "publishConfig": {
18
18
  "access": "public",
19
19
  "registry": "https://registry.npmjs.org/"
20
20
  },
21
+ "keywords": [
22
+ "speech",
23
+ "pronunciation-assessment",
24
+ "speech-to-text",
25
+ "sdk"
26
+ ],
21
27
  "module": "fesm2022/hoanghong-speaking-angular.mjs",
22
28
  "typings": "index.d.ts",
23
29
  "exports": {