lookatstudy-termux-voice 0.12.1
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/README.md +11 -0
- package/addon-static-import.js +70 -0
- package/addon.js +98 -0
- package/audio-tagg.js +45 -0
- package/keyword-spotter.js +68 -0
- package/libonnxruntime.so +0 -0
- package/libsherpa-onnx-c-api.so +0 -0
- package/non-streaming-asr.js +158 -0
- package/non-streaming-speaker-diarization.js +38 -0
- package/non-streaming-speech-denoiser.js +32 -0
- package/non-streaming-tts.js +116 -0
- package/online-speech-denoiser.js +46 -0
- package/package.json +68 -0
- package/punctuation.js +43 -0
- package/resampler.js +80 -0
- package/sherpa-onnx.js +49 -0
- package/sherpa-onnx.node +0 -0
- package/speaker-identification.js +152 -0
- package/spoken-language-identification.js +38 -0
- package/streaming-asr.js +130 -0
- package/types.js +787 -0
- package/vad.js +134 -0
package/package.json
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "lookatstudy-termux-voice",
|
|
3
|
+
"version": "0.12.1",
|
|
4
|
+
"description": "Speech-to-text, text-to-speech, speaker diarization, and speech enhancement using Next-gen Kaldi without internet connection [termux android-arm64 build with bundled .so]",
|
|
5
|
+
"main": "sherpa-onnx.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/Kaiji-Z/LookatStudy.git"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"speech to text",
|
|
15
|
+
"text to speech",
|
|
16
|
+
"transcription",
|
|
17
|
+
"real-time speech recognition",
|
|
18
|
+
"without internet connection",
|
|
19
|
+
"locally",
|
|
20
|
+
"local",
|
|
21
|
+
"embedded systems",
|
|
22
|
+
"open source",
|
|
23
|
+
"diarization",
|
|
24
|
+
"speaker diarization",
|
|
25
|
+
"speaker recognition",
|
|
26
|
+
"speaker",
|
|
27
|
+
"speaker segmentation",
|
|
28
|
+
"speaker verification",
|
|
29
|
+
"spoken language identification",
|
|
30
|
+
"sherpa",
|
|
31
|
+
"zipformer",
|
|
32
|
+
"asr",
|
|
33
|
+
"tts",
|
|
34
|
+
"stt",
|
|
35
|
+
"c++",
|
|
36
|
+
"onnxruntime",
|
|
37
|
+
"onnx",
|
|
38
|
+
"ai",
|
|
39
|
+
"next-gen kaldi",
|
|
40
|
+
"offline",
|
|
41
|
+
"privacy",
|
|
42
|
+
"open source",
|
|
43
|
+
"streaming speech recognition",
|
|
44
|
+
"speech",
|
|
45
|
+
"recognition",
|
|
46
|
+
"vad",
|
|
47
|
+
"node-addon-api",
|
|
48
|
+
"speaker id",
|
|
49
|
+
"language id",
|
|
50
|
+
"speech enhancement",
|
|
51
|
+
"denoising"
|
|
52
|
+
],
|
|
53
|
+
"author": "The next-gen Kaldi team",
|
|
54
|
+
"license": "Apache-2.0",
|
|
55
|
+
"bugs": {
|
|
56
|
+
"url": "https://github.com/csukuangfj/sherpa-onnx/issues"
|
|
57
|
+
},
|
|
58
|
+
"homepage": "https://github.com/csukuangfj/sherpa-onnx#readme",
|
|
59
|
+
"optionalDependencies": {
|
|
60
|
+
"sherpa-onnx-darwin-arm64": "^1.13.6",
|
|
61
|
+
"sherpa-onnx-darwin-x64": "^1.13.6",
|
|
62
|
+
"sherpa-onnx-linux-x64": "^1.13.6",
|
|
63
|
+
"sherpa-onnx-linux-arm64": "^1.13.6",
|
|
64
|
+
"sherpa-onnx-win-x64": "^1.13.6",
|
|
65
|
+
"sherpa-onnx-win-ia32": "^1.13.6"
|
|
66
|
+
},
|
|
67
|
+
"sherpaVersion": "1.13.6"
|
|
68
|
+
}
|
package/punctuation.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/** @typedef {import('./types').OfflinePunctuationHandle} OfflinePunctuationHandle */
|
|
2
|
+
/** @typedef {import('./types').OfflinePunctuationConfig} OfflinePunctuationConfig */
|
|
3
|
+
/** @typedef {import('./types').OnlinePunctuationConfig} OnlinePunctuationConfig */
|
|
4
|
+
/** @typedef {import('./types').OnlinePunctuationHandle} OnlinePunctuationHandle */
|
|
5
|
+
|
|
6
|
+
const addon = require('./addon.js');
|
|
7
|
+
|
|
8
|
+
class OfflinePunctuation {
|
|
9
|
+
/**
|
|
10
|
+
* @param {OfflinePunctuationConfig} config
|
|
11
|
+
*/
|
|
12
|
+
constructor(config) {
|
|
13
|
+
this.handle = addon.createOfflinePunctuation(config);
|
|
14
|
+
this.config = config;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Add punctuation to `text` and return the punctuated text.
|
|
18
|
+
* @param {string} text
|
|
19
|
+
* @returns {string}
|
|
20
|
+
*/
|
|
21
|
+
addPunct(text) {
|
|
22
|
+
return addon.offlinePunctuationAddPunct(this.handle, text);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
class OnlinePunctuation {
|
|
27
|
+
/**
|
|
28
|
+
* @param {OnlinePunctuationConfig} config
|
|
29
|
+
*/
|
|
30
|
+
constructor(config) {
|
|
31
|
+
this.handle = addon.createOnlinePunctuation(config);
|
|
32
|
+
this.config = config;
|
|
33
|
+
}
|
|
34
|
+
/** @param {string} text @returns {string} */
|
|
35
|
+
addPunct(text) {
|
|
36
|
+
return addon.onlinePunctuationAddPunct(this.handle, text);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
module.exports = {
|
|
41
|
+
OfflinePunctuation,
|
|
42
|
+
OnlinePunctuation,
|
|
43
|
+
}
|
package/resampler.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/** @typedef {import('./types').LinearResamplerHandle} LinearResamplerHandle */
|
|
2
|
+
|
|
3
|
+
const addon = require('./addon.js');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A linear resampler that converts audio from one sample rate to another.
|
|
7
|
+
*/
|
|
8
|
+
class LinearResampler {
|
|
9
|
+
/**
|
|
10
|
+
* Create a linear resampler.
|
|
11
|
+
*
|
|
12
|
+
* @param {number} inputSampleRate - Input sample rate in Hz.
|
|
13
|
+
* @param {number} outputSampleRate - Output sample rate in Hz.
|
|
14
|
+
*/
|
|
15
|
+
constructor(inputSampleRate, outputSampleRate) {
|
|
16
|
+
/** @type {LinearResamplerHandle} */
|
|
17
|
+
this.handle =
|
|
18
|
+
addon.createLinearResampler(inputSampleRate, outputSampleRate);
|
|
19
|
+
this.inputSampleRate = inputSampleRate;
|
|
20
|
+
this.outputSampleRate = outputSampleRate;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Resample a chunk of audio samples.
|
|
25
|
+
*
|
|
26
|
+
* Call this for each chunk of input audio. For the final chunk, call
|
|
27
|
+
* {@link flush} instead so that any internally buffered samples are
|
|
28
|
+
* emitted.
|
|
29
|
+
*
|
|
30
|
+
* @param {Float32Array} samples - Input audio samples.
|
|
31
|
+
* @returns {Float32Array} Resampled audio samples.
|
|
32
|
+
*/
|
|
33
|
+
resample(samples) {
|
|
34
|
+
return addon.resampleLinear(this.handle, samples, 0);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Resample the final chunk of audio and flush internal buffers.
|
|
39
|
+
*
|
|
40
|
+
* This is the same as {@link resample} but sets flush=1 so that any
|
|
41
|
+
* remaining samples buffered inside the resampler are emitted. Call
|
|
42
|
+
* this once after the last chunk of input audio.
|
|
43
|
+
*
|
|
44
|
+
* @param {Float32Array} samples - The final chunk of input audio samples.
|
|
45
|
+
* @returns {Float32Array} Resampled audio samples including buffered tail.
|
|
46
|
+
*/
|
|
47
|
+
flush(samples) {
|
|
48
|
+
return addon.resampleLinear(this.handle, samples, 1);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Reset the resampler to its initial state, discarding any internal
|
|
53
|
+
* buffered samples.
|
|
54
|
+
*/
|
|
55
|
+
reset() {
|
|
56
|
+
addon.linearResamplerReset(this.handle);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Get the input sample rate.
|
|
61
|
+
*
|
|
62
|
+
* @returns {number} Input sample rate in Hz.
|
|
63
|
+
*/
|
|
64
|
+
getInputSampleRate() {
|
|
65
|
+
return addon.linearResamplerGetInputSampleRate(this.handle);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Get the output sample rate.
|
|
70
|
+
*
|
|
71
|
+
* @returns {number} Output sample rate in Hz.
|
|
72
|
+
*/
|
|
73
|
+
getOutputSampleRate() {
|
|
74
|
+
return addon.linearResamplerGetOutputSampleRate(this.handle);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
module.exports = {
|
|
79
|
+
LinearResampler,
|
|
80
|
+
}
|
package/sherpa-onnx.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/** @typedef {import('./types').WaveObject} WaveObject */
|
|
2
|
+
/**
|
|
3
|
+
* @typedef {import('./types').OnlineRecognizerResult} OnlineRecognizerResult
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {import('./types').OfflineRecognizerResult} OfflineRecognizerResult
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const addon = require('./addon.js')
|
|
10
|
+
const streaming_asr = require('./streaming-asr.js');
|
|
11
|
+
const non_streaming_asr = require('./non-streaming-asr.js');
|
|
12
|
+
const non_streaming_tts = require('./non-streaming-tts.js');
|
|
13
|
+
const vad = require('./vad.js');
|
|
14
|
+
const slid = require('./spoken-language-identification.js');
|
|
15
|
+
const sid = require('./speaker-identification.js');
|
|
16
|
+
const at = require('./audio-tagg.js');
|
|
17
|
+
const punct = require('./punctuation.js');
|
|
18
|
+
const kws = require('./keyword-spotter.js');
|
|
19
|
+
const sd = require('./non-streaming-speaker-diarization.js');
|
|
20
|
+
const speech_denoiser = require('./non-streaming-speech-denoiser.js');
|
|
21
|
+
const online_speech_denoiser = require('./online-speech-denoiser.js');
|
|
22
|
+
const resampler = require('./resampler.js');
|
|
23
|
+
|
|
24
|
+
module.exports = {
|
|
25
|
+
OnlineRecognizer : streaming_asr.OnlineRecognizer,
|
|
26
|
+
OfflineRecognizer : non_streaming_asr.OfflineRecognizer,
|
|
27
|
+
OfflineTts : non_streaming_tts.OfflineTts,
|
|
28
|
+
GenerationConfig : non_streaming_tts.GenerationConfig,
|
|
29
|
+
readWave : addon.readWave,
|
|
30
|
+
writeWave : addon.writeWave,
|
|
31
|
+
Display : streaming_asr.Display,
|
|
32
|
+
Vad : vad.Vad,
|
|
33
|
+
CircularBuffer : vad.CircularBuffer,
|
|
34
|
+
SpokenLanguageIdentification : slid.SpokenLanguageIdentification,
|
|
35
|
+
SpeakerEmbeddingExtractor : sid.SpeakerEmbeddingExtractor,
|
|
36
|
+
SpeakerEmbeddingManager : sid.SpeakerEmbeddingManager,
|
|
37
|
+
AudioTagging : at.AudioTagging,
|
|
38
|
+
OfflinePunctuation : punct.OfflinePunctuation,
|
|
39
|
+
OnlinePunctuation : punct.OnlinePunctuation,
|
|
40
|
+
KeywordSpotter : kws.KeywordSpotter,
|
|
41
|
+
OfflineSpeakerDiarization : sd.OfflineSpeakerDiarization,
|
|
42
|
+
OfflineSpeechDenoiser : speech_denoiser.OfflineSpeechDenoiser,
|
|
43
|
+
OnlineSpeechDenoiser : online_speech_denoiser.OnlineSpeechDenoiser,
|
|
44
|
+
LinearResampler : resampler.LinearResampler,
|
|
45
|
+
version : addon.version,
|
|
46
|
+
gitSha1 : addon.gitSha1,
|
|
47
|
+
gitDate : addon.gitDate,
|
|
48
|
+
onnxruntimeVersion : addon.onnxruntimeVersion,
|
|
49
|
+
}
|
package/sherpa-onnx.node
ADDED
|
Binary file
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/** @typedef {import('./types').SpeakerEmbeddingEntry} SpeakerEmbeddingEntry */
|
|
2
|
+
/** @typedef {import('./types').SpeakerEmbeddingManagerSearchObj} SpeakerEmbeddingManagerSearchObj */
|
|
3
|
+
/** @typedef {import('./types').SpeakerEmbeddingManagerVerifyObj} SpeakerEmbeddingManagerVerifyObj */
|
|
4
|
+
/** @typedef {import('./types').SpeakerEmbeddingExtractorConfig} SpeakerEmbeddingExtractorConfig */
|
|
5
|
+
/** @typedef {import('./types').SpeakerEmbeddingExtractorHandle} SpeakerEmbeddingExtractorHandle */
|
|
6
|
+
/** @typedef {import('./types').SpeakerEmbeddingManagerHandle} SpeakerEmbeddingManagerHandle */
|
|
7
|
+
/** @typedef {import('./streaming-asr').OnlineStream} OnlineStream */
|
|
8
|
+
|
|
9
|
+
const addon = require('./addon.js');
|
|
10
|
+
const streaming_asr = require('./streaming-asr.js');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* SpeakerEmbeddingExtractor wraps native speaker embedding extractor.
|
|
14
|
+
*/
|
|
15
|
+
class SpeakerEmbeddingExtractor {
|
|
16
|
+
/**
|
|
17
|
+
* @param {SpeakerEmbeddingExtractorConfig} config
|
|
18
|
+
*/
|
|
19
|
+
constructor(config) {
|
|
20
|
+
this.handle = addon.createSpeakerEmbeddingExtractor(config);
|
|
21
|
+
this.config = config;
|
|
22
|
+
this.dim = addon.speakerEmbeddingExtractorDim(this.handle);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @returns {OnlineStream}
|
|
27
|
+
*/
|
|
28
|
+
createStream() {
|
|
29
|
+
return new streaming_asr.OnlineStream(
|
|
30
|
+
addon.speakerEmbeddingExtractorCreateStream(this.handle));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @param {OnlineStream} stream
|
|
35
|
+
* @returns {boolean}
|
|
36
|
+
*/
|
|
37
|
+
isReady(stream) {
|
|
38
|
+
return addon.speakerEmbeddingExtractorIsReady(this.handle, stream.handle);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Compute embedding and return a Float32Array
|
|
43
|
+
* @param {OnlineStream} stream
|
|
44
|
+
* @param {boolean} [enableExternalBuffer=true]
|
|
45
|
+
* @returns {Float32Array}
|
|
46
|
+
*/
|
|
47
|
+
compute(stream, enableExternalBuffer = true) {
|
|
48
|
+
return addon.speakerEmbeddingExtractorComputeEmbedding(
|
|
49
|
+
this.handle, stream.handle, enableExternalBuffer);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Flattens an array of Float32Arrays into a single Float32Array.
|
|
55
|
+
* @param {Float32Array[]} arrayList
|
|
56
|
+
* @returns {Float32Array}
|
|
57
|
+
*/
|
|
58
|
+
function flatten(arrayList) {
|
|
59
|
+
let n = 0;
|
|
60
|
+
for (let i = 0; i < arrayList.length; ++i) {
|
|
61
|
+
n += arrayList[i].length;
|
|
62
|
+
}
|
|
63
|
+
let ans = new Float32Array(n);
|
|
64
|
+
|
|
65
|
+
let offset = 0;
|
|
66
|
+
for (let i = 0; i < arrayList.length; ++i) {
|
|
67
|
+
ans.set(arrayList[i], offset);
|
|
68
|
+
offset += arrayList[i].length;
|
|
69
|
+
}
|
|
70
|
+
return ans;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Manager for speaker embeddings.
|
|
75
|
+
*/
|
|
76
|
+
class SpeakerEmbeddingManager {
|
|
77
|
+
/**
|
|
78
|
+
* @param {number} dim - The embedding dimension
|
|
79
|
+
*/
|
|
80
|
+
constructor(dim) {
|
|
81
|
+
this.handle = addon.createSpeakerEmbeddingManager(dim);
|
|
82
|
+
this.dim = dim;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* @param {SpeakerEmbeddingEntry} obj
|
|
87
|
+
* @returns {boolean}
|
|
88
|
+
*/
|
|
89
|
+
add(obj) {
|
|
90
|
+
return addon.speakerEmbeddingManagerAdd(this.handle, obj);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* @param {{name:string, v: Float32Array[]}} obj
|
|
95
|
+
* @returns {boolean}
|
|
96
|
+
*/
|
|
97
|
+
addMulti(obj) {
|
|
98
|
+
const c = {
|
|
99
|
+
name: obj.name,
|
|
100
|
+
vv: flatten(obj.v),
|
|
101
|
+
n: obj.v.length,
|
|
102
|
+
};
|
|
103
|
+
return addon.speakerEmbeddingManagerAddListFlattened(this.handle, c);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* @param {string} name
|
|
108
|
+
* @returns {boolean}
|
|
109
|
+
*/
|
|
110
|
+
remove(name) {
|
|
111
|
+
return addon.speakerEmbeddingManagerRemove(this.handle, name);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* @param {SpeakerEmbeddingManagerSearchObj} obj
|
|
116
|
+
* @returns {string}
|
|
117
|
+
*/
|
|
118
|
+
search(obj) {
|
|
119
|
+
return addon.speakerEmbeddingManagerSearch(this.handle, obj);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* @param {SpeakerEmbeddingManagerVerifyObj} obj
|
|
124
|
+
* @returns {boolean}
|
|
125
|
+
*/
|
|
126
|
+
verify(obj) {
|
|
127
|
+
return addon.speakerEmbeddingManagerVerify(this.handle, obj);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* @param {string} name
|
|
132
|
+
* @returns {boolean}
|
|
133
|
+
*/
|
|
134
|
+
contains(name) {
|
|
135
|
+
return addon.speakerEmbeddingManagerContains(this.handle, name);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** @returns {number} */
|
|
139
|
+
getNumSpeakers() {
|
|
140
|
+
return addon.speakerEmbeddingManagerNumSpeakers(this.handle);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/** @returns {string[]} */
|
|
144
|
+
getAllSpeakerNames() {
|
|
145
|
+
return addon.speakerEmbeddingManagerGetAllSpeakers(this.handle);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
module.exports = {
|
|
150
|
+
SpeakerEmbeddingExtractor,
|
|
151
|
+
SpeakerEmbeddingManager,
|
|
152
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** @typedef {import('./types').SpokenLanguageIdentificationConfig} SpokenLanguageIdentificationConfig */
|
|
2
|
+
/** @typedef {import('./types').SpokenLanguageIdentificationHandle} SpokenLanguageIdentificationHandle */
|
|
3
|
+
/** @typedef {import('./non-streaming-asr').OfflineStream} OfflineStream */
|
|
4
|
+
|
|
5
|
+
const addon = require('./addon.js');
|
|
6
|
+
const non_streaming_asr = require('./non-streaming-asr.js');
|
|
7
|
+
|
|
8
|
+
class SpokenLanguageIdentification {
|
|
9
|
+
/**
|
|
10
|
+
* @param {SpokenLanguageIdentificationConfig} config
|
|
11
|
+
*/
|
|
12
|
+
constructor(config) {
|
|
13
|
+
this.handle = addon.createSpokenLanguageIdentification(config);
|
|
14
|
+
this.config = config;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @returns {OfflineStream}
|
|
19
|
+
*/
|
|
20
|
+
createStream() {
|
|
21
|
+
return new non_streaming_asr.OfflineStream(
|
|
22
|
+
addon.createSpokenLanguageIdentificationOfflineStream(this.handle));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Return a 2-letter language code, e.g. 'en', 'de', 'fr', 'es', 'zh'
|
|
27
|
+
* @param {OfflineStream} stream
|
|
28
|
+
* @returns {string}
|
|
29
|
+
*/
|
|
30
|
+
compute(stream) {
|
|
31
|
+
return addon.spokenLanguageIdentificationCompute(
|
|
32
|
+
this.handle, stream.handle);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
module.exports = {
|
|
37
|
+
SpokenLanguageIdentification,
|
|
38
|
+
}
|
package/streaming-asr.js
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/** @typedef {import('./types').OnlineStreamObject} OnlineStreamObject */
|
|
2
|
+
/** @typedef {import('./types').OnlineRecognizerHandle} OnlineRecognizerHandle */
|
|
3
|
+
/** @typedef {import('./types').OnlineStreamHandle} OnlineStreamHandle */
|
|
4
|
+
/** @typedef {import('./types').DisplayHandle} DisplayHandle */
|
|
5
|
+
/** @typedef {import('./types').DisplayObject} DisplayObject */
|
|
6
|
+
/** @typedef {import('./types').OnlineRecognizerConfig} OnlineRecognizerConfig */
|
|
7
|
+
/** @typedef {import('./types').Waveform} Waveform */
|
|
8
|
+
/** @typedef {import('./types').OnlineRecognizerResult} OnlineRecognizerResult */
|
|
9
|
+
|
|
10
|
+
const addon = require('./addon.js');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Display helper for printing recognized words.
|
|
14
|
+
*/
|
|
15
|
+
class Display {
|
|
16
|
+
/**
|
|
17
|
+
* @param {number} maxWordPerline
|
|
18
|
+
*/
|
|
19
|
+
constructor(maxWordPerline) {
|
|
20
|
+
this.handle = addon.createDisplay(maxWordPerline);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Print text to display.
|
|
25
|
+
* @param {number} idx
|
|
26
|
+
* @param {string} text
|
|
27
|
+
*/
|
|
28
|
+
print(idx, text) {
|
|
29
|
+
addon.print(this.handle, idx, text)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* OnlineStream holds an active online stream handle.
|
|
35
|
+
*/
|
|
36
|
+
class OnlineStream {
|
|
37
|
+
/**
|
|
38
|
+
* @param {OnlineStreamObject|Object} handle - object with `handle` property
|
|
39
|
+
*/
|
|
40
|
+
constructor(handle) {
|
|
41
|
+
this.handle = handle;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Accept waveform data
|
|
46
|
+
* @param {Waveform} obj - { samples: Float32Array, sampleRate: number }
|
|
47
|
+
*/
|
|
48
|
+
acceptWaveform(obj) {
|
|
49
|
+
addon.acceptWaveformOnline(this.handle, obj)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Notify the stream input has finished. */
|
|
53
|
+
inputFinished() {
|
|
54
|
+
addon.inputFinished(this.handle)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* OnlineRecognizer wraps native online recognizer.
|
|
60
|
+
*/
|
|
61
|
+
class OnlineRecognizer {
|
|
62
|
+
/**
|
|
63
|
+
* @param {OnlineRecognizerConfig} config - online recognizer config (see C++ for fields)
|
|
64
|
+
*/
|
|
65
|
+
constructor(config) {
|
|
66
|
+
this.handle = addon.createOnlineRecognizer(config);
|
|
67
|
+
this.config = config
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Create a new OnlineStream.
|
|
72
|
+
* @returns {OnlineStream}
|
|
73
|
+
*/
|
|
74
|
+
createStream() {
|
|
75
|
+
const handle = addon.createOnlineStream(this.handle);
|
|
76
|
+
return new OnlineStream(handle);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Check whether a stream is ready.
|
|
81
|
+
* @param {OnlineStream} stream
|
|
82
|
+
* @returns {boolean}
|
|
83
|
+
*/
|
|
84
|
+
isReady(stream) {
|
|
85
|
+
return addon.isOnlineStreamReady(this.handle, stream.handle);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Trigger decoding on a stream.
|
|
90
|
+
* @param {OnlineStream} stream
|
|
91
|
+
*/
|
|
92
|
+
decode(stream) {
|
|
93
|
+
addon.decodeOnlineStream(this.handle, stream.handle);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Check endpoint condition for a stream.
|
|
98
|
+
* @param {OnlineStream} stream
|
|
99
|
+
* @returns {boolean}
|
|
100
|
+
*/
|
|
101
|
+
isEndpoint(stream) {
|
|
102
|
+
return addon.isEndpoint(this.handle, stream.handle);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Reset a stream.
|
|
107
|
+
* @param {OnlineStream} stream
|
|
108
|
+
*/
|
|
109
|
+
reset(stream) {
|
|
110
|
+
addon.reset(this.handle, stream.handle);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Get recognition result for a stream.
|
|
115
|
+
* @param {OnlineStream} stream
|
|
116
|
+
* @returns {OnlineRecognizerResult}
|
|
117
|
+
*/
|
|
118
|
+
getResult(stream) {
|
|
119
|
+
const jsonStr =
|
|
120
|
+
addon.getOnlineStreamResultAsJson(this.handle, stream.handle);
|
|
121
|
+
|
|
122
|
+
return JSON.parse(jsonStr);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
module.exports = {
|
|
127
|
+
OnlineRecognizer,
|
|
128
|
+
OnlineStream,
|
|
129
|
+
Display
|
|
130
|
+
}
|