react-native-tuner-engine 1.0.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 (224) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +188 -0
  3. package/TunerEngine.podspec +32 -0
  4. package/android/build.gradle +86 -0
  5. package/android/src/main/AndroidManifest.xml +3 -0
  6. package/android/src/main/cpp/CMakeLists.txt +31 -0
  7. package/android/src/main/cpp/OboeAudioSource.cpp +101 -0
  8. package/android/src/main/cpp/OboeAudioSource.h +41 -0
  9. package/android/src/main/cpp/TunerEngineJni.cpp +220 -0
  10. package/android/src/main/java/com/tunerengine/TunerEngineModule.kt +183 -0
  11. package/android/src/main/java/com/tunerengine/TunerEnginePackage.kt +31 -0
  12. package/cpp/CMakeLists.txt +25 -0
  13. package/cpp/build/CMakeCache.txt +347 -0
  14. package/cpp/build/CMakeFiles/4.3.2/CMakeCXXCompiler.cmake +102 -0
  15. package/cpp/build/CMakeFiles/4.3.2/CMakeDetermineCompilerABI_CXX.bin +0 -0
  16. package/cpp/build/CMakeFiles/4.3.2/CMakeSystem.cmake +15 -0
  17. package/cpp/build/CMakeFiles/4.3.2/CompilerIdCXX/CMakeCXXCompilerId.cpp +949 -0
  18. package/cpp/build/CMakeFiles/4.3.2/CompilerIdCXX/a.out +0 -0
  19. package/cpp/build/CMakeFiles/4.3.2/CompilerIdCXX/apple-sdk.cpp +1 -0
  20. package/cpp/build/CMakeFiles/CMakeConfigureLog.yaml +1619 -0
  21. package/cpp/build/CMakeFiles/CMakeDirectoryInformation.cmake +16 -0
  22. package/cpp/build/CMakeFiles/InstallScripts.json +7 -0
  23. package/cpp/build/CMakeFiles/Makefile.cmake +118 -0
  24. package/cpp/build/CMakeFiles/Makefile2 +122 -0
  25. package/cpp/build/CMakeFiles/TargetDirectories.txt +3 -0
  26. package/cpp/build/CMakeFiles/cmake.check_cache +1 -0
  27. package/cpp/build/CMakeFiles/progress.marks +1 -0
  28. package/cpp/build/CMakeFiles/tuner_engine_core.dir/DependInfo.cmake +36 -0
  29. package/cpp/build/CMakeFiles/tuner_engine_core.dir/build.make +322 -0
  30. package/cpp/build/CMakeFiles/tuner_engine_core.dir/cmake_clean.cmake +37 -0
  31. package/cpp/build/CMakeFiles/tuner_engine_core.dir/cmake_clean_target.cmake +3 -0
  32. package/cpp/build/CMakeFiles/tuner_engine_core.dir/compiler_depend.make +2 -0
  33. package/cpp/build/CMakeFiles/tuner_engine_core.dir/compiler_depend.ts +2 -0
  34. package/cpp/build/CMakeFiles/tuner_engine_core.dir/depend.make +2 -0
  35. package/cpp/build/CMakeFiles/tuner_engine_core.dir/flags.make +12 -0
  36. package/cpp/build/CMakeFiles/tuner_engine_core.dir/link.txt +2 -0
  37. package/cpp/build/CMakeFiles/tuner_engine_core.dir/progress.make +16 -0
  38. package/cpp/build/CMakeFiles/tuner_engine_core.dir/src/AudioFrameDispatcher.cpp.o +0 -0
  39. package/cpp/build/CMakeFiles/tuner_engine_core.dir/src/AudioFrameDispatcher.cpp.o.d +814 -0
  40. package/cpp/build/CMakeFiles/tuner_engine_core.dir/src/BiquadHpf.cpp.o +0 -0
  41. package/cpp/build/CMakeFiles/tuner_engine_core.dir/src/BiquadHpf.cpp.o.d +206 -0
  42. package/cpp/build/CMakeFiles/tuner_engine_core.dir/src/CepstrumPitchDetector.cpp.o +0 -0
  43. package/cpp/build/CMakeFiles/tuner_engine_core.dir/src/CepstrumPitchDetector.cpp.o.d +797 -0
  44. package/cpp/build/CMakeFiles/tuner_engine_core.dir/src/EnsembleSelector.cpp.o +0 -0
  45. package/cpp/build/CMakeFiles/tuner_engine_core.dir/src/EnsembleSelector.cpp.o.d +755 -0
  46. package/cpp/build/CMakeFiles/tuner_engine_core.dir/src/NoteMapper.cpp.o +0 -0
  47. package/cpp/build/CMakeFiles/tuner_engine_core.dir/src/NoteMapper.cpp.o.d +669 -0
  48. package/cpp/build/CMakeFiles/tuner_engine_core.dir/src/OnsetDetector.cpp.o +0 -0
  49. package/cpp/build/CMakeFiles/tuner_engine_core.dir/src/OnsetDetector.cpp.o.d +648 -0
  50. package/cpp/build/CMakeFiles/tuner_engine_core.dir/src/Pipeline.cpp.o +0 -0
  51. package/cpp/build/CMakeFiles/tuner_engine_core.dir/src/Pipeline.cpp.o.d +765 -0
  52. package/cpp/build/CMakeFiles/tuner_engine_core.dir/src/PostProcessor.cpp.o +0 -0
  53. package/cpp/build/CMakeFiles/tuner_engine_core.dir/src/PostProcessor.cpp.o.d +648 -0
  54. package/cpp/build/CMakeFiles/tuner_engine_core.dir/src/PyinPitchDetector.cpp.o +0 -0
  55. package/cpp/build/CMakeFiles/tuner_engine_core.dir/src/PyinPitchDetector.cpp.o.d +755 -0
  56. package/cpp/build/CMakeFiles/tuner_engine_core.dir/src/SnrEstimator.cpp.o +0 -0
  57. package/cpp/build/CMakeFiles/tuner_engine_core.dir/src/SnrEstimator.cpp.o.d +648 -0
  58. package/cpp/build/CMakeFiles/tuner_engine_core.dir/src/StringMatcher.cpp.o +0 -0
  59. package/cpp/build/CMakeFiles/tuner_engine_core.dir/src/StringMatcher.cpp.o.d +665 -0
  60. package/cpp/build/CMakeFiles/tuner_engine_core.dir/src/TunerEngine.cpp.o +0 -0
  61. package/cpp/build/CMakeFiles/tuner_engine_core.dir/src/TunerEngine.cpp.o.d +811 -0
  62. package/cpp/build/CMakeFiles/tuner_engine_core.dir/src/Window.cpp.o +0 -0
  63. package/cpp/build/CMakeFiles/tuner_engine_core.dir/src/Window.cpp.o.d +754 -0
  64. package/cpp/build/CMakeFiles/tuner_engine_core.dir/src/YinPitchDetector.cpp.o +0 -0
  65. package/cpp/build/CMakeFiles/tuner_engine_core.dir/src/YinPitchDetector.cpp.o.d +755 -0
  66. package/cpp/build/Makefile +532 -0
  67. package/cpp/build/cmake_install.cmake +61 -0
  68. package/cpp/build/libtuner_engine_core.a +0 -0
  69. package/cpp/include/AudioFrameDispatcher.hpp +87 -0
  70. package/cpp/include/BiquadHpf.hpp +22 -0
  71. package/cpp/include/CepstrumPitchDetector.hpp +33 -0
  72. package/cpp/include/EnsembleSelector.hpp +25 -0
  73. package/cpp/include/Fft.hpp +44 -0
  74. package/cpp/include/IPitchDetector.hpp +21 -0
  75. package/cpp/include/InstrumentPresets.hpp +33 -0
  76. package/cpp/include/NoteMapper.hpp +15 -0
  77. package/cpp/include/OnsetDetector.hpp +37 -0
  78. package/cpp/include/Pipeline.hpp +55 -0
  79. package/cpp/include/PitchResult.hpp +24 -0
  80. package/cpp/include/PostProcessor.hpp +51 -0
  81. package/cpp/include/PyinPitchDetector.hpp +35 -0
  82. package/cpp/include/RingBuffer.hpp +72 -0
  83. package/cpp/include/SnrEstimator.hpp +21 -0
  84. package/cpp/include/StringMatcher.hpp +27 -0
  85. package/cpp/include/TunerEngine.hpp +32 -0
  86. package/cpp/include/TuningPresets.hpp +103 -0
  87. package/cpp/include/Window.hpp +13 -0
  88. package/cpp/include/YinPitchDetector.hpp +37 -0
  89. package/cpp/src/AudioFrameDispatcher.cpp +180 -0
  90. package/cpp/src/BiquadHpf.cpp +35 -0
  91. package/cpp/src/CepstrumPitchDetector.cpp +116 -0
  92. package/cpp/src/EnsembleSelector.cpp +91 -0
  93. package/cpp/src/NoteMapper.cpp +47 -0
  94. package/cpp/src/OnsetDetector.cpp +39 -0
  95. package/cpp/src/Pipeline.cpp +133 -0
  96. package/cpp/src/PostProcessor.cpp +111 -0
  97. package/cpp/src/PyinPitchDetector.cpp +134 -0
  98. package/cpp/src/SnrEstimator.cpp +33 -0
  99. package/cpp/src/StringMatcher.cpp +37 -0
  100. package/cpp/src/TunerEngine.cpp +67 -0
  101. package/cpp/src/Window.cpp +21 -0
  102. package/cpp/src/YinPitchDetector.cpp +118 -0
  103. package/cpp/tests/CMakeLists.txt +23 -0
  104. package/cpp/tests/bench.cpp +160 -0
  105. package/cpp/tests/build/CMakeCache.txt +356 -0
  106. package/cpp/tests/build/CMakeFiles/4.3.2/CMakeCXXCompiler.cmake +102 -0
  107. package/cpp/tests/build/CMakeFiles/4.3.2/CMakeDetermineCompilerABI_CXX.bin +0 -0
  108. package/cpp/tests/build/CMakeFiles/4.3.2/CMakeSystem.cmake +15 -0
  109. package/cpp/tests/build/CMakeFiles/4.3.2/CompilerIdCXX/CMakeCXXCompilerId.cpp +949 -0
  110. package/cpp/tests/build/CMakeFiles/4.3.2/CompilerIdCXX/a.out +0 -0
  111. package/cpp/tests/build/CMakeFiles/4.3.2/CompilerIdCXX/apple-sdk.cpp +1 -0
  112. package/cpp/tests/build/CMakeFiles/CMakeConfigureLog.yaml +1619 -0
  113. package/cpp/tests/build/CMakeFiles/CMakeDirectoryInformation.cmake +16 -0
  114. package/cpp/tests/build/CMakeFiles/InstallScripts.json +8 -0
  115. package/cpp/tests/build/CMakeFiles/Makefile.cmake +122 -0
  116. package/cpp/tests/build/CMakeFiles/Makefile2 +211 -0
  117. package/cpp/tests/build/CMakeFiles/TargetDirectories.txt +9 -0
  118. package/cpp/tests/build/CMakeFiles/cmake.check_cache +1 -0
  119. package/cpp/tests/build/CMakeFiles/progress.marks +1 -0
  120. package/cpp/tests/build/CMakeFiles/tuner_engine_bench.dir/DependInfo.cmake +23 -0
  121. package/cpp/tests/build/CMakeFiles/tuner_engine_bench.dir/bench.cpp.o +0 -0
  122. package/cpp/tests/build/CMakeFiles/tuner_engine_bench.dir/bench.cpp.o.d +813 -0
  123. package/cpp/tests/build/CMakeFiles/tuner_engine_bench.dir/build.make +114 -0
  124. package/cpp/tests/build/CMakeFiles/tuner_engine_bench.dir/cmake_clean.cmake +11 -0
  125. package/cpp/tests/build/CMakeFiles/tuner_engine_bench.dir/compiler_depend.make +2 -0
  126. package/cpp/tests/build/CMakeFiles/tuner_engine_bench.dir/compiler_depend.ts +2 -0
  127. package/cpp/tests/build/CMakeFiles/tuner_engine_bench.dir/depend.make +2 -0
  128. package/cpp/tests/build/CMakeFiles/tuner_engine_bench.dir/flags.make +12 -0
  129. package/cpp/tests/build/CMakeFiles/tuner_engine_bench.dir/link.txt +1 -0
  130. package/cpp/tests/build/CMakeFiles/tuner_engine_bench.dir/progress.make +3 -0
  131. package/cpp/tests/build/CMakeFiles/tuner_engine_tests.dir/DependInfo.cmake +23 -0
  132. package/cpp/tests/build/CMakeFiles/tuner_engine_tests.dir/build.make +114 -0
  133. package/cpp/tests/build/CMakeFiles/tuner_engine_tests.dir/cmake_clean.cmake +11 -0
  134. package/cpp/tests/build/CMakeFiles/tuner_engine_tests.dir/compiler_depend.make +2 -0
  135. package/cpp/tests/build/CMakeFiles/tuner_engine_tests.dir/compiler_depend.ts +2 -0
  136. package/cpp/tests/build/CMakeFiles/tuner_engine_tests.dir/depend.make +2 -0
  137. package/cpp/tests/build/CMakeFiles/tuner_engine_tests.dir/flags.make +12 -0
  138. package/cpp/tests/build/CMakeFiles/tuner_engine_tests.dir/link.txt +1 -0
  139. package/cpp/tests/build/CMakeFiles/tuner_engine_tests.dir/main.cpp.o +0 -0
  140. package/cpp/tests/build/CMakeFiles/tuner_engine_tests.dir/main.cpp.o.d +823 -0
  141. package/cpp/tests/build/CMakeFiles/tuner_engine_tests.dir/progress.make +3 -0
  142. package/cpp/tests/build/CTestTestfile.cmake +9 -0
  143. package/cpp/tests/build/Makefile +247 -0
  144. package/cpp/tests/build/cmake_install.cmake +66 -0
  145. package/cpp/tests/build/tuner_engine_bench +0 -0
  146. package/cpp/tests/build/tuner_engine_core/CMakeFiles/CMakeDirectoryInformation.cmake +16 -0
  147. package/cpp/tests/build/tuner_engine_core/CMakeFiles/progress.marks +1 -0
  148. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/DependInfo.cmake +36 -0
  149. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/build.make +322 -0
  150. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/cmake_clean.cmake +37 -0
  151. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/cmake_clean_target.cmake +3 -0
  152. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/compiler_depend.make +2 -0
  153. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/compiler_depend.ts +2 -0
  154. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/depend.make +2 -0
  155. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/flags.make +12 -0
  156. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/link.txt +2 -0
  157. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/progress.make +16 -0
  158. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/src/AudioFrameDispatcher.cpp.o +0 -0
  159. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/src/AudioFrameDispatcher.cpp.o.d +814 -0
  160. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/src/BiquadHpf.cpp.o +0 -0
  161. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/src/BiquadHpf.cpp.o.d +206 -0
  162. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/src/CepstrumPitchDetector.cpp.o +0 -0
  163. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/src/CepstrumPitchDetector.cpp.o.d +797 -0
  164. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/src/EnsembleSelector.cpp.o +0 -0
  165. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/src/EnsembleSelector.cpp.o.d +755 -0
  166. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/src/NoteMapper.cpp.o +0 -0
  167. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/src/NoteMapper.cpp.o.d +669 -0
  168. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/src/OnsetDetector.cpp.o +0 -0
  169. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/src/OnsetDetector.cpp.o.d +648 -0
  170. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/src/Pipeline.cpp.o +0 -0
  171. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/src/Pipeline.cpp.o.d +765 -0
  172. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/src/PostProcessor.cpp.o +0 -0
  173. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/src/PostProcessor.cpp.o.d +648 -0
  174. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/src/PyinPitchDetector.cpp.o +0 -0
  175. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/src/PyinPitchDetector.cpp.o.d +755 -0
  176. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/src/SnrEstimator.cpp.o +0 -0
  177. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/src/SnrEstimator.cpp.o.d +648 -0
  178. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/src/StringMatcher.cpp.o +0 -0
  179. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/src/StringMatcher.cpp.o.d +665 -0
  180. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/src/TunerEngine.cpp.o +0 -0
  181. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/src/TunerEngine.cpp.o.d +811 -0
  182. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/src/Window.cpp.o +0 -0
  183. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/src/Window.cpp.o.d +754 -0
  184. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/src/YinPitchDetector.cpp.o +0 -0
  185. package/cpp/tests/build/tuner_engine_core/CMakeFiles/tuner_engine_core.dir/src/YinPitchDetector.cpp.o.d +755 -0
  186. package/cpp/tests/build/tuner_engine_core/Makefile +544 -0
  187. package/cpp/tests/build/tuner_engine_core/cmake_install.cmake +45 -0
  188. package/cpp/tests/build/tuner_engine_core/libtuner_engine_core.a +0 -0
  189. package/cpp/tests/build/tuner_engine_tests +0 -0
  190. package/cpp/tests/main.cpp +624 -0
  191. package/ios/IosAudioSource.h +23 -0
  192. package/ios/IosAudioSource.mm +174 -0
  193. package/ios/TunerBridge.h +24 -0
  194. package/ios/TunerBridge.mm +136 -0
  195. package/ios/TunerEngine.h +6 -0
  196. package/ios/TunerEngine.mm +144 -0
  197. package/lib/module/NativeTunerEngine.js +5 -0
  198. package/lib/module/NativeTunerEngine.js.map +1 -0
  199. package/lib/module/TunerEngine.js +43 -0
  200. package/lib/module/TunerEngine.js.map +1 -0
  201. package/lib/module/index.js +5 -0
  202. package/lib/module/index.js.map +1 -0
  203. package/lib/module/package.json +1 -0
  204. package/lib/module/types.js +2 -0
  205. package/lib/module/types.js.map +1 -0
  206. package/lib/module/useTuner.js +55 -0
  207. package/lib/module/useTuner.js.map +1 -0
  208. package/lib/typescript/package.json +1 -0
  209. package/lib/typescript/src/NativeTunerEngine.d.ts +17 -0
  210. package/lib/typescript/src/NativeTunerEngine.d.ts.map +1 -0
  211. package/lib/typescript/src/TunerEngine.d.ts +18 -0
  212. package/lib/typescript/src/TunerEngine.d.ts.map +1 -0
  213. package/lib/typescript/src/index.d.ts +4 -0
  214. package/lib/typescript/src/index.d.ts.map +1 -0
  215. package/lib/typescript/src/types.d.ts +86 -0
  216. package/lib/typescript/src/types.d.ts.map +1 -0
  217. package/lib/typescript/src/useTuner.d.ts +15 -0
  218. package/lib/typescript/src/useTuner.d.ts.map +1 -0
  219. package/package.json +141 -0
  220. package/src/NativeTunerEngine.ts +17 -0
  221. package/src/TunerEngine.ts +62 -0
  222. package/src/index.tsx +11 -0
  223. package/src/types.ts +109 -0
  224. package/src/useTuner.ts +67 -0
@@ -0,0 +1,174 @@
1
+ #import "IosAudioSource.h"
2
+ #import <AVFoundation/AVFoundation.h>
3
+
4
+ @implementation IosAudioSource {
5
+ AVAudioEngine* _engine;
6
+ AVAudioInputNode* _inputNode;
7
+ float _sampleRate;
8
+ BOOL _isRunning;
9
+ }
10
+
11
+ - (instancetype)init {
12
+ self = [super init];
13
+ if (self) {
14
+ _sampleRate = 48000.0f;
15
+ _isRunning = NO;
16
+ [self registerNotifications];
17
+ }
18
+ return self;
19
+ }
20
+
21
+ - (void)dealloc {
22
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
23
+ [self stop];
24
+ }
25
+
26
+ - (float)sampleRate {
27
+ return _sampleRate;
28
+ }
29
+
30
+ - (BOOL)startWithError:(NSError **)error {
31
+ if (_isRunning) return YES;
32
+
33
+ AVAudioSession* session = [AVAudioSession sharedInstance];
34
+
35
+ NSError* sessionError = nil;
36
+ [session setCategory:AVAudioSessionCategoryPlayAndRecord
37
+ withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker |
38
+ AVAudioSessionCategoryOptionAllowBluetooth
39
+ error:&sessionError];
40
+ if (sessionError) {
41
+ if (error) *error = sessionError;
42
+ return NO;
43
+ }
44
+
45
+ [session setMode:AVAudioSessionModeMeasurement error:&sessionError];
46
+ if (sessionError) {
47
+ NSLog(@"[IosAudioSource] setMode error (non-fatal): %@", sessionError.localizedDescription);
48
+ sessionError = nil;
49
+ }
50
+
51
+ [session setPreferredSampleRate:48000.0 error:&sessionError];
52
+ if (sessionError) {
53
+ NSLog(@"[IosAudioSource] setPreferredSampleRate error (non-fatal): %@", sessionError.localizedDescription);
54
+ sessionError = nil;
55
+ }
56
+
57
+ [session setPreferredIOBufferDuration:0.0213 error:&sessionError];
58
+ if (sessionError) {
59
+ NSLog(@"[IosAudioSource] setPreferredIOBufferDuration error (non-fatal): %@", sessionError.localizedDescription);
60
+ sessionError = nil;
61
+ }
62
+ [session setActive:YES error:&sessionError];
63
+ if (sessionError) {
64
+ if (error) *error = sessionError;
65
+ return NO;
66
+ }
67
+
68
+ _sampleRate = (float)session.sampleRate;
69
+ _engine = [[AVAudioEngine alloc] init];
70
+ _inputNode = _engine.inputNode;
71
+
72
+ AVAudioFormat* recordingFormat =
73
+ [[AVAudioFormat alloc] initWithCommonFormat:AVAudioPCMFormatFloat32
74
+ sampleRate:_sampleRate
75
+ channels:1
76
+ interleaved:YES];
77
+
78
+ __weak __typeof__(self) weakSelf = self;
79
+
80
+ [_inputNode installTapOnBus:0
81
+ bufferSize:2048
82
+ format:recordingFormat
83
+ block:^(AVAudioPCMBuffer* buffer, AVAudioTime* when) {
84
+ (void)when;
85
+ __strong __typeof__(weakSelf) strongSelf = weakSelf;
86
+ if (!strongSelf || !strongSelf->_isRunning) return;
87
+
88
+ const float* data = buffer.floatChannelData[0];
89
+ const AVAudioFrameCount frames = buffer.frameLength;
90
+
91
+ AudioSamplesCallback cb = strongSelf.onSamples;
92
+ if (cb && frames > 0) {
93
+ cb(data, (int)frames, strongSelf->_sampleRate);
94
+ }
95
+ }];
96
+
97
+ NSError* engineError = nil;
98
+ [_engine prepare];
99
+ [_engine startAndReturnError:&engineError];
100
+ if (engineError) {
101
+ if (error) *error = engineError;
102
+ [_inputNode removeTapOnBus:0];
103
+ _engine = nil;
104
+ return NO;
105
+ }
106
+
107
+ _isRunning = YES;
108
+ return YES;
109
+ }
110
+
111
+ - (void)stop {
112
+ if (!_isRunning) return;
113
+ _isRunning = NO;
114
+
115
+ if (_inputNode) {
116
+ [_inputNode removeTapOnBus:0];
117
+ }
118
+ if (_engine && _engine.isRunning) {
119
+ [_engine stop];
120
+ }
121
+ _engine = nil;
122
+ _inputNode = nil;
123
+
124
+ [[AVAudioSession sharedInstance] setActive:NO
125
+ withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation
126
+ error:nil];
127
+ }
128
+
129
+ #pragma mark - Notifications
130
+
131
+ - (void)registerNotifications {
132
+ [[NSNotificationCenter defaultCenter]
133
+ addObserver:self
134
+ selector:@selector(handleInterruption:)
135
+ name:AVAudioSessionInterruptionNotification
136
+ object:nil];
137
+
138
+ [[NSNotificationCenter defaultCenter]
139
+ addObserver:self
140
+ selector:@selector(handleRouteChange:)
141
+ name:AVAudioSessionRouteChangeNotification
142
+ object:nil];
143
+ }
144
+
145
+ - (void)handleInterruption:(NSNotification *)notification {
146
+ NSDictionary* info = notification.userInfo;
147
+ AVAudioSessionInterruptionType type =
148
+ (AVAudioSessionInterruptionType)[info[AVAudioSessionInterruptionTypeKey] unsignedIntegerValue];
149
+
150
+ if (type == AVAudioSessionInterruptionTypeBegan) {
151
+ [self stop];
152
+ } else if (type == AVAudioSessionInterruptionTypeEnded) {
153
+ AVAudioSessionInterruptionOptions options =
154
+ (AVAudioSessionInterruptionOptions)[info[AVAudioSessionInterruptionOptionKey] unsignedIntegerValue];
155
+ if (options & AVAudioSessionInterruptionOptionShouldResume) {
156
+ NSError* err = nil;
157
+ [self startWithError:&err];
158
+ }
159
+ }
160
+ }
161
+
162
+ - (void)handleRouteChange:(NSNotification *)notification {
163
+ NSDictionary* info = notification.userInfo;
164
+ AVAudioSessionRouteChangeReason reason =
165
+ (AVAudioSessionRouteChangeReason)[info[AVAudioSessionRouteChangeReasonKey] unsignedIntegerValue];
166
+
167
+ if (reason == AVAudioSessionRouteChangeReasonOldDeviceUnavailable) {
168
+ [self stop];
169
+ NSError* err = nil;
170
+ [self startWithError:&err];
171
+ }
172
+ }
173
+
174
+ @end
@@ -0,0 +1,24 @@
1
+ #pragma once
2
+
3
+ #import <Foundation/Foundation.h>
4
+
5
+ NS_ASSUME_NONNULL_BEGIN
6
+
7
+ typedef void (^PitchEventCallback)(NSDictionary* event);
8
+
9
+ @interface TunerBridge : NSObject
10
+
11
+ @property(nonatomic, copy, nullable) PitchEventCallback onPitch;
12
+
13
+ - (void)configure:(NSDictionary *)opts;
14
+ - (void)startWithCompletion:(void(^)(NSError* _Nullable error))completion;
15
+ - (void)stop;
16
+ - (void)setA4:(float)hz;
17
+ - (void)setInstrument:(NSString *)name;
18
+ - (void)setTuning:(NSString *)name;
19
+ - (void)setTemperament:(NSString *)name;
20
+ - (NSDictionary *)getStatus;
21
+
22
+ @end
23
+
24
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,136 @@
1
+ #import "TunerBridge.h"
2
+ #import "IosAudioSource.h"
3
+ #include "AudioFrameDispatcher.hpp"
4
+ #include "PostProcessor.hpp"
5
+ #include <memory>
6
+
7
+ @implementation TunerBridge {
8
+ IosAudioSource* _audioSource;
9
+ std::unique_ptr<AudioFrameDispatcher> _dispatcher;
10
+ bool _isRunning;
11
+ }
12
+
13
+ - (instancetype)init {
14
+ self = [super init];
15
+ if (self) {
16
+ _isRunning = false;
17
+ }
18
+ return self;
19
+ }
20
+
21
+ - (void)configure:(NSDictionary *)opts {
22
+ float sampleRate = opts[@"sampleRate"] ? [opts[@"sampleRate"] floatValue] : 48000.0f;
23
+ int frameSize = opts[@"frameSize"] ? [opts[@"frameSize"] intValue] : 2048;
24
+ float overlapRatio = opts[@"overlapRatio"] ? [opts[@"overlapRatio"] floatValue] : 0.0f;
25
+
26
+ [self buildDispatcherWithSampleRate:sampleRate frameSize:frameSize overlapRatio:overlapRatio opts:opts];
27
+ }
28
+
29
+ - (void)buildDispatcherWithSampleRate:(float)sr frameSize:(int)fs overlapRatio:(float)overlap opts:(NSDictionary*)opts {
30
+ __weak __typeof__(self) weakSelf = self;
31
+
32
+ _dispatcher = std::make_unique<AudioFrameDispatcher>(fs, sr,
33
+ [weakSelf](const PitchResult& r) {
34
+ __strong __typeof__(weakSelf) strongSelf = weakSelf;
35
+ if (!strongSelf || !strongSelf.onPitch) return;
36
+
37
+ NSDictionary* event = @{
38
+ @"hasPitch": @(r.hasPitch),
39
+ @"frequency": @(r.frequency),
40
+ @"confidence": @(r.confidence),
41
+ @"rmsDb": @(r.rmsDb),
42
+ @"noteName": @(r.noteName.c_str()),
43
+ @"octave": @(r.octave),
44
+ @"cents": @(r.cents),
45
+ @"nearestString": @(r.nearestString.c_str()),
46
+ @"stringDeviation": @(r.stringDeviation)
47
+ };
48
+ strongSelf.onPitch(event);
49
+ },
50
+ overlap
51
+ );
52
+
53
+ if (opts[@"noiseGateDb"]) _dispatcher->setNoiseGateDb([opts[@"noiseGateDb"] floatValue]);
54
+ if (opts[@"confidenceThreshold"]) _dispatcher->setConfidenceThreshold([opts[@"confidenceThreshold"] floatValue]);
55
+ if (opts[@"minFrequency"] && opts[@"maxFrequency"]) {
56
+ _dispatcher->setFrequencyRange([opts[@"minFrequency"] floatValue], [opts[@"maxFrequency"] floatValue]);
57
+ }
58
+ if (opts[@"a4"]) _dispatcher->setA4([opts[@"a4"] floatValue]);
59
+ if (opts[@"hpfCutoffHz"]) _dispatcher->setHpfCutoff([opts[@"hpfCutoffHz"] floatValue]);
60
+ if (opts[@"emaAlpha"] || opts[@"hysteresisFrames"]) {
61
+ PostProcessor::Config cfg;
62
+ if (opts[@"emaAlpha"]) cfg.emaAlpha = [opts[@"emaAlpha"] floatValue];
63
+ if (opts[@"hysteresisFrames"]) cfg.hysteresisFrames = [opts[@"hysteresisFrames"] intValue];
64
+ _dispatcher->setPostProcessorConfig(cfg);
65
+ }
66
+ if (opts[@"onsetDetection"]) {
67
+ _dispatcher->setOnsetDetectionEnabled([opts[@"onsetDetection"] boolValue]);
68
+ }
69
+ }
70
+
71
+ - (void)startWithCompletion:(void(^)(NSError* _Nullable error))completion {
72
+ if (_isRunning) {
73
+ completion(nil);
74
+ return;
75
+ }
76
+
77
+ _audioSource = [[IosAudioSource alloc] init];
78
+
79
+ // Spin up dispatcher if not yet configured
80
+ if (!_dispatcher) {
81
+ [self buildDispatcherWithSampleRate:48000.0f frameSize:2048 overlapRatio:0.0f opts:@{}];
82
+ }
83
+
84
+ __weak __typeof__(self) weakSelf = self;
85
+ _audioSource.onSamples = ^(const float* samples, int count, float sampleRate) {
86
+ __strong __typeof__(weakSelf) strongSelf = weakSelf;
87
+ if (!strongSelf || !strongSelf->_dispatcher) return;
88
+ strongSelf->_dispatcher->push(samples, count);
89
+ };
90
+
91
+ NSError* error = nil;
92
+ if (![_audioSource startWithError:&error]) {
93
+ completion(error);
94
+ return;
95
+ }
96
+
97
+ // Sync dispatcher sample rate to what AVAudioSession actually gave us
98
+ const float actualSampleRate = _audioSource.sampleRate;
99
+ _dispatcher->setSampleRate(actualSampleRate);
100
+ _dispatcher->start();
101
+ _isRunning = true;
102
+
103
+ completion(nil);
104
+ }
105
+
106
+ - (void)stop {
107
+ if (!_isRunning) return;
108
+ _isRunning = false;
109
+
110
+ if (_dispatcher) _dispatcher->stop();
111
+ [_audioSource stop];
112
+ _audioSource = nil;
113
+ }
114
+
115
+ - (void)setA4:(float)hz {
116
+ if (_dispatcher) _dispatcher->setA4(hz);
117
+ }
118
+
119
+ - (void)setInstrument:(NSString *)name {
120
+ if (_dispatcher) _dispatcher->setInstrument(std::string([name UTF8String]));
121
+ }
122
+
123
+ - (void)setTuning:(NSString *)name {
124
+ if (_dispatcher) _dispatcher->setTuning(std::string([name UTF8String]));
125
+ }
126
+
127
+ - (void)setTemperament:(NSString *)name {}
128
+
129
+ - (NSDictionary *)getStatus {
130
+ return @{
131
+ @"isRunning": @(_isRunning),
132
+ @"engineReady": @(_dispatcher != nullptr)
133
+ };
134
+ }
135
+
136
+ @end
@@ -0,0 +1,6 @@
1
+ #import <React/RCTEventEmitter.h>
2
+ #import <TunerEngineSpec/TunerEngineSpec.h>
3
+
4
+ @interface TunerEngine : RCTEventEmitter <NativeTunerEngineSpec>
5
+
6
+ @end
@@ -0,0 +1,144 @@
1
+ #import "TunerEngine.h"
2
+ #import "TunerBridge.h"
3
+ #import <AVFoundation/AVFoundation.h>
4
+ #import <ReactCommon/RCTTurboModule.h>
5
+ #import <ReactCommon/CallInvoker.h>
6
+ #import <jsi/jsi.h>
7
+
8
+ @implementation TunerEngine {
9
+ TunerBridge* _tunerBridge;
10
+ std::shared_ptr<facebook::react::CallInvoker> _jsInvoker;
11
+ }
12
+
13
+ RCT_EXPORT_MODULE(TunerEngine)
14
+
15
+ - (instancetype)init {
16
+ self = [super init];
17
+ if (self) {
18
+ [super addListener:@"onPitch"]; // keeps _listenerCount=1 for old-arch fallback
19
+ _tunerBridge = [[TunerBridge alloc] init];
20
+ }
21
+ return self;
22
+ }
23
+
24
+ - (NSArray<NSString *> *)supportedEvents {
25
+ return @[@"onPitch"];
26
+ }
27
+
28
+ - (void)addListener:(NSString *)eventName {}
29
+ - (void)removeListeners:(double)count {}
30
+
31
+ - (void)configure:(NSDictionary *)opts
32
+ resolve:(RCTPromiseResolveBlock)resolve
33
+ reject:(RCTPromiseRejectBlock)reject {
34
+ [_tunerBridge configure:opts];
35
+ resolve(nil);
36
+ }
37
+
38
+ - (void)start:(RCTPromiseResolveBlock)resolve
39
+ reject:(RCTPromiseRejectBlock)reject {
40
+ [_tunerBridge startWithCompletion:^(NSError* error) {
41
+ if (error) {
42
+ reject(@"START_ERROR", error.localizedDescription, error);
43
+ } else {
44
+ resolve(nil);
45
+ }
46
+ }];
47
+ }
48
+
49
+ - (void)stop:(RCTPromiseResolveBlock)resolve
50
+ reject:(RCTPromiseRejectBlock)reject {
51
+ [_tunerBridge stop];
52
+ resolve(nil);
53
+ }
54
+
55
+ - (void)setA4:(double)hz {
56
+ [_tunerBridge setA4:(float)hz];
57
+ }
58
+
59
+ - (void)setInstrument:(NSString *)name {
60
+ [_tunerBridge setInstrument:name];
61
+ }
62
+
63
+ - (void)setTuning:(NSString *)name {
64
+ [_tunerBridge setTuning:name];
65
+ }
66
+
67
+ - (void)setTemperament:(NSString *)name {
68
+ [_tunerBridge setTemperament:name];
69
+ }
70
+
71
+ - (void)requestPermission:(RCTPromiseResolveBlock)resolve
72
+ reject:(RCTPromiseRejectBlock)reject {
73
+ [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL granted) {
74
+ resolve(@(granted));
75
+ }];
76
+ }
77
+
78
+ - (NSDictionary *)getStatus {
79
+ return [_tunerBridge getStatus];
80
+ }
81
+
82
+ + (BOOL)requiresMainQueueSetup {
83
+ return NO;
84
+ }
85
+
86
+ - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
87
+ (const facebook::react::ObjCTurboModule::InitParams &)params
88
+ {
89
+ _jsInvoker = params.jsInvoker;
90
+
91
+ __weak __typeof__(self) weakSelf = self;
92
+ _tunerBridge.onPitch = ^(NSDictionary* event) {
93
+ __strong __typeof__(weakSelf) strongSelf = weakSelf;
94
+ if (!strongSelf) return;
95
+
96
+ auto jsInvoker = strongSelf->_jsInvoker;
97
+ if (!jsInvoker) {
98
+ [strongSelf sendEventWithName:@"onPitch" body:event];
99
+ return;
100
+ }
101
+
102
+ // Extract primitives before crossing thread boundary
103
+ bool hasPitch = [event[@"hasPitch"] boolValue];
104
+ double frequency = [event[@"frequency"] doubleValue];
105
+ double confidence = [event[@"confidence"] doubleValue];
106
+ double rmsDb = [event[@"rmsDb"] doubleValue];
107
+ std::string note = std::string([event[@"noteName"] UTF8String]);
108
+ int octave = [event[@"octave"] intValue];
109
+ double cents = [event[@"cents"] doubleValue];
110
+ std::string nearestStr = event[@"nearestString"]
111
+ ? std::string([event[@"nearestString"] UTF8String]) : std::string();
112
+ double stringDev = [event[@"stringDeviation"] doubleValue];
113
+
114
+ jsInvoker->invokeAsync([weakSelf, hasPitch, frequency, confidence, rmsDb,
115
+ note, octave, cents, nearestStr, stringDev](facebook::jsi::Runtime& rt) {
116
+ __strong __typeof__(weakSelf) innerSelf = weakSelf;
117
+ if (!innerSelf) return; // Module deallocated — bail out
118
+
119
+ auto cb = rt.global().getProperty(rt, "__tunerEngineOnPitch");
120
+ if (!cb.isObject()) return;
121
+ auto fn = cb.asObject(rt);
122
+ if (!fn.isFunction(rt)) return;
123
+
124
+ facebook::jsi::Object obj(rt);
125
+ obj.setProperty(rt, "hasPitch", facebook::jsi::Value(hasPitch));
126
+ obj.setProperty(rt, "frequency", facebook::jsi::Value(frequency));
127
+ obj.setProperty(rt, "confidence", facebook::jsi::Value(confidence));
128
+ obj.setProperty(rt, "rmsDb", facebook::jsi::Value(rmsDb));
129
+ obj.setProperty(rt, "noteName",
130
+ facebook::jsi::String::createFromUtf8(rt, note));
131
+ obj.setProperty(rt, "octave", facebook::jsi::Value(octave));
132
+ obj.setProperty(rt, "cents", facebook::jsi::Value(cents));
133
+ obj.setProperty(rt, "nearestString",
134
+ facebook::jsi::String::createFromUtf8(rt, nearestStr));
135
+ obj.setProperty(rt, "stringDeviation", facebook::jsi::Value(stringDev));
136
+
137
+ fn.asFunction(rt).call(rt, std::move(obj));
138
+ });
139
+ };
140
+
141
+ return std::make_shared<facebook::react::NativeTunerEngineSpecJSI>(params);
142
+ }
143
+
144
+ @end
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+
3
+ import { TurboModuleRegistry } from 'react-native';
4
+ export default TurboModuleRegistry.getEnforcing('TunerEngine');
5
+ //# sourceMappingURL=NativeTunerEngine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeTunerEngine.ts"],"mappings":";;AAAA,SAASA,mBAAmB,QAA0B,cAAc;AAgBpE,eAAeA,mBAAmB,CAACC,YAAY,CAAO,aAAa,CAAC","ignoreList":[]}
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+
3
+ import { DeviceEventEmitter } from 'react-native';
4
+ import NativeTunerEngine from "./NativeTunerEngine.js";
5
+ class TunerEngine {
6
+ configure(opts) {
7
+ return NativeTunerEngine.configure(opts);
8
+ }
9
+ start() {
10
+ return NativeTunerEngine.start();
11
+ }
12
+ stop() {
13
+ return NativeTunerEngine.stop();
14
+ }
15
+ requestPermission() {
16
+ return NativeTunerEngine.requestPermission();
17
+ }
18
+ setA4(hz) {
19
+ NativeTunerEngine.setA4(hz);
20
+ }
21
+ setInstrument(name) {
22
+ NativeTunerEngine.setInstrument(name);
23
+ }
24
+ setTemperament(name) {
25
+ NativeTunerEngine.setTemperament(name);
26
+ }
27
+ setTuning(name) {
28
+ NativeTunerEngine.setTuning(name);
29
+ }
30
+ getStatus() {
31
+ return NativeTunerEngine.getStatus();
32
+ }
33
+ onPitch(callback) {
34
+ globalThis.__tunerEngineOnPitch = callback;
35
+ const sub = DeviceEventEmitter.addListener('onPitch', callback);
36
+ return () => {
37
+ globalThis.__tunerEngineOnPitch = undefined;
38
+ sub.remove();
39
+ };
40
+ }
41
+ }
42
+ export default new TunerEngine();
43
+ //# sourceMappingURL=TunerEngine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["DeviceEventEmitter","NativeTunerEngine","TunerEngine","configure","opts","start","stop","requestPermission","setA4","hz","setInstrument","name","setTemperament","setTuning","getStatus","onPitch","callback","globalThis","__tunerEngineOnPitch","sub","addListener","undefined","remove"],"sourceRoot":"../../src","sources":["TunerEngine.ts"],"mappings":";;AAAA,SAASA,kBAAkB,QAAQ,cAAc;AACjD,OAAOC,iBAAiB,MAAM,wBAAqB;AAanD,MAAMC,WAAW,CAAC;EAChBC,SAASA,CAACC,IAAiB,EAAiB;IAC1C,OAAOH,iBAAiB,CAACE,SAAS,CAACC,IAAI,CAAC;EAC1C;EAEAC,KAAKA,CAAA,EAAkB;IACrB,OAAOJ,iBAAiB,CAACI,KAAK,CAAC,CAAC;EAClC;EAEAC,IAAIA,CAAA,EAAkB;IACpB,OAAOL,iBAAiB,CAACK,IAAI,CAAC,CAAC;EACjC;EAEAC,iBAAiBA,CAAA,EAAqB;IACpC,OAAON,iBAAiB,CAACM,iBAAiB,CAAC,CAAC;EAC9C;EAEAC,KAAKA,CAACC,EAAU,EAAQ;IACtBR,iBAAiB,CAACO,KAAK,CAACC,EAAE,CAAC;EAC7B;EAEAC,aAAaA,CAACC,IAAgB,EAAQ;IACpCV,iBAAiB,CAACS,aAAa,CAACC,IAAI,CAAC;EACvC;EAEAC,cAAcA,CAACD,IAAiB,EAAQ;IACtCV,iBAAiB,CAACW,cAAc,CAACD,IAAI,CAAC;EACxC;EAEAE,SAASA,CAACF,IAAuB,EAAQ;IACvCV,iBAAiB,CAACY,SAAS,CAACF,IAAI,CAAC;EACnC;EAEAG,SAASA,CAAA,EAAiB;IACxB,OAAOb,iBAAiB,CAACa,SAAS,CAAC,CAAC;EACtC;EAEAC,OAAOA,CAACC,QAAuB,EAAe;IAC3CC,UAAU,CAASC,oBAAoB,GAAGF,QAAQ;IACnD,MAAMG,GAAG,GAAGnB,kBAAkB,CAACoB,WAAW,CAAC,SAAS,EAAEJ,QAAQ,CAAC;IAC/D,OAAO,MAAM;MACVC,UAAU,CAASC,oBAAoB,GAAGG,SAAS;MACpDF,GAAG,CAACG,MAAM,CAAC,CAAC;IACd,CAAC;EACH;AACF;AAEA,eAAe,IAAIpB,WAAW,CAAC,CAAC","ignoreList":[]}
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+
3
+ export { default as TunerEngine } from "./TunerEngine.js";
4
+ export { useTuner } from "./useTuner.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["default","TunerEngine","useTuner"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SAASA,OAAO,IAAIC,WAAW,QAAQ,kBAAe;AACtD,SAASC,QAAQ,QAAQ,eAAY","ignoreList":[]}
@@ -0,0 +1 @@
1
+ {"type":"module"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sourceRoot":"../../src","sources":["types.ts"],"mappings":"","ignoreList":[]}
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+
3
+ import { useCallback, useEffect, useRef, useState } from 'react';
4
+ import TunerEngine from "./TunerEngine.js";
5
+ export function useTuner(opts = {}) {
6
+ const [latest, setLatest] = useState(null);
7
+ const [isRunning, setIsRunning] = useState(false);
8
+ const [error, setError] = useState(null);
9
+ const optsRef = useRef(opts);
10
+ optsRef.current = opts;
11
+ const unsubscribeRef = useRef(null);
12
+ const stop = useCallback(async () => {
13
+ unsubscribeRef.current?.();
14
+ unsubscribeRef.current = null;
15
+ await TunerEngine.stop();
16
+ setIsRunning(false);
17
+ }, []);
18
+ const start = useCallback(async () => {
19
+ setError(null);
20
+ try {
21
+ const granted = await TunerEngine.requestPermission();
22
+ if (!granted) {
23
+ throw new Error('Microphone permission denied');
24
+ }
25
+ const {
26
+ instrument,
27
+ a4,
28
+ ...config
29
+ } = optsRef.current;
30
+ await TunerEngine.configure(config);
31
+ if (instrument) TunerEngine.setInstrument(instrument);
32
+ if (a4 !== undefined) TunerEngine.setA4(a4);
33
+ unsubscribeRef.current = TunerEngine.onPitch(setLatest);
34
+ await TunerEngine.start();
35
+ setIsRunning(true);
36
+ } catch (e) {
37
+ setError(e instanceof Error ? e : new Error(String(e)));
38
+ setIsRunning(false);
39
+ }
40
+ }, []);
41
+ useEffect(() => {
42
+ return () => {
43
+ unsubscribeRef.current?.();
44
+ TunerEngine.stop();
45
+ };
46
+ }, []);
47
+ return {
48
+ start,
49
+ stop,
50
+ latest,
51
+ isRunning,
52
+ error
53
+ };
54
+ }
55
+ //# sourceMappingURL=useTuner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useCallback","useEffect","useRef","useState","TunerEngine","useTuner","opts","latest","setLatest","isRunning","setIsRunning","error","setError","optsRef","current","unsubscribeRef","stop","start","granted","requestPermission","Error","instrument","a4","config","configure","setInstrument","undefined","setA4","onPitch","e","String"],"sourceRoot":"../../src","sources":["useTuner.ts"],"mappings":";;AAAA,SAASA,WAAW,EAAEC,SAAS,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,OAAO;AAChE,OAAOC,WAAW,MAAM,kBAAe;AAgBvC,OAAO,SAASC,QAAQA,CAACC,IAAqB,GAAG,CAAC,CAAC,EAAkB;EACnE,MAAM,CAACC,MAAM,EAAEC,SAAS,CAAC,GAAGL,QAAQ,CAAoB,IAAI,CAAC;EAC7D,MAAM,CAACM,SAAS,EAAEC,YAAY,CAAC,GAAGP,QAAQ,CAAC,KAAK,CAAC;EACjD,MAAM,CAACQ,KAAK,EAAEC,QAAQ,CAAC,GAAGT,QAAQ,CAAe,IAAI,CAAC;EAEtD,MAAMU,OAAO,GAAGX,MAAM,CAACI,IAAI,CAAC;EAC5BO,OAAO,CAACC,OAAO,GAAGR,IAAI;EAEtB,MAAMS,cAAc,GAAGb,MAAM,CAAsB,IAAI,CAAC;EAExD,MAAMc,IAAI,GAAGhB,WAAW,CAAC,YAAY;IACnCe,cAAc,CAACD,OAAO,GAAG,CAAC;IAC1BC,cAAc,CAACD,OAAO,GAAG,IAAI;IAC7B,MAAMV,WAAW,CAACY,IAAI,CAAC,CAAC;IACxBN,YAAY,CAAC,KAAK,CAAC;EACrB,CAAC,EAAE,EAAE,CAAC;EAEN,MAAMO,KAAK,GAAGjB,WAAW,CAAC,YAAY;IACpCY,QAAQ,CAAC,IAAI,CAAC;IACd,IAAI;MACF,MAAMM,OAAO,GAAG,MAAMd,WAAW,CAACe,iBAAiB,CAAC,CAAC;MACrD,IAAI,CAACD,OAAO,EAAE;QACZ,MAAM,IAAIE,KAAK,CAAC,8BAA8B,CAAC;MACjD;MAEA,MAAM;QAAEC,UAAU;QAAEC,EAAE;QAAE,GAAGC;MAAO,CAAC,GAAGV,OAAO,CAACC,OAAO;MACrD,MAAMV,WAAW,CAACoB,SAAS,CAACD,MAAM,CAAC;MAEnC,IAAIF,UAAU,EAAEjB,WAAW,CAACqB,aAAa,CAACJ,UAAU,CAAC;MACrD,IAAIC,EAAE,KAAKI,SAAS,EAAEtB,WAAW,CAACuB,KAAK,CAACL,EAAE,CAAC;MAE3CP,cAAc,CAACD,OAAO,GAAGV,WAAW,CAACwB,OAAO,CAACpB,SAAS,CAAC;MAEvD,MAAMJ,WAAW,CAACa,KAAK,CAAC,CAAC;MACzBP,YAAY,CAAC,IAAI,CAAC;IACpB,CAAC,CAAC,OAAOmB,CAAC,EAAE;MACVjB,QAAQ,CAACiB,CAAC,YAAYT,KAAK,GAAGS,CAAC,GAAG,IAAIT,KAAK,CAACU,MAAM,CAACD,CAAC,CAAC,CAAC,CAAC;MACvDnB,YAAY,CAAC,KAAK,CAAC;IACrB;EACF,CAAC,EAAE,EAAE,CAAC;EAENT,SAAS,CAAC,MAAM;IACd,OAAO,MAAM;MACXc,cAAc,CAACD,OAAO,GAAG,CAAC;MAC1BV,WAAW,CAACY,IAAI,CAAC,CAAC;IACpB,CAAC;EACH,CAAC,EAAE,EAAE,CAAC;EAEN,OAAO;IAAEC,KAAK;IAAED,IAAI;IAAET,MAAM;IAAEE,SAAS;IAAEE;EAAM,CAAC;AAClD","ignoreList":[]}
@@ -0,0 +1 @@
1
+ {"type":"module"}
@@ -0,0 +1,17 @@
1
+ import { type TurboModule } from 'react-native';
2
+ export interface Spec extends TurboModule {
3
+ configure(opts: Object): Promise<void>;
4
+ start(): Promise<void>;
5
+ stop(): Promise<void>;
6
+ setA4(hz: number): void;
7
+ setInstrument(name: string): void;
8
+ setTemperament(name: string): void;
9
+ setTuning(name: string): void;
10
+ requestPermission(): Promise<boolean>;
11
+ getStatus(): Object;
12
+ addListener(eventName: string): void;
13
+ removeListeners(count: number): void;
14
+ }
15
+ declare const _default: Spec;
16
+ export default _default;
17
+ //# sourceMappingURL=NativeTunerEngine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NativeTunerEngine.d.ts","sourceRoot":"","sources":["../../../src/NativeTunerEngine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAErE,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IACtC,SAAS,IAAI,MAAM,CAAC;IACpB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;;AAED,wBAAqE"}
@@ -0,0 +1,18 @@
1
+ import type { EngineStatus, Instrument, PitchEvent, Temperament, TunerConfig, TuningPreset } from './types';
2
+ type PitchCallback = (event: PitchEvent) => void;
3
+ type Unsubscribe = () => void;
4
+ declare class TunerEngine {
5
+ configure(opts: TunerConfig): Promise<void>;
6
+ start(): Promise<void>;
7
+ stop(): Promise<void>;
8
+ requestPermission(): Promise<boolean>;
9
+ setA4(hz: number): void;
10
+ setInstrument(name: Instrument): void;
11
+ setTemperament(name: Temperament): void;
12
+ setTuning(name: TuningPreset | ''): void;
13
+ getStatus(): EngineStatus;
14
+ onPitch(callback: PitchCallback): Unsubscribe;
15
+ }
16
+ declare const _default: TunerEngine;
17
+ export default _default;
18
+ //# sourceMappingURL=TunerEngine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TunerEngine.d.ts","sourceRoot":"","sources":["../../../src/TunerEngine.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,YAAY,EACZ,UAAU,EACV,UAAU,EACV,WAAW,EACX,WAAW,EACX,YAAY,EACb,MAAM,SAAS,CAAC;AAEjB,KAAK,aAAa,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;AACjD,KAAK,WAAW,GAAG,MAAM,IAAI,CAAC;AAE9B,cAAM,WAAW;IACf,SAAS,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC;IAIrC,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAIvB,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;IAIrC,cAAc,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI;IAIvC,SAAS,CAAC,IAAI,EAAE,YAAY,GAAG,EAAE,GAAG,IAAI;IAIxC,SAAS,IAAI,YAAY;IAIzB,OAAO,CAAC,QAAQ,EAAE,aAAa,GAAG,WAAW;CAQ9C;;AAED,wBAAiC"}