whisper.rn 0.3.5 → 0.3.7
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/android/src/main/java/com/rnwhisper/RNWhisper.java +68 -8
- package/android/src/main/java/com/rnwhisper/WhisperContext.java +127 -2
- package/android/src/main/jni.cpp +22 -0
- package/cpp/rn-whisper.cpp +51 -0
- package/cpp/rn-whisper.h +2 -1
- package/ios/RNWhisper.mm +36 -30
- package/ios/RNWhisper.xcodeproj/project.pbxproj +21 -3
- package/ios/RNWhisper.xcodeproj/project.xcworkspace/xcuserdata/jhen.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/ios/RNWhisper.xcodeproj/xcuserdata/jhen.xcuserdatad/xcschemes/xcschememanagement.plist +5 -0
- package/ios/RNWhisperAudioUtils.h +8 -0
- package/ios/RNWhisperAudioUtils.m +62 -0
- package/ios/RNWhisperContext.h +8 -3
- package/ios/RNWhisperContext.mm +69 -11
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/index.d.ts +25 -2
- package/lib/typescript/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +25 -2
|
@@ -21,6 +21,8 @@ import java.io.FileInputStream;
|
|
|
21
21
|
import java.io.PushbackInputStream;
|
|
22
22
|
|
|
23
23
|
public class RNWhisper implements LifecycleEventListener {
|
|
24
|
+
public static final String NAME = "RNWhisper";
|
|
25
|
+
|
|
24
26
|
private ReactApplicationContext reactContext;
|
|
25
27
|
private Downloader downloader;
|
|
26
28
|
|
|
@@ -40,6 +42,8 @@ public class RNWhisper implements LifecycleEventListener {
|
|
|
40
42
|
return constants;
|
|
41
43
|
}
|
|
42
44
|
|
|
45
|
+
private HashMap<AsyncTask, String> tasks = new HashMap<>();
|
|
46
|
+
|
|
43
47
|
private HashMap<Integer, WhisperContext> contexts = new HashMap<>();
|
|
44
48
|
|
|
45
49
|
private int getResourceIdentifier(String filePath) {
|
|
@@ -59,7 +63,7 @@ public class RNWhisper implements LifecycleEventListener {
|
|
|
59
63
|
}
|
|
60
64
|
|
|
61
65
|
public void initContext(final ReadableMap options, final Promise promise) {
|
|
62
|
-
new AsyncTask<Void, Void, Integer>() {
|
|
66
|
+
AsyncTask task = new AsyncTask<Void, Void, Integer>() {
|
|
63
67
|
private Exception exception;
|
|
64
68
|
|
|
65
69
|
@Override
|
|
@@ -104,8 +108,10 @@ public class RNWhisper implements LifecycleEventListener {
|
|
|
104
108
|
return;
|
|
105
109
|
}
|
|
106
110
|
promise.resolve(id);
|
|
111
|
+
tasks.remove(this);
|
|
107
112
|
}
|
|
108
113
|
}.execute();
|
|
114
|
+
tasks.put(task, "initContext");
|
|
109
115
|
}
|
|
110
116
|
|
|
111
117
|
public void transcribeFile(double id, double jobId, String filePath, ReadableMap options, Promise promise) {
|
|
@@ -122,7 +128,7 @@ public class RNWhisper implements LifecycleEventListener {
|
|
|
122
128
|
promise.reject("Context is already transcribing");
|
|
123
129
|
return;
|
|
124
130
|
}
|
|
125
|
-
new AsyncTask<Void, Void, WritableMap>() {
|
|
131
|
+
AsyncTask task = new AsyncTask<Void, Void, WritableMap>() {
|
|
126
132
|
private Exception exception;
|
|
127
133
|
|
|
128
134
|
@Override
|
|
@@ -161,8 +167,10 @@ public class RNWhisper implements LifecycleEventListener {
|
|
|
161
167
|
return;
|
|
162
168
|
}
|
|
163
169
|
promise.resolve(data);
|
|
170
|
+
tasks.remove(this);
|
|
164
171
|
}
|
|
165
172
|
}.execute();
|
|
173
|
+
tasks.put(task, "transcribeFile-" + id);
|
|
166
174
|
}
|
|
167
175
|
|
|
168
176
|
public void startRealtimeTranscribe(double id, double jobId, ReadableMap options, Promise promise) {
|
|
@@ -183,18 +191,48 @@ public class RNWhisper implements LifecycleEventListener {
|
|
|
183
191
|
promise.reject("Failed to start realtime transcribe. State: " + state);
|
|
184
192
|
}
|
|
185
193
|
|
|
186
|
-
public void abortTranscribe(double
|
|
187
|
-
WhisperContext context = contexts.get((int)
|
|
194
|
+
public void abortTranscribe(double id, double jobId, Promise promise) {
|
|
195
|
+
WhisperContext context = contexts.get((int) id);
|
|
188
196
|
if (context == null) {
|
|
189
197
|
promise.reject("Context not found");
|
|
190
198
|
return;
|
|
191
199
|
}
|
|
192
|
-
|
|
200
|
+
AsyncTask task = new AsyncTask<Void, Void, Void>() {
|
|
201
|
+
private Exception exception;
|
|
202
|
+
|
|
203
|
+
@Override
|
|
204
|
+
protected Void doInBackground(Void... voids) {
|
|
205
|
+
try {
|
|
206
|
+
context.stopTranscribe((int) jobId);
|
|
207
|
+
AsyncTask completionTask = null;
|
|
208
|
+
for (AsyncTask task : tasks.keySet()) {
|
|
209
|
+
if (tasks.get(task).equals("transcribeFile-" + id)) {
|
|
210
|
+
task.get();
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
} catch (Exception e) {
|
|
215
|
+
exception = e;
|
|
216
|
+
}
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
@Override
|
|
221
|
+
protected void onPostExecute(Void result) {
|
|
222
|
+
if (exception != null) {
|
|
223
|
+
promise.reject(exception);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
promise.resolve(null);
|
|
227
|
+
tasks.remove(this);
|
|
228
|
+
}
|
|
229
|
+
}.execute();
|
|
230
|
+
tasks.put(task, "abortTranscribe-" + id);
|
|
193
231
|
}
|
|
194
232
|
|
|
195
233
|
public void releaseContext(double id, Promise promise) {
|
|
196
234
|
final int contextId = (int) id;
|
|
197
|
-
new AsyncTask<Void, Void, Void>() {
|
|
235
|
+
AsyncTask task = new AsyncTask<Void, Void, Void>() {
|
|
198
236
|
private Exception exception;
|
|
199
237
|
|
|
200
238
|
@Override
|
|
@@ -204,6 +242,14 @@ public class RNWhisper implements LifecycleEventListener {
|
|
|
204
242
|
if (context == null) {
|
|
205
243
|
throw new Exception("Context " + id + " not found");
|
|
206
244
|
}
|
|
245
|
+
context.stopCurrentTranscribe();
|
|
246
|
+
AsyncTask completionTask = null;
|
|
247
|
+
for (AsyncTask task : tasks.keySet()) {
|
|
248
|
+
if (tasks.get(task).equals("transcribeFile-" + contextId)) {
|
|
249
|
+
task.get();
|
|
250
|
+
break;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
207
253
|
context.release();
|
|
208
254
|
contexts.remove(contextId);
|
|
209
255
|
} catch (Exception e) {
|
|
@@ -219,12 +265,14 @@ public class RNWhisper implements LifecycleEventListener {
|
|
|
219
265
|
return;
|
|
220
266
|
}
|
|
221
267
|
promise.resolve(null);
|
|
268
|
+
tasks.remove(this);
|
|
222
269
|
}
|
|
223
270
|
}.execute();
|
|
271
|
+
tasks.put(task, "releaseContext-" + id);
|
|
224
272
|
}
|
|
225
273
|
|
|
226
274
|
public void releaseAllContexts(Promise promise) {
|
|
227
|
-
new AsyncTask<Void, Void, Void>() {
|
|
275
|
+
AsyncTask task = new AsyncTask<Void, Void, Void>() {
|
|
228
276
|
private Exception exception;
|
|
229
277
|
|
|
230
278
|
@Override
|
|
@@ -244,8 +292,10 @@ public class RNWhisper implements LifecycleEventListener {
|
|
|
244
292
|
return;
|
|
245
293
|
}
|
|
246
294
|
promise.resolve(null);
|
|
295
|
+
tasks.remove(this);
|
|
247
296
|
}
|
|
248
297
|
}.execute();
|
|
298
|
+
tasks.put(task, "releaseAllContexts");
|
|
249
299
|
}
|
|
250
300
|
|
|
251
301
|
@Override
|
|
@@ -258,10 +308,20 @@ public class RNWhisper implements LifecycleEventListener {
|
|
|
258
308
|
|
|
259
309
|
@Override
|
|
260
310
|
public void onHostDestroy() {
|
|
261
|
-
WhisperContext.
|
|
311
|
+
for (WhisperContext context : contexts.values()) {
|
|
312
|
+
context.stopCurrentTranscribe();
|
|
313
|
+
}
|
|
314
|
+
for (AsyncTask task : tasks.keySet()) {
|
|
315
|
+
try {
|
|
316
|
+
task.get();
|
|
317
|
+
} catch (Exception e) {
|
|
318
|
+
Log.e(NAME, "Failed to wait for task", e);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
262
321
|
for (WhisperContext context : contexts.values()) {
|
|
263
322
|
context.release();
|
|
264
323
|
}
|
|
324
|
+
WhisperContext.abortAllTranscribe(); // graceful abort
|
|
265
325
|
contexts.clear();
|
|
266
326
|
downloader.clearCache();
|
|
267
327
|
}
|
|
@@ -24,6 +24,8 @@ import java.io.FileReader;
|
|
|
24
24
|
import java.io.ByteArrayOutputStream;
|
|
25
25
|
import java.io.File;
|
|
26
26
|
import java.io.FileInputStream;
|
|
27
|
+
import java.io.FileOutputStream;
|
|
28
|
+
import java.io.DataOutputStream;
|
|
27
29
|
import java.io.IOException;
|
|
28
30
|
import java.io.InputStream;
|
|
29
31
|
import java.io.PushbackInputStream;
|
|
@@ -61,6 +63,7 @@ public class WhisperContext {
|
|
|
61
63
|
private boolean isCapturing = false;
|
|
62
64
|
private boolean isStoppedByAction = false;
|
|
63
65
|
private boolean isTranscribing = false;
|
|
66
|
+
private Thread rootFullHandler = null;
|
|
64
67
|
private Thread fullHandler = null;
|
|
65
68
|
|
|
66
69
|
public WhisperContext(int id, ReactApplicationContext reactContext, long context) {
|
|
@@ -81,9 +84,105 @@ public class WhisperContext {
|
|
|
81
84
|
isCapturing = false;
|
|
82
85
|
isStoppedByAction = false;
|
|
83
86
|
isTranscribing = false;
|
|
87
|
+
rootFullHandler = null;
|
|
84
88
|
fullHandler = null;
|
|
85
89
|
}
|
|
86
90
|
|
|
91
|
+
public byte[] shortToByte(short[] shortInts) {
|
|
92
|
+
int j = 0;
|
|
93
|
+
int length = shortInts.length;
|
|
94
|
+
byte[] byteData = new byte[length * 2];
|
|
95
|
+
for (int i = 0; i < length; i++) {
|
|
96
|
+
byteData[j++] = (byte) (shortInts[i] >>> 8);
|
|
97
|
+
byteData[j++] = (byte) (shortInts[i] >>> 0);
|
|
98
|
+
}
|
|
99
|
+
return byteData;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
public byte[] concatShortBuffers(ArrayList<short[]> buffers) {
|
|
103
|
+
int totalLength = 0;
|
|
104
|
+
for (int i = 0; i < buffers.size(); i++) {
|
|
105
|
+
totalLength += buffers.get(i).length;
|
|
106
|
+
}
|
|
107
|
+
byte[] result = new byte[totalLength * 2];
|
|
108
|
+
int offset = 0;
|
|
109
|
+
for (int i = 0; i < buffers.size(); i++) {
|
|
110
|
+
byte[] bytes = shortToByte(buffers.get(i));
|
|
111
|
+
System.arraycopy(bytes, 0, result, offset, bytes.length);
|
|
112
|
+
offset += bytes.length;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return result;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
public byte[] removeTrailingZeros(byte[] audioData) {
|
|
119
|
+
int i = audioData.length - 1;
|
|
120
|
+
while (i >= 0 && audioData[i] == 0) {
|
|
121
|
+
--i;
|
|
122
|
+
}
|
|
123
|
+
byte[] newData = new byte[i + 1];
|
|
124
|
+
System.arraycopy(audioData, 0, newData, 0, i + 1);
|
|
125
|
+
return newData;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
private void saveWavFile(byte[] rawData, String audioOutputFile) throws IOException {
|
|
129
|
+
Log.d(NAME, "call saveWavFile");
|
|
130
|
+
rawData = removeTrailingZeros(rawData);
|
|
131
|
+
DataOutputStream output = null;
|
|
132
|
+
try {
|
|
133
|
+
output = new DataOutputStream(new FileOutputStream(audioOutputFile));
|
|
134
|
+
// WAVE header
|
|
135
|
+
// see http://ccrma.stanford.edu/courses/422/projects/WaveFormat/
|
|
136
|
+
output.writeBytes("RIFF"); // chunk id
|
|
137
|
+
output.writeInt(Integer.reverseBytes(36 + rawData.length)); // chunk size
|
|
138
|
+
output.writeBytes("WAVE"); // format
|
|
139
|
+
output.writeBytes("fmt "); // subchunk 1 id
|
|
140
|
+
output.writeInt(Integer.reverseBytes(16)); // subchunk 1 size
|
|
141
|
+
output.writeShort(Short.reverseBytes((short) 1)); // audio format (1 = PCM)
|
|
142
|
+
output.writeShort(Short.reverseBytes((short) 1)); // number of channels
|
|
143
|
+
output.writeInt(Integer.reverseBytes(SAMPLE_RATE)); // sample rate
|
|
144
|
+
output.writeInt(Integer.reverseBytes(SAMPLE_RATE * 2)); // byte rate
|
|
145
|
+
output.writeShort(Short.reverseBytes((short) 2)); // block align
|
|
146
|
+
output.writeShort(Short.reverseBytes((short) 16)); // bits per sample
|
|
147
|
+
output.writeBytes("data"); // subchunk 2 id
|
|
148
|
+
output.writeInt(Integer.reverseBytes(rawData.length)); // subchunk 2 size
|
|
149
|
+
// Audio data (conversion big endian -> little endian)
|
|
150
|
+
short[] shorts = new short[rawData.length / 2];
|
|
151
|
+
ByteBuffer.wrap(rawData).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shorts);
|
|
152
|
+
ByteBuffer bytes = ByteBuffer.allocate(shorts.length * 2);
|
|
153
|
+
for (short s : shorts) {
|
|
154
|
+
bytes.putShort(s);
|
|
155
|
+
}
|
|
156
|
+
Log.d(NAME, "writing audio file: " + audioOutputFile);
|
|
157
|
+
output.write(bytes.array());
|
|
158
|
+
} finally {
|
|
159
|
+
if (output != null) {
|
|
160
|
+
output.close();
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
private boolean vad(ReadableMap options, short[] shortBuffer, int nSamples, int n) {
|
|
166
|
+
boolean isSpeech = true;
|
|
167
|
+
if (!isTranscribing && options.hasKey("useVad") && options.getBoolean("useVad")) {
|
|
168
|
+
int vadSec = options.hasKey("vadMs") ? options.getInt("vadMs") / 1000 : 2;
|
|
169
|
+
int sampleSize = vadSec * SAMPLE_RATE;
|
|
170
|
+
if (nSamples + n > sampleSize) {
|
|
171
|
+
int start = nSamples + n - sampleSize;
|
|
172
|
+
float[] audioData = new float[sampleSize];
|
|
173
|
+
for (int i = 0; i < sampleSize; i++) {
|
|
174
|
+
audioData[i] = shortBuffer[i + start] / 32768.0f;
|
|
175
|
+
}
|
|
176
|
+
float vadThold = options.hasKey("vadThold") ? (float) options.getDouble("vadThold") : 0.6f;
|
|
177
|
+
float vadFreqThold = options.hasKey("vadFreqThold") ? (float) options.getDouble("vadFreqThold") : 0.6f;
|
|
178
|
+
isSpeech = vadSimple(audioData, sampleSize, vadThold, vadFreqThold);
|
|
179
|
+
} else {
|
|
180
|
+
isSpeech = false;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return isSpeech;
|
|
184
|
+
}
|
|
185
|
+
|
|
87
186
|
public int startRealtimeTranscribe(int jobId, ReadableMap options) {
|
|
88
187
|
if (isCapturing || isTranscribing) {
|
|
89
188
|
return -100;
|
|
@@ -109,6 +208,8 @@ public class WhisperContext {
|
|
|
109
208
|
|
|
110
209
|
isUseSlices = audioSliceSec < audioSec;
|
|
111
210
|
|
|
211
|
+
String audioOutputPath = options.hasKey("audioOutputPath") ? options.getString("audioOutputPath") : null;
|
|
212
|
+
|
|
112
213
|
shortBufferSlices = new ArrayList<short[]>();
|
|
113
214
|
shortBufferSlices.add(new short[audioSliceSec * SAMPLE_RATE]);
|
|
114
215
|
sliceNSamples = new ArrayList<Integer>();
|
|
@@ -117,7 +218,7 @@ public class WhisperContext {
|
|
|
117
218
|
isCapturing = true;
|
|
118
219
|
recorder.startRecording();
|
|
119
220
|
|
|
120
|
-
new Thread(new Runnable() {
|
|
221
|
+
rootFullHandler = new Thread(new Runnable() {
|
|
121
222
|
@Override
|
|
122
223
|
public void run() {
|
|
123
224
|
try {
|
|
@@ -143,6 +244,12 @@ public class WhisperContext {
|
|
|
143
244
|
) {
|
|
144
245
|
emitTranscribeEvent("@RNWhisper_onRealtimeTranscribeEnd", Arguments.createMap());
|
|
145
246
|
} else if (!isTranscribing) {
|
|
247
|
+
short[] shortBuffer = shortBufferSlices.get(sliceIndex);
|
|
248
|
+
boolean isSpeech = vad(options, shortBuffer, nSamples, 0);
|
|
249
|
+
if (!isSpeech) {
|
|
250
|
+
emitTranscribeEvent("@RNWhisper_onRealtimeTranscribeEnd", Arguments.createMap());
|
|
251
|
+
break;
|
|
252
|
+
}
|
|
146
253
|
isTranscribing = true;
|
|
147
254
|
fullTranscribeSamples(options, true);
|
|
148
255
|
}
|
|
@@ -164,9 +271,14 @@ public class WhisperContext {
|
|
|
164
271
|
for (int i = 0; i < n; i++) {
|
|
165
272
|
shortBuffer[nSamples + i] = buffer[i];
|
|
166
273
|
}
|
|
274
|
+
|
|
275
|
+
boolean isSpeech = vad(options, shortBuffer, nSamples, n);
|
|
276
|
+
|
|
167
277
|
nSamples += n;
|
|
168
278
|
sliceNSamples.set(sliceIndex, nSamples);
|
|
169
279
|
|
|
280
|
+
if (!isSpeech) continue;
|
|
281
|
+
|
|
170
282
|
if (!isTranscribing && nSamples > SAMPLE_RATE / 2) {
|
|
171
283
|
isTranscribing = true;
|
|
172
284
|
fullHandler = new Thread(new Runnable() {
|
|
@@ -181,6 +293,9 @@ public class WhisperContext {
|
|
|
181
293
|
Log.e(NAME, "Error transcribing realtime: " + e.getMessage());
|
|
182
294
|
}
|
|
183
295
|
}
|
|
296
|
+
// TODO: Append in real time so we don't need to keep all slices & also reduce memory usage
|
|
297
|
+
Log.d(NAME, "Begin saving wav file to " + audioOutputPath);
|
|
298
|
+
saveWavFile(concatShortBuffers(shortBufferSlices), audioOutputPath);
|
|
184
299
|
if (!isTranscribing) {
|
|
185
300
|
emitTranscribeEvent("@RNWhisper_onRealtimeTranscribeEnd", Arguments.createMap());
|
|
186
301
|
}
|
|
@@ -195,7 +310,8 @@ public class WhisperContext {
|
|
|
195
310
|
recorder = null;
|
|
196
311
|
}
|
|
197
312
|
}
|
|
198
|
-
})
|
|
313
|
+
});
|
|
314
|
+
rootFullHandler.start();
|
|
199
315
|
return state;
|
|
200
316
|
}
|
|
201
317
|
|
|
@@ -402,6 +518,14 @@ public class WhisperContext {
|
|
|
402
518
|
abortTranscribe(jobId);
|
|
403
519
|
isCapturing = false;
|
|
404
520
|
isStoppedByAction = true;
|
|
521
|
+
if (rootFullHandler != null) {
|
|
522
|
+
try {
|
|
523
|
+
rootFullHandler.join();
|
|
524
|
+
} catch (Exception e) {
|
|
525
|
+
Log.e(NAME, "Error joining rootFullHandler: " + e.getMessage());
|
|
526
|
+
}
|
|
527
|
+
rootFullHandler = null;
|
|
528
|
+
}
|
|
405
529
|
}
|
|
406
530
|
|
|
407
531
|
public void stopCurrentTranscribe() {
|
|
@@ -502,6 +626,7 @@ public class WhisperContext {
|
|
|
502
626
|
protected static native long initContext(String modelPath);
|
|
503
627
|
protected static native long initContextWithAsset(AssetManager assetManager, String modelPath);
|
|
504
628
|
protected static native long initContextWithInputStream(PushbackInputStream inputStream);
|
|
629
|
+
protected static native boolean vadSimple(float[] audio_data, int audio_data_len, float vad_thold, float vad_freq_thold);
|
|
505
630
|
protected static native int fullTranscribe(
|
|
506
631
|
int job_id,
|
|
507
632
|
long context,
|
package/android/src/main/jni.cpp
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
#include <sys/sysinfo.h>
|
|
7
7
|
#include <string>
|
|
8
8
|
#include <thread>
|
|
9
|
+
#include <vector>
|
|
9
10
|
#include "whisper.h"
|
|
10
11
|
#include "rn-whisper.h"
|
|
11
12
|
#include "ggml.h"
|
|
@@ -184,6 +185,27 @@ Java_com_rnwhisper_WhisperContext_initContextWithInputStream(
|
|
|
184
185
|
return reinterpret_cast<jlong>(context);
|
|
185
186
|
}
|
|
186
187
|
|
|
188
|
+
JNIEXPORT jboolean JNICALL
|
|
189
|
+
Java_com_rnwhisper_WhisperContext_vadSimple(
|
|
190
|
+
JNIEnv *env,
|
|
191
|
+
jobject thiz,
|
|
192
|
+
jfloatArray audio_data,
|
|
193
|
+
jint audio_data_len,
|
|
194
|
+
jfloat vad_thold,
|
|
195
|
+
jfloat vad_freq_thold
|
|
196
|
+
) {
|
|
197
|
+
UNUSED(thiz);
|
|
198
|
+
|
|
199
|
+
std::vector<float> samples(audio_data_len);
|
|
200
|
+
jfloat *audio_data_arr = env->GetFloatArrayElements(audio_data, nullptr);
|
|
201
|
+
for (int i = 0; i < audio_data_len; i++) {
|
|
202
|
+
samples[i] = audio_data_arr[i];
|
|
203
|
+
}
|
|
204
|
+
bool is_speech = rn_whisper_vad_simple(samples, WHISPER_SAMPLE_RATE, 1000, vad_thold, vad_freq_thold, false);
|
|
205
|
+
env->ReleaseFloatArrayElements(audio_data, audio_data_arr, JNI_ABORT);
|
|
206
|
+
return is_speech;
|
|
207
|
+
}
|
|
208
|
+
|
|
187
209
|
struct progress_callback_context {
|
|
188
210
|
JNIEnv *env;
|
|
189
211
|
jobject progress_callback_instance;
|
package/cpp/rn-whisper.cpp
CHANGED
|
@@ -38,4 +38,55 @@ void rn_whisper_abort_all_transcribe() {
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
void high_pass_filter(std::vector<float> & data, float cutoff, float sample_rate) {
|
|
42
|
+
const float rc = 1.0f / (2.0f * M_PI * cutoff);
|
|
43
|
+
const float dt = 1.0f / sample_rate;
|
|
44
|
+
const float alpha = dt / (rc + dt);
|
|
45
|
+
|
|
46
|
+
float y = data[0];
|
|
47
|
+
|
|
48
|
+
for (size_t i = 1; i < data.size(); i++) {
|
|
49
|
+
y = alpha * (y + data[i] - data[i - 1]);
|
|
50
|
+
data[i] = y;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
bool rn_whisper_vad_simple(std::vector<float> & pcmf32, int sample_rate, int last_ms, float vad_thold, float freq_thold, bool verbose) {
|
|
55
|
+
const int n_samples = pcmf32.size();
|
|
56
|
+
const int n_samples_last = (sample_rate * last_ms) / 1000;
|
|
57
|
+
|
|
58
|
+
if (n_samples_last >= n_samples) {
|
|
59
|
+
// not enough samples - assume no speech
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (freq_thold > 0.0f) {
|
|
64
|
+
high_pass_filter(pcmf32, freq_thold, sample_rate);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
float energy_all = 0.0f;
|
|
68
|
+
float energy_last = 0.0f;
|
|
69
|
+
|
|
70
|
+
for (int i = 0; i < n_samples; i++) {
|
|
71
|
+
energy_all += fabsf(pcmf32[i]);
|
|
72
|
+
|
|
73
|
+
if (i >= n_samples - n_samples_last) {
|
|
74
|
+
energy_last += fabsf(pcmf32[i]);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
energy_all /= n_samples;
|
|
79
|
+
energy_last /= n_samples_last;
|
|
80
|
+
|
|
81
|
+
if (verbose) {
|
|
82
|
+
fprintf(stderr, "%s: energy_all: %f, energy_last: %f, vad_thold: %f, freq_thold: %f\n", __func__, energy_all, energy_last, vad_thold, freq_thold);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (energy_last > vad_thold*energy_all) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
|
|
41
92
|
}
|
package/cpp/rn-whisper.h
CHANGED
|
@@ -10,7 +10,8 @@ void rn_whisper_remove_abort_map(int job_id);
|
|
|
10
10
|
void rn_whisper_abort_transcribe(int job_id);
|
|
11
11
|
bool rn_whisper_transcribe_is_aborted(int job_id);
|
|
12
12
|
void rn_whisper_abort_all_transcribe();
|
|
13
|
+
bool rn_whisper_vad_simple(std::vector<float> & pcmf32, int sample_rate, int last_ms, float vad_thold, float freq_thold, bool verbose);
|
|
13
14
|
|
|
14
15
|
#ifdef __cplusplus
|
|
15
16
|
}
|
|
16
|
-
#endif
|
|
17
|
+
#endif
|
package/ios/RNWhisper.mm
CHANGED
|
@@ -68,13 +68,17 @@ RCT_REMAP_METHOD(initContext,
|
|
|
68
68
|
path = [[NSBundle mainBundle] pathForResource:modelPath ofType:nil];
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
int contextId = arc4random_uniform(1000000);
|
|
72
|
+
|
|
73
|
+
RNWhisperContext *context = [RNWhisperContext
|
|
74
|
+
initWithModelPath:path
|
|
75
|
+
contextId:contextId
|
|
76
|
+
];
|
|
72
77
|
if ([context getContext] == NULL) {
|
|
73
78
|
reject(@"whisper_cpp_error", @"Failed to load the model", nil);
|
|
74
79
|
return;
|
|
75
80
|
}
|
|
76
81
|
|
|
77
|
-
int contextId = arc4random_uniform(1000000);
|
|
78
82
|
[contexts setObject:context forKey:[NSNumber numberWithInt:contextId]];
|
|
79
83
|
|
|
80
84
|
resolve([NSNumber numberWithInt:contextId]);
|
|
@@ -122,36 +126,36 @@ RCT_REMAP_METHOD(transcribeFile,
|
|
|
122
126
|
reject(@"whisper_error", @"Invalid file", nil);
|
|
123
127
|
return;
|
|
124
128
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
129
|
+
[context transcribeFile:jobId
|
|
130
|
+
audioData:waveFile
|
|
131
|
+
audioDataCount:count
|
|
132
|
+
options:options
|
|
133
|
+
onProgress: ^(int progress) {
|
|
134
|
+
if (rn_whisper_transcribe_is_aborted(jobId)) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
138
|
+
[self sendEventWithName:@"@RNWhisper_onTranscribeProgress"
|
|
139
|
+
body:@{
|
|
140
|
+
@"contextId": [NSNumber numberWithInt:contextId],
|
|
141
|
+
@"jobId": [NSNumber numberWithInt:jobId],
|
|
142
|
+
@"progress": [NSNumber numberWithInt:progress]
|
|
143
|
+
}
|
|
144
|
+
];
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
onEnd: ^(int code) {
|
|
148
|
+
if (code != 0) {
|
|
149
|
+
free(waveFile);
|
|
150
|
+
reject(@"whisper_cpp_error", [NSString stringWithFormat:@"Failed to transcribe the file. Code: %d", code], nil);
|
|
151
|
+
return;
|
|
143
152
|
}
|
|
144
|
-
];
|
|
145
|
-
if (code != 0) {
|
|
146
153
|
free(waveFile);
|
|
147
|
-
|
|
148
|
-
|
|
154
|
+
NSMutableDictionary *result = [context getTextSegments];
|
|
155
|
+
result[@"isAborted"] = @([context isStoppedByAction]);
|
|
156
|
+
resolve(result);
|
|
149
157
|
}
|
|
150
|
-
|
|
151
|
-
NSMutableDictionary *result = [context getTextSegments];
|
|
152
|
-
result[@"isAborted"] = @([context isStoppedByAction]);
|
|
153
|
-
resolve(result);
|
|
154
|
-
});
|
|
158
|
+
];
|
|
155
159
|
}
|
|
156
160
|
|
|
157
161
|
RCT_REMAP_METHOD(startRealtimeTranscribe,
|
|
@@ -260,7 +264,7 @@ RCT_REMAP_METHOD(releaseAllContexts,
|
|
|
260
264
|
}
|
|
261
265
|
|
|
262
266
|
- (void)invalidate {
|
|
263
|
-
|
|
267
|
+
[super invalidate];
|
|
264
268
|
|
|
265
269
|
if (contexts == nil) {
|
|
266
270
|
return;
|
|
@@ -271,6 +275,8 @@ RCT_REMAP_METHOD(releaseAllContexts,
|
|
|
271
275
|
[context invalidate];
|
|
272
276
|
}
|
|
273
277
|
|
|
278
|
+
rn_whisper_abort_all_transcribe(); // graceful abort
|
|
279
|
+
|
|
274
280
|
[contexts removeAllObjects];
|
|
275
281
|
contexts = nil;
|
|
276
282
|
|
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
|
|
9
9
|
/* Begin PBXBuildFile section */
|
|
10
10
|
5E555C0D2413F4C50049A1A2 /* RNWhisper.mm in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* RNWhisper.mm */; };
|
|
11
|
+
7FE0BBA12ABE6C7B0049B4E4 /* RNWhisperDownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FE0BB9B2ABE6C7B0049B4E4 /* RNWhisperDownloader.m */; };
|
|
12
|
+
7FE0BBA22ABE6C7B0049B4E4 /* RNWhisperAudioUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FE0BB9C2ABE6C7B0049B4E4 /* RNWhisperAudioUtils.m */; };
|
|
13
|
+
7FE0BBA32ABE6C7B0049B4E4 /* RNWhisperContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7FE0BBA02ABE6C7B0049B4E4 /* RNWhisperContext.mm */; };
|
|
11
14
|
/* End PBXBuildFile section */
|
|
12
15
|
|
|
13
16
|
/* Begin PBXCopyFilesBuildPhase section */
|
|
@@ -24,6 +27,13 @@
|
|
|
24
27
|
|
|
25
28
|
/* Begin PBXFileReference section */
|
|
26
29
|
134814201AA4EA6300B7C361 /* libRNWhisper.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNWhisper.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
30
|
+
7FE0BB9A2ABE6C7B0049B4E4 /* RNWhisper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNWhisper.h; sourceTree = "<group>"; };
|
|
31
|
+
7FE0BB9B2ABE6C7B0049B4E4 /* RNWhisperDownloader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNWhisperDownloader.m; sourceTree = "<group>"; };
|
|
32
|
+
7FE0BB9C2ABE6C7B0049B4E4 /* RNWhisperAudioUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNWhisperAudioUtils.m; sourceTree = "<group>"; };
|
|
33
|
+
7FE0BB9D2ABE6C7B0049B4E4 /* RNWhisperContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNWhisperContext.h; sourceTree = "<group>"; };
|
|
34
|
+
7FE0BB9E2ABE6C7B0049B4E4 /* RNWhisperDownloader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNWhisperDownloader.h; sourceTree = "<group>"; };
|
|
35
|
+
7FE0BB9F2ABE6C7B0049B4E4 /* RNWhisperAudioUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNWhisperAudioUtils.h; sourceTree = "<group>"; };
|
|
36
|
+
7FE0BBA02ABE6C7B0049B4E4 /* RNWhisperContext.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RNWhisperContext.mm; sourceTree = "<group>"; };
|
|
27
37
|
B3E7B5891CC2AC0600A0062D /* RNWhisper.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RNWhisper.mm; sourceTree = "<group>"; };
|
|
28
38
|
/* End PBXFileReference section */
|
|
29
39
|
|
|
@@ -49,6 +59,13 @@
|
|
|
49
59
|
58B511D21A9E6C8500147676 = {
|
|
50
60
|
isa = PBXGroup;
|
|
51
61
|
children = (
|
|
62
|
+
7FE0BB9F2ABE6C7B0049B4E4 /* RNWhisperAudioUtils.h */,
|
|
63
|
+
7FE0BB9C2ABE6C7B0049B4E4 /* RNWhisperAudioUtils.m */,
|
|
64
|
+
7FE0BB9A2ABE6C7B0049B4E4 /* RNWhisper.h */,
|
|
65
|
+
7FE0BB9D2ABE6C7B0049B4E4 /* RNWhisperContext.h */,
|
|
66
|
+
7FE0BBA02ABE6C7B0049B4E4 /* RNWhisperContext.mm */,
|
|
67
|
+
7FE0BB9E2ABE6C7B0049B4E4 /* RNWhisperDownloader.h */,
|
|
68
|
+
7FE0BB9B2ABE6C7B0049B4E4 /* RNWhisperDownloader.m */,
|
|
52
69
|
B3E7B5891CC2AC0600A0062D /* RNWhisper.mm */,
|
|
53
70
|
134814211AA4EA7D00B7C361 /* Products */,
|
|
54
71
|
);
|
|
@@ -112,6 +129,9 @@
|
|
|
112
129
|
buildActionMask = 2147483647;
|
|
113
130
|
files = (
|
|
114
131
|
5E555C0D2413F4C50049A1A2 /* RNWhisper.mm in Sources */,
|
|
132
|
+
7FE0BBA22ABE6C7B0049B4E4 /* RNWhisperAudioUtils.m in Sources */,
|
|
133
|
+
7FE0BBA32ABE6C7B0049B4E4 /* RNWhisperContext.mm in Sources */,
|
|
134
|
+
7FE0BBA12ABE6C7B0049B4E4 /* RNWhisperDownloader.m in Sources */,
|
|
115
135
|
);
|
|
116
136
|
runOnlyForDeploymentPostprocessing = 0;
|
|
117
137
|
};
|
|
@@ -223,9 +243,7 @@
|
|
|
223
243
|
"$(SRCROOT)/../../react-native/React/**",
|
|
224
244
|
);
|
|
225
245
|
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
|
226
|
-
OTHER_LDFLAGS =
|
|
227
|
-
"-ObjC",
|
|
228
|
-
);
|
|
246
|
+
OTHER_LDFLAGS = "-ObjC";
|
|
229
247
|
PRODUCT_NAME = RNWhisper;
|
|
230
248
|
SKIP_INSTALL = YES;
|
|
231
249
|
};
|
|
Binary file
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
#import <Foundation/Foundation.h>
|
|
2
|
+
|
|
3
|
+
@interface RNWhisperAudioUtils : NSObject
|
|
4
|
+
|
|
5
|
+
+ (NSData *)concatShortBuffers:(NSMutableArray<NSValue *> *)buffers sliceNSamples:(NSMutableArray<NSNumber *> *)sliceNSamples;
|
|
6
|
+
+ (void)saveWavFile:(NSData *)rawData audioOutputFile:(NSString *)audioOutputFile;
|
|
7
|
+
|
|
8
|
+
@end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#import "RNWhisperAudioUtils.h"
|
|
2
|
+
#import "whisper.h"
|
|
3
|
+
|
|
4
|
+
@implementation RNWhisperAudioUtils
|
|
5
|
+
|
|
6
|
+
+ (NSData *)concatShortBuffers:(NSMutableArray<NSValue *> *)buffers sliceNSamples:(NSMutableArray<NSNumber *> *)sliceNSamples {
|
|
7
|
+
NSMutableData *outputData = [NSMutableData data];
|
|
8
|
+
for (int i = 0; i < buffers.count; i++) {
|
|
9
|
+
int size = [sliceNSamples objectAtIndex:i].intValue;
|
|
10
|
+
NSValue *buffer = [buffers objectAtIndex:i];
|
|
11
|
+
short *bufferPtr = buffer.pointerValue;
|
|
12
|
+
[outputData appendBytes:bufferPtr length:size * sizeof(short)];
|
|
13
|
+
}
|
|
14
|
+
return outputData;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
+ (void)saveWavFile:(NSData *)rawData audioOutputFile:(NSString *)audioOutputFile {
|
|
18
|
+
NSMutableData *outputData = [NSMutableData data];
|
|
19
|
+
|
|
20
|
+
// WAVE header
|
|
21
|
+
[outputData appendData:[@"RIFF" dataUsingEncoding:NSUTF8StringEncoding]]; // chunk id
|
|
22
|
+
int chunkSize = CFSwapInt32HostToLittle(36 + rawData.length);
|
|
23
|
+
[outputData appendBytes:&chunkSize length:sizeof(chunkSize)];
|
|
24
|
+
[outputData appendData:[@"WAVE" dataUsingEncoding:NSUTF8StringEncoding]]; // format
|
|
25
|
+
[outputData appendData:[@"fmt " dataUsingEncoding:NSUTF8StringEncoding]]; // subchunk 1 id
|
|
26
|
+
|
|
27
|
+
int subchunk1Size = CFSwapInt32HostToLittle(16);
|
|
28
|
+
[outputData appendBytes:&subchunk1Size length:sizeof(subchunk1Size)];
|
|
29
|
+
|
|
30
|
+
short audioFormat = CFSwapInt16HostToLittle(1); // PCM
|
|
31
|
+
[outputData appendBytes:&audioFormat length:sizeof(audioFormat)];
|
|
32
|
+
|
|
33
|
+
short numChannels = CFSwapInt16HostToLittle(1); // mono
|
|
34
|
+
[outputData appendBytes:&numChannels length:sizeof(numChannels)];
|
|
35
|
+
|
|
36
|
+
int sampleRate = CFSwapInt32HostToLittle(WHISPER_SAMPLE_RATE);
|
|
37
|
+
[outputData appendBytes:&sampleRate length:sizeof(sampleRate)];
|
|
38
|
+
|
|
39
|
+
// (bitDepth * sampleRate * channels) >> 3
|
|
40
|
+
int byteRate = CFSwapInt32HostToLittle(WHISPER_SAMPLE_RATE * 1 * 16 / 8);
|
|
41
|
+
[outputData appendBytes:&byteRate length:sizeof(byteRate)];
|
|
42
|
+
|
|
43
|
+
// (bitDepth * channels) >> 3
|
|
44
|
+
short blockAlign = CFSwapInt16HostToLittle(16 / 8);
|
|
45
|
+
[outputData appendBytes:&blockAlign length:sizeof(blockAlign)];
|
|
46
|
+
|
|
47
|
+
// bitDepth
|
|
48
|
+
short bitsPerSample = CFSwapInt16HostToLittle(16);
|
|
49
|
+
[outputData appendBytes:&bitsPerSample length:sizeof(bitsPerSample)];
|
|
50
|
+
|
|
51
|
+
[outputData appendData:[@"data" dataUsingEncoding:NSUTF8StringEncoding]]; // subchunk 2 id
|
|
52
|
+
int subchunk2Size = CFSwapInt32HostToLittle((int)rawData.length);
|
|
53
|
+
[outputData appendBytes:&subchunk2Size length:sizeof(subchunk2Size)];
|
|
54
|
+
|
|
55
|
+
// Audio data
|
|
56
|
+
[outputData appendData:rawData];
|
|
57
|
+
|
|
58
|
+
// Save to file
|
|
59
|
+
[outputData writeToFile:audioOutputFile atomically:YES];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@end
|
package/ios/RNWhisperContext.h
CHANGED
|
@@ -36,21 +36,26 @@ typedef struct {
|
|
|
36
36
|
} RNWhisperContextRecordState;
|
|
37
37
|
|
|
38
38
|
@interface RNWhisperContext : NSObject {
|
|
39
|
+
int contextId;
|
|
40
|
+
dispatch_queue_t dQueue;
|
|
39
41
|
struct whisper_context * ctx;
|
|
40
42
|
RNWhisperContextRecordState recordState;
|
|
41
43
|
}
|
|
42
44
|
|
|
43
|
-
+ (instancetype)initWithModelPath:(NSString *)modelPath;
|
|
45
|
+
+ (instancetype)initWithModelPath:(NSString *)modelPath contextId:(int)contextId;
|
|
44
46
|
- (struct whisper_context *)getContext;
|
|
47
|
+
- (dispatch_queue_t)getDispatchQueue;
|
|
45
48
|
- (OSStatus)transcribeRealtime:(int)jobId
|
|
46
49
|
options:(NSDictionary *)options
|
|
47
50
|
onTranscribe:(void (^)(int, NSString *, NSDictionary *))onTranscribe;
|
|
48
|
-
- (
|
|
51
|
+
- (void)transcribeFile:(int)jobId
|
|
49
52
|
audioData:(float *)audioData
|
|
50
53
|
audioDataCount:(int)audioDataCount
|
|
51
54
|
options:(NSDictionary *)options
|
|
52
|
-
onProgress:(void (^)(int))onProgress
|
|
55
|
+
onProgress:(void (^)(int))onProgress
|
|
56
|
+
onEnd:(void (^)(int))onEnd;
|
|
53
57
|
- (void)stopTranscribe:(int)jobId;
|
|
58
|
+
- (void)stopCurrentTranscribe;
|
|
54
59
|
- (bool)isCapturing;
|
|
55
60
|
- (bool)isTranscribing;
|
|
56
61
|
- (bool)isStoppedByAction;
|
package/ios/RNWhisperContext.mm
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
#import "RNWhisperContext.h"
|
|
2
|
+
#import "RNWhisperAudioUtils.h"
|
|
3
|
+
#include <vector>
|
|
2
4
|
|
|
3
5
|
#define NUM_BYTES_PER_BUFFER 16 * 1024
|
|
4
6
|
|
|
5
7
|
@implementation RNWhisperContext
|
|
6
8
|
|
|
7
|
-
+ (instancetype)initWithModelPath:(NSString *)modelPath {
|
|
9
|
+
+ (instancetype)initWithModelPath:(NSString *)modelPath contextId:(int)contextId {
|
|
8
10
|
RNWhisperContext *context = [[RNWhisperContext alloc] init];
|
|
11
|
+
context->contextId = contextId;
|
|
9
12
|
context->ctx = whisper_init_from_file([modelPath UTF8String]);
|
|
13
|
+
context->dQueue = dispatch_queue_create(
|
|
14
|
+
[[NSString stringWithFormat:@"RNWhisperContext-%d", contextId] UTF8String],
|
|
15
|
+
DISPATCH_QUEUE_SERIAL
|
|
16
|
+
);
|
|
10
17
|
return context;
|
|
11
18
|
}
|
|
12
19
|
|
|
@@ -14,6 +21,10 @@
|
|
|
14
21
|
return self->ctx;
|
|
15
22
|
}
|
|
16
23
|
|
|
24
|
+
- (dispatch_queue_t)getDispatchQueue {
|
|
25
|
+
return self->dQueue;
|
|
26
|
+
}
|
|
27
|
+
|
|
17
28
|
- (void)prepareRealtime:(NSDictionary *)options {
|
|
18
29
|
self->recordState.options = options;
|
|
19
30
|
|
|
@@ -68,6 +79,29 @@
|
|
|
68
79
|
}
|
|
69
80
|
}
|
|
70
81
|
|
|
82
|
+
bool vad(RNWhisperContextRecordState *state, int16_t* audioBufferI16, int nSamples, int n)
|
|
83
|
+
{
|
|
84
|
+
bool isSpeech = true;
|
|
85
|
+
if (!state->isTranscribing && state->options[@"useVad"]) {
|
|
86
|
+
int vadSec = state->options[@"vadMs"] != nil ? [state->options[@"vadMs"] intValue] / 1000 : 2;
|
|
87
|
+
int sampleSize = vadSec * WHISPER_SAMPLE_RATE;
|
|
88
|
+
if (nSamples + n > sampleSize) {
|
|
89
|
+
int start = nSamples + n - sampleSize;
|
|
90
|
+
std::vector<float> audioBufferF32Vec(sampleSize);
|
|
91
|
+
for (int i = 0; i < sampleSize; i++) {
|
|
92
|
+
audioBufferF32Vec[i] = (float)audioBufferI16[i + start] / 32768.0f;
|
|
93
|
+
}
|
|
94
|
+
float vadThold = state->options[@"vadThold"] != nil ? [state->options[@"vadThold"] floatValue] : 0.6f;
|
|
95
|
+
float vadFreqThold = state->options[@"vadFreqThold"] != nil ? [state->options[@"vadFreqThold"] floatValue] : 100.0f;
|
|
96
|
+
isSpeech = rn_whisper_vad_simple(audioBufferF32Vec, WHISPER_SAMPLE_RATE, 1000, vadThold, vadFreqThold, false);
|
|
97
|
+
NSLog(@"[RNWhisper] VAD result: %d", isSpeech);
|
|
98
|
+
} else {
|
|
99
|
+
isSpeech = false;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return isSpeech;
|
|
103
|
+
}
|
|
104
|
+
|
|
71
105
|
void AudioInputCallback(void * inUserData,
|
|
72
106
|
AudioQueueRef inAQ,
|
|
73
107
|
AudioQueueBufferRef inBuffer,
|
|
@@ -108,8 +142,13 @@ void AudioInputCallback(void * inUserData,
|
|
|
108
142
|
!state->isTranscribing &&
|
|
109
143
|
nSamples != state->nSamplesTranscribing
|
|
110
144
|
) {
|
|
145
|
+
int16_t* audioBufferI16 = (int16_t*) [state->shortBufferSlices[state->sliceIndex] pointerValue];
|
|
146
|
+
if (!vad(state, audioBufferI16, nSamples, 0)) {
|
|
147
|
+
state->transcribeHandler(state->jobId, @"end", @{});
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
111
150
|
state->isTranscribing = true;
|
|
112
|
-
dispatch_async(
|
|
151
|
+
dispatch_async([state->mSelf getDispatchQueue], ^{
|
|
113
152
|
[state->mSelf fullTranscribeSamples:state];
|
|
114
153
|
});
|
|
115
154
|
}
|
|
@@ -133,14 +172,18 @@ void AudioInputCallback(void * inUserData,
|
|
|
133
172
|
for (int i = 0; i < n; i++) {
|
|
134
173
|
audioBufferI16[nSamples + i] = ((short*)inBuffer->mAudioData)[i];
|
|
135
174
|
}
|
|
175
|
+
|
|
176
|
+
bool isSpeech = vad(state, audioBufferI16, nSamples, n);
|
|
136
177
|
nSamples += n;
|
|
137
178
|
state->sliceNSamples[state->sliceIndex] = [NSNumber numberWithInt:nSamples];
|
|
138
179
|
|
|
139
180
|
AudioQueueEnqueueBuffer(state->queue, inBuffer, 0, NULL);
|
|
140
181
|
|
|
182
|
+
if (!isSpeech) return;
|
|
183
|
+
|
|
141
184
|
if (!state->isTranscribing) {
|
|
142
185
|
state->isTranscribing = true;
|
|
143
|
-
dispatch_async(
|
|
186
|
+
dispatch_async([state->mSelf getDispatchQueue], ^{
|
|
144
187
|
[state->mSelf fullTranscribeSamples:state];
|
|
145
188
|
});
|
|
146
189
|
}
|
|
@@ -203,6 +246,17 @@ void AudioInputCallback(void * inUserData,
|
|
|
203
246
|
NSLog(@"[RNWhisper] Transcribe end");
|
|
204
247
|
result[@"isStoppedByAction"] = @(state->isStoppedByAction);
|
|
205
248
|
result[@"isCapturing"] = @(false);
|
|
249
|
+
|
|
250
|
+
// Save wav if needed
|
|
251
|
+
if (state->options[@"audioOutputPath"] != nil) {
|
|
252
|
+
// TODO: Append in real time so we don't need to keep all slices & also reduce memory usage
|
|
253
|
+
[RNWhisperAudioUtils
|
|
254
|
+
saveWavFile:[RNWhisperAudioUtils concatShortBuffers:state->shortBufferSlices
|
|
255
|
+
sliceNSamples:state->sliceNSamples]
|
|
256
|
+
audioOutputFile:state->options[@"audioOutputPath"]
|
|
257
|
+
];
|
|
258
|
+
}
|
|
259
|
+
|
|
206
260
|
state->transcribeHandler(state->jobId, @"end", result);
|
|
207
261
|
} else if (code == 0) {
|
|
208
262
|
result[@"isCapturing"] = @(true);
|
|
@@ -263,19 +317,22 @@ void AudioInputCallback(void * inUserData,
|
|
|
263
317
|
return status;
|
|
264
318
|
}
|
|
265
319
|
|
|
266
|
-
- (
|
|
320
|
+
- (void)transcribeFile:(int)jobId
|
|
267
321
|
audioData:(float *)audioData
|
|
268
322
|
audioDataCount:(int)audioDataCount
|
|
269
323
|
options:(NSDictionary *)options
|
|
270
324
|
onProgress:(void (^)(int))onProgress
|
|
325
|
+
onEnd:(void (^)(int))onEnd
|
|
271
326
|
{
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
327
|
+
dispatch_async(dQueue, ^{
|
|
328
|
+
self->recordState.isStoppedByAction = false;
|
|
329
|
+
self->recordState.isTranscribing = true;
|
|
330
|
+
self->recordState.jobId = jobId;
|
|
331
|
+
int code = [self fullTranscribeWithProgress:onProgress jobId:jobId audioData:audioData audioDataCount:audioDataCount options:options];
|
|
332
|
+
self->recordState.jobId = -1;
|
|
333
|
+
self->recordState.isTranscribing = false;
|
|
334
|
+
onEnd(code);
|
|
335
|
+
});
|
|
279
336
|
}
|
|
280
337
|
|
|
281
338
|
- (void)stopAudio {
|
|
@@ -293,6 +350,7 @@ void AudioInputCallback(void * inUserData,
|
|
|
293
350
|
}
|
|
294
351
|
self->recordState.isCapturing = false;
|
|
295
352
|
self->recordState.isStoppedByAction = true;
|
|
353
|
+
dispatch_barrier_sync(dQueue, ^{});
|
|
296
354
|
}
|
|
297
355
|
|
|
298
356
|
- (void)stopCurrentTranscribe {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_reactNative","require","_NativeRNWhisper","_interopRequireDefault","_version","_RNWhisper$getConstan","obj","__esModule","default","EventEmitter","Platform","OS","NativeEventEmitter","RNWhisper","DeviceEventEmitter","EVENT_ON_TRANSCRIBE_PROGRESS","EVENT_ON_REALTIME_TRANSCRIBE","EVENT_ON_REALTIME_TRANSCRIBE_END","WhisperContext","constructor","id","transcribe","filePath","options","arguments","length","undefined","path","source","Image","resolveAssetSource","uri","e","Error","startsWith","slice","jobId","Math","floor","random","onProgress","rest","progressListener","lastProgress","addListener","evt","contextId","progress","removeProgressListener","remove","stop","abortTranscribe","promise","transcribeFile","then","result","isAborted","catch","transcribeRealtime","startRealtimeTranscribe","lastTranscribePayload","slices","sliceIndex","tOffset","putSlice","payload","isUseSlices","_slices$sliceIndex","_segments","segments","data","t1","map","segment","t0","mergeSlicesIfNeeded","mergedPayload","forEach","_mergedPayload$data","_slice$data","_mergedPayload$data2","_slice$data2","processTime","recordingTime","subscribe","callback","transcribeListener","endListener","lastPayload","isCapturing","release","releaseContext","exports","coreMLModelAssetPaths","initWhisper","_ref","coreMLModelAsset","isBundleAsset","coreMLAssets","filename","assets","asset","filepath","find","p","includes","filter","initContext","downloadCoreMLAssets","__DEV__","releaseAllWhisper","releaseAllContexts","libVersion","version","useCoreML","coreMLAllowFallback","getConstants","call","isUseCoreML","isCoreMLAllowFallback"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;;;;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAOA,IAAAC,gBAAA,GAAAC,sBAAA,CAAAF,OAAA;AAMA,IAAAG,QAAA,GAAAH,OAAA;AAAwC,IAAAI,qBAAA;AAAA,SAAAF,uBAAAG,GAAA,WAAAA,GAAA,IAAAA,GAAA,CAAAC,UAAA,GAAAD,GAAA,KAAAE,OAAA,EAAAF,GAAA;AAExC,IAAIG,YAA2D;AAC/D,IAAIC,qBAAQ,CAACC,EAAE,KAAK,KAAK,EAAE;EACzB;EACAF,YAAY,GAAG,IAAIG,+BAAkB,CAACC,wBAAS,CAAC;AAClD;AACA,IAAIH,qBAAQ,CAACC,EAAE,KAAK,SAAS,EAAE;EAC7BF,YAAY,GAAGK,+BAAkB;AACnC;AAKA,MAAMC,4BAA4B,GAAG,iCAAiC;AAEtE,MAAMC,4BAA4B,GAAG,iCAAiC;AACtE,MAAMC,gCAAgC,GAAG,oCAAoC;;AAE7E;;
|
|
1
|
+
{"version":3,"names":["_reactNative","require","_NativeRNWhisper","_interopRequireDefault","_version","_RNWhisper$getConstan","obj","__esModule","default","EventEmitter","Platform","OS","NativeEventEmitter","RNWhisper","DeviceEventEmitter","EVENT_ON_TRANSCRIBE_PROGRESS","EVENT_ON_REALTIME_TRANSCRIBE","EVENT_ON_REALTIME_TRANSCRIBE_END","WhisperContext","constructor","id","transcribe","filePath","options","arguments","length","undefined","path","source","Image","resolveAssetSource","uri","e","Error","startsWith","slice","jobId","Math","floor","random","onProgress","rest","progressListener","lastProgress","addListener","evt","contextId","progress","removeProgressListener","remove","stop","abortTranscribe","promise","transcribeFile","then","result","isAborted","catch","transcribeRealtime","startRealtimeTranscribe","lastTranscribePayload","slices","sliceIndex","tOffset","putSlice","payload","isUseSlices","_slices$sliceIndex","_segments","segments","data","t1","map","segment","t0","mergeSlicesIfNeeded","mergedPayload","forEach","_mergedPayload$data","_slice$data","_mergedPayload$data2","_slice$data2","processTime","recordingTime","subscribe","callback","transcribeListener","endListener","lastPayload","isCapturing","release","releaseContext","exports","coreMLModelAssetPaths","initWhisper","_ref","coreMLModelAsset","isBundleAsset","coreMLAssets","filename","assets","asset","filepath","find","p","includes","filter","initContext","downloadCoreMLAssets","__DEV__","releaseAllWhisper","releaseAllContexts","libVersion","version","useCoreML","coreMLAllowFallback","getConstants","call","isUseCoreML","isCoreMLAllowFallback"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":"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"}
|
package/lib/module/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["NativeEventEmitter","DeviceEventEmitter","Platform","Image","RNWhisper","version","EventEmitter","OS","EVENT_ON_TRANSCRIBE_PROGRESS","EVENT_ON_REALTIME_TRANSCRIBE","EVENT_ON_REALTIME_TRANSCRIBE_END","WhisperContext","constructor","id","transcribe","filePath","options","arguments","length","undefined","path","source","resolveAssetSource","uri","e","Error","startsWith","slice","jobId","Math","floor","random","onProgress","rest","progressListener","lastProgress","addListener","evt","contextId","progress","removeProgressListener","remove","stop","abortTranscribe","promise","transcribeFile","then","result","isAborted","catch","transcribeRealtime","startRealtimeTranscribe","lastTranscribePayload","slices","sliceIndex","tOffset","putSlice","payload","isUseSlices","_slices$sliceIndex","_segments","segments","data","t1","map","segment","t0","mergeSlicesIfNeeded","mergedPayload","forEach","_mergedPayload$data","_slice$data","_mergedPayload$data2","_slice$data2","processTime","recordingTime","subscribe","callback","transcribeListener","endListener","lastPayload","isCapturing","release","releaseContext","coreMLModelAssetPaths","initWhisper","_ref","coreMLModelAsset","isBundleAsset","coreMLAssets","filename","assets","asset","filepath","find","p","includes","filter","initContext","downloadCoreMLAssets","__DEV__","releaseAllWhisper","releaseAllContexts","libVersion","useCoreML","coreMLAllowFallback","_RNWhisper$getConstan","getConstants","call","isUseCoreML","isCoreMLAllowFallback"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";AAAA,SACEA,kBAAkB,EAClBC,kBAAkB,EAClBC,QAAQ,EAERC,KAAK,QACA,cAAc;AACrB,OAAOC,SAAS,MAAM,mBAAmB;AAMzC,SAASC,OAAO,QAAQ,gBAAgB;AAExC,IAAIC,YAA2D;AAC/D,IAAIJ,QAAQ,CAACK,EAAE,KAAK,KAAK,EAAE;EACzB;EACAD,YAAY,GAAG,IAAIN,kBAAkB,CAACI,SAAS,CAAC;AAClD;AACA,IAAIF,QAAQ,CAACK,EAAE,KAAK,SAAS,EAAE;EAC7BD,YAAY,GAAGL,kBAAkB;AACnC;AAKA,MAAMO,4BAA4B,GAAG,iCAAiC;AAEtE,MAAMC,4BAA4B,GAAG,iCAAiC;AACtE,MAAMC,gCAAgC,GAAG,oCAAoC;;AAE7E;;
|
|
1
|
+
{"version":3,"names":["NativeEventEmitter","DeviceEventEmitter","Platform","Image","RNWhisper","version","EventEmitter","OS","EVENT_ON_TRANSCRIBE_PROGRESS","EVENT_ON_REALTIME_TRANSCRIBE","EVENT_ON_REALTIME_TRANSCRIBE_END","WhisperContext","constructor","id","transcribe","filePath","options","arguments","length","undefined","path","source","resolveAssetSource","uri","e","Error","startsWith","slice","jobId","Math","floor","random","onProgress","rest","progressListener","lastProgress","addListener","evt","contextId","progress","removeProgressListener","remove","stop","abortTranscribe","promise","transcribeFile","then","result","isAborted","catch","transcribeRealtime","startRealtimeTranscribe","lastTranscribePayload","slices","sliceIndex","tOffset","putSlice","payload","isUseSlices","_slices$sliceIndex","_segments","segments","data","t1","map","segment","t0","mergeSlicesIfNeeded","mergedPayload","forEach","_mergedPayload$data","_slice$data","_mergedPayload$data2","_slice$data2","processTime","recordingTime","subscribe","callback","transcribeListener","endListener","lastPayload","isCapturing","release","releaseContext","coreMLModelAssetPaths","initWhisper","_ref","coreMLModelAsset","isBundleAsset","coreMLAssets","filename","assets","asset","filepath","find","p","includes","filter","initContext","downloadCoreMLAssets","__DEV__","releaseAllWhisper","releaseAllContexts","libVersion","useCoreML","coreMLAllowFallback","_RNWhisper$getConstan","getConstants","call","isUseCoreML","isCoreMLAllowFallback"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":"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"}
|
|
@@ -24,6 +24,29 @@ export type TranscribeRealtimeOptions = TranscribeOptions & {
|
|
|
24
24
|
* (Default: Equal to `realtimeMaxAudioSec`)
|
|
25
25
|
*/
|
|
26
26
|
realtimeAudioSliceSec?: number;
|
|
27
|
+
/**
|
|
28
|
+
* Output path for audio file. If not set, the audio file will not be saved
|
|
29
|
+
* (Default: Undefined)
|
|
30
|
+
*/
|
|
31
|
+
audioOutputPath?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Start transcribe on recording when the audio volume is greater than the threshold by using VAD (Voice Activity Detection).
|
|
34
|
+
* The first VAD will be triggered after 2 second of recording.
|
|
35
|
+
* (Default: false)
|
|
36
|
+
*/
|
|
37
|
+
useVad?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* The length of the collected audio is used for VAD. (ms) (Default: 2000)
|
|
40
|
+
*/
|
|
41
|
+
vadMs?: number;
|
|
42
|
+
/**
|
|
43
|
+
* VAD threshold. (Default: 0.6)
|
|
44
|
+
*/
|
|
45
|
+
vadThold?: number;
|
|
46
|
+
/**
|
|
47
|
+
* Frequency to apply High-pass filter in VAD. (Default: 100.0)
|
|
48
|
+
*/
|
|
49
|
+
vadFreqThold?: number;
|
|
27
50
|
};
|
|
28
51
|
export type TranscribeRealtimeEvent = {
|
|
29
52
|
contextId: number;
|
|
@@ -67,14 +90,14 @@ export declare class WhisperContext {
|
|
|
67
90
|
/** Transcribe audio file */
|
|
68
91
|
transcribe(filePath: string | number, options?: TranscribeFileOptions): {
|
|
69
92
|
/** Stop the transcribe */
|
|
70
|
-
stop: () => void
|
|
93
|
+
stop: () => Promise<void>;
|
|
71
94
|
/** Transcribe result promise */
|
|
72
95
|
promise: Promise<TranscribeResult>;
|
|
73
96
|
};
|
|
74
97
|
/** Transcribe the microphone audio stream, the microphone user permission is required */
|
|
75
98
|
transcribeRealtime(options?: TranscribeRealtimeOptions): Promise<{
|
|
76
99
|
/** Stop the realtime transcribe */
|
|
77
|
-
stop: () => void
|
|
100
|
+
stop: () => Promise<void>;
|
|
78
101
|
/** Subscribe to realtime transcribe events */
|
|
79
102
|
subscribe: (callback: (event: TranscribeRealtimeEvent) => void) => void;
|
|
80
103
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,iBAAiB,EACjB,gBAAgB,EAEjB,MAAM,mBAAmB,CAAA;AAY1B,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,CAAA;AASnD,MAAM,MAAM,qBAAqB,GAAG,iBAAiB,GAAG;IACtD;;OAEG;IACH,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;CACxC,CAAA;AAED,MAAM,MAAM,6BAA6B,GAAG;IAC1C,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAGD,MAAM,MAAM,yBAAyB,GAAG,iBAAiB,GAAG;IAC1D;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -58,6 +58,29 @@ export type TranscribeRealtimeOptions = TranscribeOptions & {
|
|
|
58
58
|
* (Default: Equal to `realtimeMaxAudioSec`)
|
|
59
59
|
*/
|
|
60
60
|
realtimeAudioSliceSec?: number
|
|
61
|
+
/**
|
|
62
|
+
* Output path for audio file. If not set, the audio file will not be saved
|
|
63
|
+
* (Default: Undefined)
|
|
64
|
+
*/
|
|
65
|
+
audioOutputPath?: string
|
|
66
|
+
/**
|
|
67
|
+
* Start transcribe on recording when the audio volume is greater than the threshold by using VAD (Voice Activity Detection).
|
|
68
|
+
* The first VAD will be triggered after 2 second of recording.
|
|
69
|
+
* (Default: false)
|
|
70
|
+
*/
|
|
71
|
+
useVad?: boolean
|
|
72
|
+
/**
|
|
73
|
+
* The length of the collected audio is used for VAD. (ms) (Default: 2000)
|
|
74
|
+
*/
|
|
75
|
+
vadMs?: number
|
|
76
|
+
/**
|
|
77
|
+
* VAD threshold. (Default: 0.6)
|
|
78
|
+
*/
|
|
79
|
+
vadThold?: number
|
|
80
|
+
/**
|
|
81
|
+
* Frequency to apply High-pass filter in VAD. (Default: 100.0)
|
|
82
|
+
*/
|
|
83
|
+
vadFreqThold?: number
|
|
61
84
|
}
|
|
62
85
|
|
|
63
86
|
export type TranscribeRealtimeEvent = {
|
|
@@ -112,7 +135,7 @@ export class WhisperContext {
|
|
|
112
135
|
options: TranscribeFileOptions = {},
|
|
113
136
|
): {
|
|
114
137
|
/** Stop the transcribe */
|
|
115
|
-
stop: () => void
|
|
138
|
+
stop: () => Promise<void>
|
|
116
139
|
/** Transcribe result promise */
|
|
117
140
|
promise: Promise<TranscribeResult>
|
|
118
141
|
} {
|
|
@@ -177,7 +200,7 @@ export class WhisperContext {
|
|
|
177
200
|
/** Transcribe the microphone audio stream, the microphone user permission is required */
|
|
178
201
|
async transcribeRealtime(options: TranscribeRealtimeOptions = {}): Promise<{
|
|
179
202
|
/** Stop the realtime transcribe */
|
|
180
|
-
stop: () => void
|
|
203
|
+
stop: () => Promise<void>
|
|
181
204
|
/** Subscribe to realtime transcribe events */
|
|
182
205
|
subscribe: (callback: (event: TranscribeRealtimeEvent) => void) => void
|
|
183
206
|
}> {
|