whisper.rn 0.3.3 → 0.3.5

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.
@@ -1,19 +1,12 @@
1
1
  package com.rnwhisper;
2
2
 
3
3
  import androidx.annotation.NonNull;
4
- import android.util.Log;
5
- import android.os.Build;
6
- import android.os.Handler;
7
- import android.os.AsyncTask;
8
- import android.media.AudioRecord;
9
4
 
10
5
  import com.facebook.react.bridge.Promise;
11
6
  import com.facebook.react.bridge.ReactApplicationContext;
12
7
  import com.facebook.react.bridge.ReactContextBaseJavaModule;
13
8
  import com.facebook.react.bridge.ReactMethod;
14
- import com.facebook.react.bridge.LifecycleEventListener;
15
9
  import com.facebook.react.bridge.ReadableMap;
16
- import com.facebook.react.bridge.WritableMap;
17
10
  import com.facebook.react.module.annotations.ReactModule;
18
11
 
19
12
  import java.util.HashMap;
@@ -23,17 +16,14 @@ import java.io.FileInputStream;
23
16
  import java.io.PushbackInputStream;
24
17
 
25
18
  @ReactModule(name = RNWhisperModule.NAME)
26
- public class RNWhisperModule extends ReactContextBaseJavaModule implements LifecycleEventListener {
19
+ public class RNWhisperModule extends ReactContextBaseJavaModule {
27
20
  public static final String NAME = "RNWhisper";
28
21
 
29
- private ReactApplicationContext reactContext;
30
- private Downloader downloader;
22
+ private RNWhisper rnwhisper;
31
23
 
32
24
  public RNWhisperModule(ReactApplicationContext reactContext) {
33
25
  super(reactContext);
34
- reactContext.addLifecycleEventListener(this);
35
- this.reactContext = reactContext;
36
- this.downloader = new Downloader(reactContext);
26
+ rnwhisper = new RNWhisper(reactContext);
37
27
  }
38
28
 
39
29
  @Override
@@ -42,234 +32,38 @@ public class RNWhisperModule extends ReactContextBaseJavaModule implements Lifec
42
32
  return NAME;
43
33
  }
44
34
 
45
- private HashMap<Integer, WhisperContext> contexts = new HashMap<>();
46
-
47
- private int getResourceIdentifier(String filePath) {
48
- int identifier = reactContext.getResources().getIdentifier(
49
- filePath,
50
- "drawable",
51
- reactContext.getPackageName()
52
- );
53
- if (identifier == 0) {
54
- identifier = reactContext.getResources().getIdentifier(
55
- filePath,
56
- "raw",
57
- reactContext.getPackageName()
58
- );
59
- }
60
- return identifier;
35
+ @Override
36
+ public HashMap<String, Object> getConstants() {
37
+ return rnwhisper.getTypedExportedConstants();
61
38
  }
62
39
 
63
40
  @ReactMethod
64
41
  public void initContext(final ReadableMap options, final Promise promise) {
65
- new AsyncTask<Void, Void, Integer>() {
66
- private Exception exception;
67
-
68
- @Override
69
- protected Integer doInBackground(Void... voids) {
70
- try {
71
- String modelPath = options.getString("filePath");
72
- boolean isBundleAsset = options.getBoolean("isBundleAsset");
73
-
74
- String modelFilePath = modelPath;
75
- if (!isBundleAsset && (modelPath.startsWith("http://") || modelPath.startsWith("https://"))) {
76
- modelFilePath = downloader.downloadFile(modelPath);
77
- }
78
-
79
- long context;
80
- int resId = getResourceIdentifier(modelFilePath);
81
- if (resId > 0) {
82
- context = WhisperContext.initContextWithInputStream(
83
- new PushbackInputStream(reactContext.getResources().openRawResource(resId))
84
- );
85
- } else if (isBundleAsset) {
86
- context = WhisperContext.initContextWithAsset(reactContext.getAssets(), modelFilePath);
87
- } else {
88
- context = WhisperContext.initContext(modelFilePath);
89
- }
90
- if (context == 0) {
91
- throw new Exception("Failed to initialize context");
92
- }
93
- int id = Math.abs(new Random().nextInt());
94
- WhisperContext whisperContext = new WhisperContext(id, reactContext, context);
95
- contexts.put(id, whisperContext);
96
- return id;
97
- } catch (Exception e) {
98
- exception = e;
99
- return null;
100
- }
101
- }
102
-
103
- @Override
104
- protected void onPostExecute(Integer id) {
105
- if (exception != null) {
106
- promise.reject(exception);
107
- return;
108
- }
109
- promise.resolve(id);
110
- }
111
- }.execute();
42
+ rnwhisper.initContext(options, promise);
112
43
  }
113
44
 
114
45
  @ReactMethod
115
- public void transcribeFile(int id, int jobId, String filePath, ReadableMap options, Promise promise) {
116
- final WhisperContext context = contexts.get(id);
117
- if (context == null) {
118
- promise.reject("Context not found");
119
- return;
120
- }
121
- if (context.isCapturing()) {
122
- promise.reject("The context is in realtime transcribe mode");
123
- return;
124
- }
125
- if (context.isTranscribing()) {
126
- promise.reject("Context is already transcribing");
127
- return;
128
- }
129
- new AsyncTask<Void, Void, WritableMap>() {
130
- private Exception exception;
131
-
132
- @Override
133
- protected WritableMap doInBackground(Void... voids) {
134
- try {
135
- String waveFilePath = filePath;
136
-
137
- if (filePath.startsWith("http://") || filePath.startsWith("https://")) {
138
- waveFilePath = downloader.downloadFile(filePath);
139
- }
140
-
141
- int resId = getResourceIdentifier(waveFilePath);
142
- if (resId > 0) {
143
- return context.transcribeInputStream(
144
- (int) jobId,
145
- reactContext.getResources().openRawResource(resId),
146
- options
147
- );
148
- }
149
-
150
- return context.transcribeInputStream(
151
- (int) jobId,
152
- new FileInputStream(new File(waveFilePath)),
153
- options
154
- );
155
- } catch (Exception e) {
156
- exception = e;
157
- return null;
158
- }
159
- }
160
-
161
- @Override
162
- protected void onPostExecute(WritableMap data) {
163
- if (exception != null) {
164
- promise.reject(exception);
165
- return;
166
- }
167
- promise.resolve(data);
168
- }
169
- }.execute();
46
+ public void transcribeFile(double id, double jobId, String filePath, ReadableMap options, Promise promise) {
47
+ rnwhisper.transcribeFile(id, jobId, filePath, options, promise);
170
48
  }
171
49
 
172
50
  @ReactMethod
173
- public void startRealtimeTranscribe(int id, int jobId, ReadableMap options, Promise promise) {
174
- final WhisperContext context = contexts.get(id);
175
- if (context == null) {
176
- promise.reject("Context not found");
177
- return;
178
- }
179
- if (context.isCapturing()) {
180
- promise.reject("Context is already in capturing");
181
- return;
182
- }
183
- int state = context.startRealtimeTranscribe(jobId, options);
184
- if (state == AudioRecord.STATE_INITIALIZED) {
185
- promise.resolve(null);
186
- return;
187
- }
188
- promise.reject("Failed to start realtime transcribe. State: " + state);
51
+ public void startRealtimeTranscribe(double id, double jobId, ReadableMap options, Promise promise) {
52
+ rnwhisper.startRealtimeTranscribe(id, jobId, options, promise);
189
53
  }
190
54
 
191
55
  @ReactMethod
192
- public void abortTranscribe(int contextId, int jobId, Promise promise) {
193
- WhisperContext context = contexts.get(contextId);
194
- if (context == null) {
195
- promise.reject("Context not found");
196
- return;
197
- }
198
- context.stopTranscribe(jobId);
56
+ public void abortTranscribe(double contextId, double jobId, Promise promise) {
57
+ rnwhisper.abortTranscribe(contextId, jobId, promise);
199
58
  }
200
59
 
201
60
  @ReactMethod
202
- public void releaseContext(int id, Promise promise) {
203
- new AsyncTask<Void, Void, Void>() {
204
- private Exception exception;
205
-
206
- @Override
207
- protected Void doInBackground(Void... voids) {
208
- try {
209
- WhisperContext context = contexts.get(id);
210
- if (context == null) {
211
- throw new Exception("Context " + id + " not found");
212
- }
213
- context.release();
214
- contexts.remove(id);
215
- } catch (Exception e) {
216
- exception = e;
217
- }
218
- return null;
219
- }
220
-
221
- @Override
222
- protected void onPostExecute(Void result) {
223
- if (exception != null) {
224
- promise.reject(exception);
225
- return;
226
- }
227
- promise.resolve(null);
228
- }
229
- }.execute();
61
+ public void releaseContext(double id, Promise promise) {
62
+ rnwhisper.releaseContext(id, promise);
230
63
  }
231
64
 
232
65
  @ReactMethod
233
66
  public void releaseAllContexts(Promise promise) {
234
- new AsyncTask<Void, Void, Void>() {
235
- private Exception exception;
236
-
237
- @Override
238
- protected Void doInBackground(Void... voids) {
239
- try {
240
- onHostDestroy();
241
- } catch (Exception e) {
242
- exception = e;
243
- }
244
- return null;
245
- }
246
-
247
- @Override
248
- protected void onPostExecute(Void result) {
249
- if (exception != null) {
250
- promise.reject(exception);
251
- return;
252
- }
253
- promise.resolve(null);
254
- }
255
- }.execute();
256
- }
257
-
258
- @Override
259
- public void onHostResume() {
260
- }
261
-
262
- @Override
263
- public void onHostPause() {
264
- }
265
-
266
- @Override
267
- public void onHostDestroy() {
268
- WhisperContext.abortAllTranscribe();
269
- for (WhisperContext context : contexts.values()) {
270
- context.release();
271
- }
272
- contexts.clear();
273
- downloader.clearCache();
67
+ rnwhisper.releaseAllContexts(promise);
274
68
  }
275
69
  }
package/cpp/README.md ADDED
@@ -0,0 +1,4 @@
1
+ # Note
2
+
3
+ - Only `rn-whisper.h` / `rn-whisper.cpp` are the specific files for this project, others are sync from [whisper.cpp](https://github.com/ggerganov/whisper.cpp).
4
+ - We can update the native source by using the [bootstrap](../scripts/bootstrap.sh) script.
@@ -53,9 +53,11 @@ void whisper_coreml_encode(
53
53
  error: nil
54
54
  ];
55
55
 
56
- whisper_encoder_implOutput * outCoreML = [(__bridge id) ctx->data predictionFromLogmel_data:inMultiArray error:nil];
56
+ @autoreleasepool {
57
+ whisper_encoder_implOutput * outCoreML = [(__bridge id) ctx->data predictionFromLogmel_data:inMultiArray error:nil];
57
58
 
58
- memcpy(out, outCoreML.output.dataPointer, outCoreML.output.count * sizeof(float));
59
+ memcpy(out, outCoreML.output.dataPointer, outCoreML.output.count * sizeof(float));
60
+ }
59
61
  }
60
62
 
61
63
  #if __cplusplus
package/cpp/ggml.c CHANGED
@@ -292,7 +292,7 @@ typedef double wsp_ggml_float;
292
292
  #if defined(_MSC_VER) || defined(__MINGW32__)
293
293
  #include <intrin.h>
294
294
  #else
295
- #if defined(__AVX__) || defined(__AVX2__) || defined(__AVX512F__) || defined(__SSSE3__)
295
+ #if defined(__AVX__) || defined(__AVX2__) || defined(__AVX512F__) || defined(__SSSE3__) || defined(__SSE3__)
296
296
  #include <immintrin.h>
297
297
  #endif
298
298
  #endif
@@ -18721,6 +18721,14 @@ int wsp_ggml_cpu_has_sse3(void) {
18721
18721
  #endif
18722
18722
  }
18723
18723
 
18724
+ int wsp_ggml_cpu_has_ssse3(void) {
18725
+ #if defined(__SSSE3__)
18726
+ return 1;
18727
+ #else
18728
+ return 0;
18729
+ #endif
18730
+ }
18731
+
18724
18732
  int wsp_ggml_cpu_has_vsx(void) {
18725
18733
  #if defined(__POWER9_VECTOR__)
18726
18734
  return 1;
package/cpp/ggml.h CHANGED
@@ -1508,6 +1508,7 @@ extern "C" {
1508
1508
  WSP_GGML_API int wsp_ggml_cpu_has_clblast (void);
1509
1509
  WSP_GGML_API int wsp_ggml_cpu_has_gpublas (void);
1510
1510
  WSP_GGML_API int wsp_ggml_cpu_has_sse3 (void);
1511
+ WSP_GGML_API int wsp_ggml_cpu_has_ssse3 (void);
1511
1512
  WSP_GGML_API int wsp_ggml_cpu_has_vsx (void);
1512
1513
 
1513
1514
  //