whisper.rn 0.4.2 → 0.5.0-rc.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 (98) hide show
  1. package/README.md +1 -3
  2. package/android/build.gradle +70 -11
  3. package/android/src/main/CMakeLists.txt +28 -1
  4. package/android/src/main/java/com/rnwhisper/JSCallInvokerResolver.java +40 -0
  5. package/android/src/main/java/com/rnwhisper/RNWhisper.java +80 -27
  6. package/android/src/main/java/com/rnwhisper/WhisperContext.java +21 -9
  7. package/android/src/main/java/com/rnwhisper/WhisperVadContext.java +1 -1
  8. package/android/src/main/jni.cpp +79 -2
  9. package/android/src/main/jniLibs/arm64-v8a/librnwhisper.so +0 -0
  10. package/android/src/main/jniLibs/arm64-v8a/librnwhisper_v8fp16_va_2.so +0 -0
  11. package/android/src/main/jniLibs/armeabi-v7a/librnwhisper.so +0 -0
  12. package/android/src/main/jniLibs/armeabi-v7a/librnwhisper_vfpv4.so +0 -0
  13. package/android/src/main/jniLibs/x86_64/librnwhisper.so +0 -0
  14. package/android/src/main/jniLibs/x86_64/librnwhisper_x86_64.so +0 -0
  15. package/android/src/newarch/java/com/rnwhisper/RNWhisperModule.java +5 -0
  16. package/android/src/oldarch/java/com/rnwhisper/RNWhisperModule.java +5 -0
  17. package/cpp/ggml-backend.cpp +36 -18
  18. package/cpp/ggml-backend.h +1 -1
  19. package/cpp/ggml-cpu/amx/mmq.cpp +10 -9
  20. package/cpp/ggml-cpu/arch/arm/quants.c +109 -108
  21. package/cpp/ggml-cpu/arch/arm/repack.cpp +13 -12
  22. package/cpp/ggml-cpu/arch/x86/quants.c +83 -82
  23. package/cpp/ggml-cpu/arch/x86/repack.cpp +20 -19
  24. package/cpp/ggml-cpu/common.h +3 -2
  25. package/cpp/ggml-cpu/ggml-cpu-impl.h +9 -3
  26. package/cpp/ggml-cpu/ggml-cpu.c +95 -17
  27. package/cpp/ggml-cpu/ggml-cpu.cpp +4 -0
  28. package/cpp/ggml-cpu/ops.cpp +775 -74
  29. package/cpp/ggml-cpu/ops.h +7 -0
  30. package/cpp/ggml-cpu/quants.c +25 -24
  31. package/cpp/ggml-cpu/repack.cpp +15 -14
  32. package/cpp/ggml-cpu/simd-mappings.h +211 -33
  33. package/cpp/ggml-cpu/vec.cpp +26 -2
  34. package/cpp/ggml-cpu/vec.h +99 -45
  35. package/cpp/ggml-cpu.h +2 -0
  36. package/cpp/ggml-impl.h +125 -183
  37. package/cpp/ggml-metal-impl.h +27 -0
  38. package/cpp/ggml-metal.m +298 -41
  39. package/cpp/ggml-quants.c +6 -6
  40. package/cpp/ggml-whisper-sim.metallib +0 -0
  41. package/cpp/ggml-whisper.metallib +0 -0
  42. package/cpp/ggml.c +269 -40
  43. package/cpp/ggml.h +122 -2
  44. package/cpp/gguf.cpp +5 -1
  45. package/cpp/jsi/RNWhisperJSI.cpp +681 -0
  46. package/cpp/jsi/RNWhisperJSI.h +44 -0
  47. package/cpp/jsi/ThreadPool.h +100 -0
  48. package/cpp/whisper.cpp +4 -0
  49. package/cpp/whisper.h +2 -0
  50. package/ios/RNWhisper.h +3 -0
  51. package/ios/RNWhisper.mm +66 -31
  52. package/ios/rnwhisper.xcframework/ios-arm64/rnwhisper.framework/Headers/ggml-backend.h +1 -1
  53. package/ios/rnwhisper.xcframework/ios-arm64/rnwhisper.framework/Headers/ggml-cpu.h +2 -0
  54. package/ios/rnwhisper.xcframework/ios-arm64/rnwhisper.framework/Headers/ggml-impl.h +125 -183
  55. package/ios/rnwhisper.xcframework/ios-arm64/rnwhisper.framework/Headers/ggml-metal-impl.h +27 -0
  56. package/ios/rnwhisper.xcframework/ios-arm64/rnwhisper.framework/Headers/ggml.h +122 -2
  57. package/ios/rnwhisper.xcframework/ios-arm64/rnwhisper.framework/Headers/whisper.h +2 -0
  58. package/ios/rnwhisper.xcframework/ios-arm64/rnwhisper.framework/ggml-whisper.metallib +0 -0
  59. package/ios/rnwhisper.xcframework/ios-arm64/rnwhisper.framework/rnwhisper +0 -0
  60. package/ios/rnwhisper.xcframework/ios-arm64_x86_64-simulator/rnwhisper.framework/Headers/ggml-backend.h +1 -1
  61. package/ios/rnwhisper.xcframework/ios-arm64_x86_64-simulator/rnwhisper.framework/Headers/ggml-cpu.h +2 -0
  62. package/ios/rnwhisper.xcframework/ios-arm64_x86_64-simulator/rnwhisper.framework/Headers/ggml-impl.h +125 -183
  63. package/ios/rnwhisper.xcframework/ios-arm64_x86_64-simulator/rnwhisper.framework/Headers/ggml-metal-impl.h +27 -0
  64. package/ios/rnwhisper.xcframework/ios-arm64_x86_64-simulator/rnwhisper.framework/Headers/ggml.h +122 -2
  65. package/ios/rnwhisper.xcframework/ios-arm64_x86_64-simulator/rnwhisper.framework/Headers/whisper.h +2 -0
  66. package/ios/rnwhisper.xcframework/ios-arm64_x86_64-simulator/rnwhisper.framework/ggml-whisper-sim.metallib +0 -0
  67. package/ios/rnwhisper.xcframework/ios-arm64_x86_64-simulator/rnwhisper.framework/rnwhisper +0 -0
  68. package/ios/rnwhisper.xcframework/tvos-arm64/rnwhisper.framework/Headers/ggml-backend.h +1 -1
  69. package/ios/rnwhisper.xcframework/tvos-arm64/rnwhisper.framework/Headers/ggml-cpu.h +2 -0
  70. package/ios/rnwhisper.xcframework/tvos-arm64/rnwhisper.framework/Headers/ggml-impl.h +125 -183
  71. package/ios/rnwhisper.xcframework/tvos-arm64/rnwhisper.framework/Headers/ggml-metal-impl.h +27 -0
  72. package/ios/rnwhisper.xcframework/tvos-arm64/rnwhisper.framework/Headers/ggml.h +122 -2
  73. package/ios/rnwhisper.xcframework/tvos-arm64/rnwhisper.framework/Headers/whisper.h +2 -0
  74. package/ios/rnwhisper.xcframework/tvos-arm64/rnwhisper.framework/ggml-whisper.metallib +0 -0
  75. package/ios/rnwhisper.xcframework/tvos-arm64/rnwhisper.framework/rnwhisper +0 -0
  76. package/ios/rnwhisper.xcframework/tvos-arm64_x86_64-simulator/rnwhisper.framework/Headers/ggml-backend.h +1 -1
  77. package/ios/rnwhisper.xcframework/tvos-arm64_x86_64-simulator/rnwhisper.framework/Headers/ggml-cpu.h +2 -0
  78. package/ios/rnwhisper.xcframework/tvos-arm64_x86_64-simulator/rnwhisper.framework/Headers/ggml-impl.h +125 -183
  79. package/ios/rnwhisper.xcframework/tvos-arm64_x86_64-simulator/rnwhisper.framework/Headers/ggml-metal-impl.h +27 -0
  80. package/ios/rnwhisper.xcframework/tvos-arm64_x86_64-simulator/rnwhisper.framework/Headers/ggml.h +122 -2
  81. package/ios/rnwhisper.xcframework/tvos-arm64_x86_64-simulator/rnwhisper.framework/Headers/whisper.h +2 -0
  82. package/ios/rnwhisper.xcframework/tvos-arm64_x86_64-simulator/rnwhisper.framework/ggml-whisper-sim.metallib +0 -0
  83. package/ios/rnwhisper.xcframework/tvos-arm64_x86_64-simulator/rnwhisper.framework/rnwhisper +0 -0
  84. package/jest/mock.js +1 -0
  85. package/lib/commonjs/NativeRNWhisper.js.map +1 -1
  86. package/lib/commonjs/index.js +83 -2
  87. package/lib/commonjs/index.js.map +1 -1
  88. package/lib/module/NativeRNWhisper.js.map +1 -1
  89. package/lib/module/index.js +83 -2
  90. package/lib/module/index.js.map +1 -1
  91. package/lib/typescript/NativeRNWhisper.d.ts +4 -0
  92. package/lib/typescript/NativeRNWhisper.d.ts.map +1 -1
  93. package/lib/typescript/index.d.ts +18 -6
  94. package/lib/typescript/index.d.ts.map +1 -1
  95. package/package.json +2 -3
  96. package/src/NativeRNWhisper.ts +2 -0
  97. package/src/index.ts +162 -33
  98. package/whisper-rn.podspec +6 -3
@@ -0,0 +1,44 @@
1
+ #pragma once
2
+
3
+ #include <jsi/jsi.h>
4
+ #include <memory>
5
+ #include <mutex>
6
+ #include <unordered_map>
7
+ #include <vector>
8
+ #include <atomic>
9
+ #include <ReactCommon/CallInvoker.h>
10
+
11
+ #if defined(__ANDROID__)
12
+ #include <android/log.h>
13
+ #include "whisper.h"
14
+ #include "rn-whisper.h"
15
+ #endif
16
+
17
+ #if defined(__APPLE__)
18
+ #if RNWHISPER_BUILD_FROM_SOURCE
19
+ #include "whisper.h"
20
+ #include "rn-whisper.h"
21
+ #else
22
+ #include <rnwhisper/whisper.h>
23
+ #include <rnwhisper/rn-whisper.h>
24
+ #endif
25
+ #endif
26
+
27
+ namespace rnwhisper_jsi {
28
+
29
+ // Context management functions
30
+ void addContext(int contextId, long contextPtr);
31
+ void removeContext(int contextId);
32
+ void addVadContext(int contextId, long vadContextPtr);
33
+ void removeVadContext(int contextId);
34
+
35
+ // Main JSI installation function
36
+ void installJSIBindings(
37
+ facebook::jsi::Runtime& runtime,
38
+ std::shared_ptr<facebook::react::CallInvoker> callInvoker
39
+ );
40
+
41
+ // Cleanup function to dispose of ThreadPool
42
+ void cleanupJSIBindings();
43
+
44
+ } // namespace rnwhisper_jsi
@@ -0,0 +1,100 @@
1
+ // From https://github.com/progschj/ThreadPool
2
+
3
+ #ifndef THREAD_POOL_H
4
+ #define THREAD_POOL_H
5
+
6
+ #include <vector>
7
+ #include <queue>
8
+ #include <memory>
9
+ #include <thread>
10
+ #include <mutex>
11
+ #include <condition_variable>
12
+ #include <future>
13
+ #include <functional>
14
+ #include <stdexcept>
15
+
16
+ class ThreadPool {
17
+ public:
18
+ ThreadPool(size_t);
19
+ template<class F, class... Args>
20
+ auto enqueue(F&& f, Args&&... args)
21
+ -> std::future<typename std::result_of<F(Args...)>::type>;
22
+ ~ThreadPool();
23
+ private:
24
+ // need to keep track of threads so we can join them
25
+ std::vector< std::thread > workers;
26
+ // the task queue
27
+ std::queue< std::function<void()> > tasks;
28
+
29
+ // synchronization
30
+ std::mutex queue_mutex;
31
+ std::condition_variable condition;
32
+ bool stop;
33
+ };
34
+
35
+ // the constructor just launches some amount of workers
36
+ inline ThreadPool::ThreadPool(size_t threads)
37
+ : stop(false)
38
+ {
39
+ for(size_t i = 0;i<threads;++i)
40
+ workers.emplace_back(
41
+ [this]
42
+ {
43
+ for(;;)
44
+ {
45
+ std::function<void()> task;
46
+
47
+ {
48
+ std::unique_lock<std::mutex> lock(this->queue_mutex);
49
+ this->condition.wait(lock,
50
+ [this]{ return this->stop || !this->tasks.empty(); });
51
+ if(this->stop && this->tasks.empty())
52
+ return;
53
+ task = std::move(this->tasks.front());
54
+ this->tasks.pop();
55
+ }
56
+
57
+ task();
58
+ }
59
+ }
60
+ );
61
+ }
62
+
63
+ // add new work item to the pool
64
+ template<class F, class... Args>
65
+ auto ThreadPool::enqueue(F&& f, Args&&... args)
66
+ -> std::future<typename std::result_of<F(Args...)>::type>
67
+ {
68
+ using return_type = typename std::result_of<F(Args...)>::type;
69
+
70
+ auto task = std::make_shared< std::packaged_task<return_type()> >(
71
+ std::bind(std::forward<F>(f), std::forward<Args>(args)...)
72
+ );
73
+
74
+ std::future<return_type> res = task->get_future();
75
+ {
76
+ std::unique_lock<std::mutex> lock(queue_mutex);
77
+
78
+ // don't allow enqueueing after stopping the pool
79
+ if(stop)
80
+ throw std::runtime_error("enqueue on stopped ThreadPool");
81
+
82
+ tasks.emplace([task](){ (*task)(); });
83
+ }
84
+ condition.notify_one();
85
+ return res;
86
+ }
87
+
88
+ // the destructor joins all threads
89
+ inline ThreadPool::~ThreadPool()
90
+ {
91
+ {
92
+ std::unique_lock<std::mutex> lock(queue_mutex);
93
+ stop = true;
94
+ }
95
+ condition.notify_all();
96
+ for(std::thread &worker: workers)
97
+ worker.join();
98
+ }
99
+
100
+ #endif
package/cpp/whisper.cpp CHANGED
@@ -8942,6 +8942,10 @@ void whisper_log_set(wsp_ggml_log_callback log_callback, void * user_data) {
8942
8942
  wsp_ggml_log_set(g_state.log_callback, g_state.log_callback_user_data);
8943
8943
  }
8944
8944
 
8945
+ const char * whisper_version(void) {
8946
+ return "1.7.6";
8947
+ }
8948
+
8945
8949
  WSP_GGML_ATTRIBUTE_FORMAT(2, 3)
8946
8950
  static void whisper_log_internal(wsp_ggml_log_level level, const char * format, ...) {
8947
8951
  va_list args;
package/cpp/whisper.h CHANGED
@@ -199,6 +199,8 @@ extern "C" {
199
199
  float samples_overlap; // Overlap in seconds when copying audio samples from speech segment.
200
200
  } whisper_vad_params;
201
201
 
202
+ WHISPER_API const char * whisper_version(void);
203
+
202
204
  // Various functions for loading a ggml whisper model.
203
205
  // Allocate (almost) all memory needed for the model.
204
206
  // Return NULL on failure
package/ios/RNWhisper.h CHANGED
@@ -8,8 +8,11 @@
8
8
  #endif
9
9
  #endif
10
10
 
11
+ #import <Foundation/Foundation.h>
11
12
  #import <React/RCTBridgeModule.h>
13
+ #import <React/RCTBridge+Private.h>
12
14
  #import <React/RCTEventEmitter.h>
15
+ #import <ReactCommon/RCTTurboModule.h>
13
16
 
14
17
  @interface RNWhisper : RCTEventEmitter <RCTBridgeModule>
15
18
 
package/ios/RNWhisper.mm CHANGED
@@ -4,6 +4,7 @@
4
4
  #import "RNWhisperDownloader.h"
5
5
  #import "RNWhisperAudioUtils.h"
6
6
  #import "RNWhisperAudioSessionUtils.h"
7
+ #import "RNWhisperJSI.h"
7
8
  #include <stdlib.h>
8
9
  #include <string>
9
10
 
@@ -90,6 +91,8 @@ RCT_REMAP_METHOD(initContext,
90
91
  }
91
92
 
92
93
  [contexts setObject:context forKey:[NSNumber numberWithInt:contextId]];
94
+ // Also add to unified context management - store raw context pointer like Android
95
+ rnwhisper_jsi::addContext(contextId, reinterpret_cast<long>([context getContext]));
93
96
 
94
97
  resolve(@{
95
98
  @"contextId": @(contextId),
@@ -345,6 +348,8 @@ RCT_REMAP_METHOD(releaseContext,
345
348
  }
346
349
  [context invalidate];
347
350
  [contexts removeObjectForKey:[NSNumber numberWithInt:contextId]];
351
+ // Also remove from unified context management
352
+ rnwhisper_jsi::removeContext(contextId);
348
353
  resolve(nil);
349
354
  }
350
355
 
@@ -352,39 +357,10 @@ RCT_REMAP_METHOD(releaseAllContexts,
352
357
  withResolver:(RCTPromiseResolveBlock)resolve
353
358
  withRejecter:(RCTPromiseRejectBlock)reject)
354
359
  {
355
- [self invalidate];
360
+ [self releaseAllContexts];
356
361
  resolve(nil);
357
362
  }
358
363
 
359
- - (void)invalidate {
360
- [super invalidate];
361
-
362
- if (contexts == nil) {
363
- return;
364
- }
365
-
366
- for (NSNumber *contextId in contexts) {
367
- RNWhisperContext *context = contexts[contextId];
368
- [context invalidate];
369
- }
370
-
371
- if (vadContexts != nil) {
372
- for (NSNumber *contextId in vadContexts) {
373
- RNWhisperVadContext *vadContext = vadContexts[contextId];
374
- [vadContext invalidate];
375
- }
376
- [vadContexts removeAllObjects];
377
- vadContexts = nil;
378
- }
379
-
380
- rnwhisper::job_abort_all(); // graceful abort
381
-
382
- [contexts removeAllObjects];
383
- contexts = nil;
384
-
385
- [RNWhisperDownloader clearCache];
386
- }
387
-
388
364
  // MARK: - AudioSessionUtils
389
365
 
390
366
  RCT_EXPORT_METHOD(getAudioSessionCurrentCategory:(RCTPromiseResolveBlock)resolve
@@ -484,6 +460,8 @@ RCT_REMAP_METHOD(initVadContext,
484
460
  }
485
461
 
486
462
  [vadContexts setObject:vadContext forKey:[NSNumber numberWithInt:contextId]];
463
+ // Also add to unified context management - store raw VAD context pointer like Android
464
+ rnwhisper_jsi::addVadContext(contextId, reinterpret_cast<long>([vadContext getVadContext]));
487
465
 
488
466
  resolve(@{
489
467
  @"contextId": @(contextId),
@@ -568,20 +546,77 @@ RCT_REMAP_METHOD(releaseVadContext,
568
546
  }
569
547
  [vadContext invalidate];
570
548
  [vadContexts removeObjectForKey:[NSNumber numberWithInt:contextId]];
549
+ // Also remove from unified context management
550
+ rnwhisper_jsi::removeVadContext(contextId);
571
551
  resolve(nil);
572
552
  }
573
553
 
574
554
  RCT_EXPORT_METHOD(releaseAllVadContexts:(RCTPromiseResolveBlock)resolve
575
555
  withRejecter:(RCTPromiseRejectBlock)reject)
576
556
  {
557
+ [self releaseAllVadContexts];
558
+ resolve(nil);
559
+ }
560
+
561
+ - (void)releaseAllContexts {
562
+ rnwhisper::job_abort_all(); // graceful abort
563
+ if (contexts != nil) {
564
+ for (NSNumber *contextId in contexts) {
565
+ RNWhisperContext *context = contexts[contextId];
566
+ [context invalidate];
567
+ }
568
+ [contexts removeAllObjects];
569
+ contexts = nil;
570
+ }
571
+ }
572
+
573
+ - (void)releaseAllVadContexts {
577
574
  if (vadContexts != nil) {
578
575
  for (NSNumber *contextId in vadContexts) {
579
576
  RNWhisperVadContext *vadContext = vadContexts[contextId];
580
577
  [vadContext invalidate];
581
578
  }
582
579
  [vadContexts removeAllObjects];
580
+ vadContexts = nil;
583
581
  }
584
- resolve(nil);
582
+ }
583
+
584
+ RCT_EXPORT_METHOD(installJSIBindings:(RCTPromiseResolveBlock)resolve
585
+ withRejecter:(RCTPromiseRejectBlock)reject)
586
+ {
587
+ RCTBridge *bridge = [RCTBridge currentBridge];
588
+ if (bridge == nil) {
589
+ reject(@"whisper_jsi_error", @"Bridge not available", nil);
590
+ return;
591
+ }
592
+
593
+ RCTCxxBridge *cxxBridge = (RCTCxxBridge *)bridge;
594
+ auto callInvoker = bridge.jsCallInvoker;
595
+ if (cxxBridge.runtime) {
596
+ facebook::jsi::Runtime *runtime = static_cast<facebook::jsi::Runtime *>(cxxBridge.runtime);
597
+
598
+ if (callInvoker) {
599
+ callInvoker->invokeAsync([runtime, callInvoker]() {
600
+ rnwhisper_jsi::installJSIBindings(*runtime, callInvoker);
601
+ });
602
+ } else {
603
+ reject(@"whisper_jsi_error", @"CallInvoker not available", nil);
604
+ return;
605
+ }
606
+
607
+ resolve(@{});
608
+ } else {
609
+ reject(@"whisper_jsi_error", @"Runtime not available", nil);
610
+ }
611
+ }
612
+
613
+ - (void)invalidate {
614
+ [super invalidate];
615
+
616
+ [self releaseAllContexts];
617
+ [self releaseAllVadContexts];
618
+
619
+ [RNWhisperDownloader clearCache];
585
620
  }
586
621
 
587
622
  #ifdef RCT_NEW_ARCH_ENABLED
@@ -339,7 +339,7 @@ extern "C" {
339
339
  typedef bool (*wsp_ggml_backend_eval_callback)(int node_index, struct wsp_ggml_tensor * t1, struct wsp_ggml_tensor * t2, void * user_data);
340
340
 
341
341
  // Compare the output of two backends
342
- WSP_GGML_API bool wsp_ggml_backend_compare_graph_backend(wsp_ggml_backend_t backend1, wsp_ggml_backend_t backend2, struct wsp_ggml_cgraph * graph, wsp_ggml_backend_eval_callback callback, void * user_data);
342
+ WSP_GGML_API bool wsp_ggml_backend_compare_graph_backend(wsp_ggml_backend_t backend1, wsp_ggml_backend_t backend2, struct wsp_ggml_cgraph * graph, wsp_ggml_backend_eval_callback callback, void * user_data, struct wsp_ggml_tensor * test_node);
343
343
 
344
344
  // Tensor initialization
345
345
  WSP_GGML_API enum wsp_ggml_status wsp_ggml_backend_tensor_alloc(wsp_ggml_backend_buffer_t buffer, struct wsp_ggml_tensor * tensor, void * addr);
@@ -101,6 +101,7 @@ extern "C" {
101
101
  WSP_GGML_BACKEND_API int wsp_ggml_cpu_has_riscv_v (void);
102
102
  WSP_GGML_BACKEND_API int wsp_ggml_cpu_has_vsx (void);
103
103
  WSP_GGML_BACKEND_API int wsp_ggml_cpu_has_vxe (void);
104
+ WSP_GGML_BACKEND_API int wsp_ggml_cpu_has_nnpa (void);
104
105
  WSP_GGML_BACKEND_API int wsp_ggml_cpu_has_wasm_simd (void);
105
106
  WSP_GGML_BACKEND_API int wsp_ggml_cpu_has_llamafile (void);
106
107
 
@@ -133,6 +134,7 @@ extern "C" {
133
134
 
134
135
  WSP_GGML_BACKEND_API wsp_ggml_backend_reg_t wsp_ggml_backend_cpu_reg(void);
135
136
 
137
+ WSP_GGML_BACKEND_API void wsp_ggml_cpu_fp32_to_fp32(const float *, float *, int64_t);
136
138
  WSP_GGML_BACKEND_API void wsp_ggml_cpu_fp32_to_fp16(const float *, wsp_ggml_fp16_t *, int64_t);
137
139
  WSP_GGML_BACKEND_API void wsp_ggml_cpu_fp16_to_fp32(const wsp_ggml_fp16_t *, float *, int64_t);
138
140
  WSP_GGML_BACKEND_API void wsp_ggml_cpu_fp32_to_bf16(const float *, wsp_ggml_bf16_t *, int64_t);