@siteed/audio-studio 3.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 (375) hide show
  1. package/CHANGELOG.md +535 -0
  2. package/LICENSE +21 -0
  3. package/README.md +167 -0
  4. package/android/build.gradle +143 -0
  5. package/android/src/androidTest/assets/chorus.wav +0 -0
  6. package/android/src/androidTest/assets/jfk.wav +0 -0
  7. package/android/src/androidTest/assets/osr_us_000_0010_8k.wav +0 -0
  8. package/android/src/androidTest/assets/recorder_hello_world.wav +0 -0
  9. package/android/src/androidTest/java/net/siteed/audiostudio/AudioProcessorInstrumentedTest.kt +197 -0
  10. package/android/src/androidTest/java/net/siteed/audiostudio/AudioRecorderInstrumentedTest.kt +541 -0
  11. package/android/src/androidTest/java/net/siteed/audiostudio/AudioRecorderPerformanceInstrumentedTest.kt +234 -0
  12. package/android/src/androidTest/java/net/siteed/audiostudio/integration/AudioFocusStrategyIntegrationTest.kt +332 -0
  13. package/android/src/androidTest/java/net/siteed/audiostudio/integration/BufferDurationIntegrationTest.kt +324 -0
  14. package/android/src/androidTest/java/net/siteed/audiostudio/integration/CompressedOnlyOutputTest.kt +253 -0
  15. package/android/src/androidTest/java/net/siteed/audiostudio/integration/DeviceDisconnectionFallbackTest.kt +218 -0
  16. package/android/src/androidTest/java/net/siteed/audiostudio/integration/EventEmissionIntervalTest.kt +120 -0
  17. package/android/src/androidTest/java/net/siteed/audiostudio/integration/M4aFormatTest.kt +345 -0
  18. package/android/src/androidTest/java/net/siteed/audiostudio/integration/OutputControlIntegrationTest.kt +340 -0
  19. package/android/src/androidTest/java/net/siteed/audiostudio/integration/PcmStreamingDurationTest.kt +252 -0
  20. package/android/src/androidTest/java/net/siteed/audiostudio/integration/README.md +95 -0
  21. package/android/src/androidTest/java/net/siteed/audiostudio/integration/run_integration_tests.sh +43 -0
  22. package/android/src/main/AndroidManifest.xml +30 -0
  23. package/android/src/main/CMakeLists.txt +29 -0
  24. package/android/src/main/java/net/siteed/audiostudio/AudioAnalysisData.kt +188 -0
  25. package/android/src/main/java/net/siteed/audiostudio/AudioDataEncoder.kt +9 -0
  26. package/android/src/main/java/net/siteed/audiostudio/AudioDeviceManager.kt +1741 -0
  27. package/android/src/main/java/net/siteed/audiostudio/AudioFeaturesNative.kt +26 -0
  28. package/android/src/main/java/net/siteed/audiostudio/AudioFileHandler.kt +136 -0
  29. package/android/src/main/java/net/siteed/audiostudio/AudioFormatUtils.kt +354 -0
  30. package/android/src/main/java/net/siteed/audiostudio/AudioNotificationsManager.kt +439 -0
  31. package/android/src/main/java/net/siteed/audiostudio/AudioProcessor.kt +2237 -0
  32. package/android/src/main/java/net/siteed/audiostudio/AudioRecorderManager.kt +2163 -0
  33. package/android/src/main/java/net/siteed/audiostudio/AudioRecordingService.kt +167 -0
  34. package/android/src/main/java/net/siteed/audiostudio/AudioStudioModule.kt +1112 -0
  35. package/android/src/main/java/net/siteed/audiostudio/AudioTrimmer.kt +1099 -0
  36. package/android/src/main/java/net/siteed/audiostudio/Constants.kt +37 -0
  37. package/android/src/main/java/net/siteed/audiostudio/EventSender.kt +7 -0
  38. package/android/src/main/java/net/siteed/audiostudio/FFT.kt +100 -0
  39. package/android/src/main/java/net/siteed/audiostudio/Features.kt +98 -0
  40. package/android/src/main/java/net/siteed/audiostudio/LogUtils.kt +93 -0
  41. package/android/src/main/java/net/siteed/audiostudio/MelSpectrogramNative.kt +36 -0
  42. package/android/src/main/java/net/siteed/audiostudio/NotificationConfig.kt +72 -0
  43. package/android/src/main/java/net/siteed/audiostudio/PermissionUtils.kt +68 -0
  44. package/android/src/main/java/net/siteed/audiostudio/RecordingActionReceiver.kt +59 -0
  45. package/android/src/main/java/net/siteed/audiostudio/RecordingConfig.kt +259 -0
  46. package/android/src/main/java/net/siteed/audiostudio/WaveformConfig.kt +19 -0
  47. package/android/src/main/java/net/siteed/audiostudio/WaveformRenderer.kt +159 -0
  48. package/android/src/main/jni/AudioFeaturesJNI.cpp +152 -0
  49. package/android/src/main/jni/MelSpectrogramJNI.cpp +165 -0
  50. package/android/src/main/res/drawable/ic_default_action_icon.xml +16 -0
  51. package/android/src/main/res/drawable/ic_microphone.xml +13 -0
  52. package/android/src/main/res/drawable/ic_pause.xml +10 -0
  53. package/android/src/main/res/drawable/ic_play.xml +10 -0
  54. package/android/src/main/res/drawable/ic_stop.xml +10 -0
  55. package/android/src/main/res/layout/notification_recording.xml +37 -0
  56. package/android/src/test/java/net/siteed/audiostudio/AudioFileHandlerTest.kt +279 -0
  57. package/android/src/test/java/net/siteed/audiostudio/AudioFocusStrategyTest.kt +249 -0
  58. package/android/src/test/java/net/siteed/audiostudio/AudioFormatTest.kt +151 -0
  59. package/android/src/test/java/net/siteed/audiostudio/AudioFormatUtilsTest.kt +273 -0
  60. package/android/src/test/java/net/siteed/audiostudio/DeviceDisconnectionFallbackUnitTest.kt +140 -0
  61. package/android/src/test/resources/chorus.wav +0 -0
  62. package/android/src/test/resources/generate_test_audio.py +94 -0
  63. package/android/src/test/resources/jfk.wav +0 -0
  64. package/android/src/test/resources/osr_us_000_0010_8k.wav +0 -0
  65. package/android/src/test/resources/recorder_hello_world.wav +0 -0
  66. package/app.plugin.js +3 -0
  67. package/build/cjs/AudioAnalysis/AudioAnalysis.types.js +4 -0
  68. package/build/cjs/AudioAnalysis/AudioAnalysis.types.js.map +1 -0
  69. package/build/cjs/AudioAnalysis/audioFeaturesWasm.js +164 -0
  70. package/build/cjs/AudioAnalysis/audioFeaturesWasm.js.map +1 -0
  71. package/build/cjs/AudioAnalysis/extractAudioAnalysis.js +213 -0
  72. package/build/cjs/AudioAnalysis/extractAudioAnalysis.js.map +1 -0
  73. package/build/cjs/AudioAnalysis/extractAudioData.js +21 -0
  74. package/build/cjs/AudioAnalysis/extractAudioData.js.map +1 -0
  75. package/build/cjs/AudioAnalysis/extractMelSpectrogram.js +90 -0
  76. package/build/cjs/AudioAnalysis/extractMelSpectrogram.js.map +1 -0
  77. package/build/cjs/AudioAnalysis/extractPreview.js +28 -0
  78. package/build/cjs/AudioAnalysis/extractPreview.js.map +1 -0
  79. package/build/cjs/AudioAnalysis/extractWaveform.js +18 -0
  80. package/build/cjs/AudioAnalysis/extractWaveform.js.map +1 -0
  81. package/build/cjs/AudioAnalysis/melSpectrogramWasm.js +149 -0
  82. package/build/cjs/AudioAnalysis/melSpectrogramWasm.js.map +1 -0
  83. package/build/cjs/AudioDeviceManager.js +688 -0
  84. package/build/cjs/AudioDeviceManager.js.map +1 -0
  85. package/build/cjs/AudioRecorder.provider.js +78 -0
  86. package/build/cjs/AudioRecorder.provider.js.map +1 -0
  87. package/build/cjs/AudioStudio.native.js +8 -0
  88. package/build/cjs/AudioStudio.native.js.map +1 -0
  89. package/build/cjs/AudioStudio.types.js +11 -0
  90. package/build/cjs/AudioStudio.types.js.map +1 -0
  91. package/build/cjs/AudioStudio.web.js +708 -0
  92. package/build/cjs/AudioStudio.web.js.map +1 -0
  93. package/build/cjs/AudioStudioModule.js +718 -0
  94. package/build/cjs/AudioStudioModule.js.map +1 -0
  95. package/build/cjs/WebRecorder.web.js +865 -0
  96. package/build/cjs/WebRecorder.web.js.map +1 -0
  97. package/build/cjs/constants/platformLimitations.js +99 -0
  98. package/build/cjs/constants/platformLimitations.js.map +1 -0
  99. package/build/cjs/constants.js +20 -0
  100. package/build/cjs/constants.js.map +1 -0
  101. package/build/cjs/events.js +29 -0
  102. package/build/cjs/events.js.map +1 -0
  103. package/build/cjs/hooks/useAudioDevices.js +179 -0
  104. package/build/cjs/hooks/useAudioDevices.js.map +1 -0
  105. package/build/cjs/index.js +64 -0
  106. package/build/cjs/index.js.map +1 -0
  107. package/build/cjs/trimAudio.js +76 -0
  108. package/build/cjs/trimAudio.js.map +1 -0
  109. package/build/cjs/useAudioRecorder.js +535 -0
  110. package/build/cjs/useAudioRecorder.js.map +1 -0
  111. package/build/cjs/utils/BlobFix.js +502 -0
  112. package/build/cjs/utils/BlobFix.js.map +1 -0
  113. package/build/cjs/utils/audioProcessing.js +136 -0
  114. package/build/cjs/utils/audioProcessing.js.map +1 -0
  115. package/build/cjs/utils/cleanNativeOptions.js +22 -0
  116. package/build/cjs/utils/cleanNativeOptions.js.map +1 -0
  117. package/build/cjs/utils/concatenateBuffers.js +25 -0
  118. package/build/cjs/utils/concatenateBuffers.js.map +1 -0
  119. package/build/cjs/utils/convertPCMToFloat32.js +124 -0
  120. package/build/cjs/utils/convertPCMToFloat32.js.map +1 -0
  121. package/build/cjs/utils/crc32.js +52 -0
  122. package/build/cjs/utils/crc32.js.map +1 -0
  123. package/build/cjs/utils/encodingToBitDepth.js +17 -0
  124. package/build/cjs/utils/encodingToBitDepth.js.map +1 -0
  125. package/build/cjs/utils/getWavFileInfo.js +96 -0
  126. package/build/cjs/utils/getWavFileInfo.js.map +1 -0
  127. package/build/cjs/utils/writeWavHeader.js +88 -0
  128. package/build/cjs/utils/writeWavHeader.js.map +1 -0
  129. package/build/cjs/workers/InlineFeaturesExtractor.web.js +294 -0
  130. package/build/cjs/workers/InlineFeaturesExtractor.web.js.map +1 -0
  131. package/build/cjs/workers/inlineAudioWebWorker.web.js +190 -0
  132. package/build/cjs/workers/inlineAudioWebWorker.web.js.map +1 -0
  133. package/build/cjs/workers/wasmGlueString.web.js +27 -0
  134. package/build/cjs/workers/wasmGlueString.web.js.map +1 -0
  135. package/build/esm/AudioAnalysis/AudioAnalysis.types.js +3 -0
  136. package/build/esm/AudioAnalysis/AudioAnalysis.types.js.map +1 -0
  137. package/build/esm/AudioAnalysis/audioFeaturesWasm.js +126 -0
  138. package/build/esm/AudioAnalysis/audioFeaturesWasm.js.map +1 -0
  139. package/build/esm/AudioAnalysis/extractAudioAnalysis.js +205 -0
  140. package/build/esm/AudioAnalysis/extractAudioAnalysis.js.map +1 -0
  141. package/build/esm/AudioAnalysis/extractAudioData.js +14 -0
  142. package/build/esm/AudioAnalysis/extractAudioData.js.map +1 -0
  143. package/build/esm/AudioAnalysis/extractMelSpectrogram.js +86 -0
  144. package/build/esm/AudioAnalysis/extractMelSpectrogram.js.map +1 -0
  145. package/build/esm/AudioAnalysis/extractPreview.js +25 -0
  146. package/build/esm/AudioAnalysis/extractPreview.js.map +1 -0
  147. package/build/esm/AudioAnalysis/extractWaveform.js +11 -0
  148. package/build/esm/AudioAnalysis/extractWaveform.js.map +1 -0
  149. package/build/esm/AudioAnalysis/melSpectrogramWasm.js +111 -0
  150. package/build/esm/AudioAnalysis/melSpectrogramWasm.js.map +1 -0
  151. package/build/esm/AudioDeviceManager.js +681 -0
  152. package/build/esm/AudioDeviceManager.js.map +1 -0
  153. package/build/esm/AudioRecorder.provider.js +40 -0
  154. package/build/esm/AudioRecorder.provider.js.map +1 -0
  155. package/build/esm/AudioStudio.native.js +6 -0
  156. package/build/esm/AudioStudio.native.js.map +1 -0
  157. package/build/esm/AudioStudio.types.js +8 -0
  158. package/build/esm/AudioStudio.types.js.map +1 -0
  159. package/build/esm/AudioStudio.web.js +704 -0
  160. package/build/esm/AudioStudio.web.js.map +1 -0
  161. package/build/esm/AudioStudioModule.js +713 -0
  162. package/build/esm/AudioStudioModule.js.map +1 -0
  163. package/build/esm/WebRecorder.web.js +861 -0
  164. package/build/esm/WebRecorder.web.js.map +1 -0
  165. package/build/esm/constants/platformLimitations.js +90 -0
  166. package/build/esm/constants/platformLimitations.js.map +1 -0
  167. package/build/esm/constants.js +17 -0
  168. package/build/esm/constants.js.map +1 -0
  169. package/build/esm/events.js +21 -0
  170. package/build/esm/events.js.map +1 -0
  171. package/build/esm/hooks/useAudioDevices.js +176 -0
  172. package/build/esm/hooks/useAudioDevices.js.map +1 -0
  173. package/build/esm/index.js +23 -0
  174. package/build/esm/index.js.map +1 -0
  175. package/build/esm/trimAudio.js +69 -0
  176. package/build/esm/trimAudio.js.map +1 -0
  177. package/build/esm/useAudioRecorder.js +529 -0
  178. package/build/esm/useAudioRecorder.js.map +1 -0
  179. package/build/esm/utils/BlobFix.js +498 -0
  180. package/build/esm/utils/BlobFix.js.map +1 -0
  181. package/build/esm/utils/audioProcessing.js +133 -0
  182. package/build/esm/utils/audioProcessing.js.map +1 -0
  183. package/build/esm/utils/cleanNativeOptions.js +19 -0
  184. package/build/esm/utils/cleanNativeOptions.js.map +1 -0
  185. package/build/esm/utils/concatenateBuffers.js +21 -0
  186. package/build/esm/utils/concatenateBuffers.js.map +1 -0
  187. package/build/esm/utils/convertPCMToFloat32.js +120 -0
  188. package/build/esm/utils/convertPCMToFloat32.js.map +1 -0
  189. package/build/esm/utils/crc32.js +50 -0
  190. package/build/esm/utils/crc32.js.map +1 -0
  191. package/build/esm/utils/encodingToBitDepth.js +13 -0
  192. package/build/esm/utils/encodingToBitDepth.js.map +1 -0
  193. package/build/esm/utils/getWavFileInfo.js +92 -0
  194. package/build/esm/utils/getWavFileInfo.js.map +1 -0
  195. package/build/esm/utils/writeWavHeader.js +84 -0
  196. package/build/esm/utils/writeWavHeader.js.map +1 -0
  197. package/build/esm/workers/InlineFeaturesExtractor.web.js +291 -0
  198. package/build/esm/workers/InlineFeaturesExtractor.web.js.map +1 -0
  199. package/build/esm/workers/inlineAudioWebWorker.web.js +187 -0
  200. package/build/esm/workers/inlineAudioWebWorker.web.js.map +1 -0
  201. package/build/esm/workers/wasmGlueString.web.js +24 -0
  202. package/build/esm/workers/wasmGlueString.web.js.map +1 -0
  203. package/build/types/AudioAnalysis/AudioAnalysis.types.d.ts +198 -0
  204. package/build/types/AudioAnalysis/AudioAnalysis.types.d.ts.map +1 -0
  205. package/build/types/AudioAnalysis/audioFeaturesWasm.d.ts +24 -0
  206. package/build/types/AudioAnalysis/audioFeaturesWasm.d.ts.map +1 -0
  207. package/build/types/AudioAnalysis/extractAudioAnalysis.d.ts +74 -0
  208. package/build/types/AudioAnalysis/extractAudioAnalysis.d.ts.map +1 -0
  209. package/build/types/AudioAnalysis/extractAudioData.d.ts +3 -0
  210. package/build/types/AudioAnalysis/extractAudioData.d.ts.map +1 -0
  211. package/build/types/AudioAnalysis/extractMelSpectrogram.d.ts +20 -0
  212. package/build/types/AudioAnalysis/extractMelSpectrogram.d.ts.map +1 -0
  213. package/build/types/AudioAnalysis/extractPreview.d.ts +11 -0
  214. package/build/types/AudioAnalysis/extractPreview.d.ts.map +1 -0
  215. package/build/types/AudioAnalysis/extractWaveform.d.ts +8 -0
  216. package/build/types/AudioAnalysis/extractWaveform.d.ts.map +1 -0
  217. package/build/types/AudioAnalysis/melSpectrogramWasm.d.ts +16 -0
  218. package/build/types/AudioAnalysis/melSpectrogramWasm.d.ts.map +1 -0
  219. package/build/types/AudioDeviceManager.d.ts +187 -0
  220. package/build/types/AudioDeviceManager.d.ts.map +1 -0
  221. package/build/types/AudioRecorder.provider.d.ts +11 -0
  222. package/build/types/AudioRecorder.provider.d.ts.map +1 -0
  223. package/build/types/AudioStudio.native.d.ts +3 -0
  224. package/build/types/AudioStudio.native.d.ts.map +1 -0
  225. package/build/types/AudioStudio.types.d.ts +760 -0
  226. package/build/types/AudioStudio.types.d.ts.map +1 -0
  227. package/build/types/AudioStudio.web.d.ts +96 -0
  228. package/build/types/AudioStudio.web.d.ts.map +1 -0
  229. package/build/types/AudioStudioModule.d.ts +3 -0
  230. package/build/types/AudioStudioModule.d.ts.map +1 -0
  231. package/build/types/WebRecorder.web.d.ts +208 -0
  232. package/build/types/WebRecorder.web.d.ts.map +1 -0
  233. package/build/types/constants/platformLimitations.d.ts +40 -0
  234. package/build/types/constants/platformLimitations.d.ts.map +1 -0
  235. package/build/types/constants.d.ts +14 -0
  236. package/build/types/constants.d.ts.map +1 -0
  237. package/build/types/events.d.ts +29 -0
  238. package/build/types/events.d.ts.map +1 -0
  239. package/build/types/hooks/useAudioDevices.d.ts +15 -0
  240. package/build/types/hooks/useAudioDevices.d.ts.map +1 -0
  241. package/build/types/index.d.ts +21 -0
  242. package/build/types/index.d.ts.map +1 -0
  243. package/build/types/trimAudio.d.ts +25 -0
  244. package/build/types/trimAudio.d.ts.map +1 -0
  245. package/build/types/useAudioRecorder.d.ts +22 -0
  246. package/build/types/useAudioRecorder.d.ts.map +1 -0
  247. package/build/types/utils/BlobFix.d.ts +9 -0
  248. package/build/types/utils/BlobFix.d.ts.map +1 -0
  249. package/build/types/utils/audioProcessing.d.ts +24 -0
  250. package/build/types/utils/audioProcessing.d.ts.map +1 -0
  251. package/build/types/utils/cleanNativeOptions.d.ts +15 -0
  252. package/build/types/utils/cleanNativeOptions.d.ts.map +1 -0
  253. package/build/types/utils/concatenateBuffers.d.ts +8 -0
  254. package/build/types/utils/concatenateBuffers.d.ts.map +1 -0
  255. package/build/types/utils/convertPCMToFloat32.d.ts +13 -0
  256. package/build/types/utils/convertPCMToFloat32.d.ts.map +1 -0
  257. package/build/types/utils/crc32.d.ts +7 -0
  258. package/build/types/utils/crc32.d.ts.map +1 -0
  259. package/build/types/utils/encodingToBitDepth.d.ts +5 -0
  260. package/build/types/utils/encodingToBitDepth.d.ts.map +1 -0
  261. package/build/types/utils/getWavFileInfo.d.ts +26 -0
  262. package/build/types/utils/getWavFileInfo.d.ts.map +1 -0
  263. package/build/types/utils/writeWavHeader.d.ts +34 -0
  264. package/build/types/utils/writeWavHeader.d.ts.map +1 -0
  265. package/build/types/workers/InlineFeaturesExtractor.web.d.ts +2 -0
  266. package/build/types/workers/InlineFeaturesExtractor.web.d.ts.map +1 -0
  267. package/build/types/workers/inlineAudioWebWorker.web.d.ts +2 -0
  268. package/build/types/workers/inlineAudioWebWorker.web.d.ts.map +1 -0
  269. package/build/types/workers/wasmGlueString.web.d.ts +2 -0
  270. package/build/types/workers/wasmGlueString.web.d.ts.map +1 -0
  271. package/cpp/AudioFeatures.cpp +274 -0
  272. package/cpp/AudioFeatures.h +85 -0
  273. package/cpp/AudioFeaturesBridge.cpp +146 -0
  274. package/cpp/AudioFeaturesBridge.h +47 -0
  275. package/cpp/MelSpectrogram.cpp +227 -0
  276. package/cpp/MelSpectrogram.h +82 -0
  277. package/cpp/MelSpectrogramBridge.cpp +112 -0
  278. package/cpp/MelSpectrogramBridge.h +33 -0
  279. package/cpp/kiss_fft/COPYING +11 -0
  280. package/cpp/kiss_fft/_kiss_fft_guts.h +167 -0
  281. package/cpp/kiss_fft/kiss_fft.c +424 -0
  282. package/cpp/kiss_fft/kiss_fft.h +160 -0
  283. package/cpp/kiss_fft/kiss_fft_log.h +36 -0
  284. package/cpp/kiss_fft/kiss_fftr.c +155 -0
  285. package/cpp/kiss_fft/kiss_fftr.h +54 -0
  286. package/expo-module.config.json +10 -0
  287. package/ios/AudioAnalysisData.swift +74 -0
  288. package/ios/AudioDeviceManager.swift +670 -0
  289. package/ios/AudioFeaturesWrapper.h +21 -0
  290. package/ios/AudioFeaturesWrapper.mm +63 -0
  291. package/ios/AudioNotificationManager.swift +154 -0
  292. package/ios/AudioProcessingHelpers.swift +797 -0
  293. package/ios/AudioProcessor.swift +1191 -0
  294. package/ios/AudioStreamError.swift +7 -0
  295. package/ios/AudioStreamManager.swift +2369 -0
  296. package/ios/AudioStreamManagerDelegate.swift +16 -0
  297. package/ios/AudioStudio.podspec +39 -0
  298. package/ios/AudioStudioModule.swift +1111 -0
  299. package/ios/AudioStudioTests/AudioFileHandlerTests.swift +338 -0
  300. package/ios/AudioStudioTests/AudioFormatUtilsTests.swift +331 -0
  301. package/ios/AudioStudioTests/AudioTestHelpers.swift +130 -0
  302. package/ios/AudioStudioTests/CompressedOnlyOutputTests.swift +294 -0
  303. package/ios/AudioStudioTests/EventEmissionIntervalTests.swift +105 -0
  304. package/ios/AudioStudioTests/Info.plist +22 -0
  305. package/ios/AudioStudioTests/README.md +39 -0
  306. package/ios/AudioStudioTests/SimpleAudioTest.swift +98 -0
  307. package/ios/AudioStudioTests/TestAudioGenerator.swift +75 -0
  308. package/ios/DataPoint.swift +54 -0
  309. package/ios/DecodingConfig.swift +59 -0
  310. package/ios/FFT.swift +62 -0
  311. package/ios/Features.swift +95 -0
  312. package/ios/ISSUE_IOS.md +68 -0
  313. package/ios/Logger.swift +39 -0
  314. package/ios/MelSpectrogramWrapper.h +30 -0
  315. package/ios/MelSpectrogramWrapper.mm +97 -0
  316. package/ios/NotificationExtension.swift +15 -0
  317. package/ios/RecordingResult.swift +22 -0
  318. package/ios/RecordingSettings.swift +311 -0
  319. package/ios/WaveformExtractor.swift +105 -0
  320. package/ios/tests/README.md +41 -0
  321. package/ios/tests/integration/buffer_and_fallback_test.swift +178 -0
  322. package/ios/tests/integration/buffer_duration_test.swift +185 -0
  323. package/ios/tests/integration/compressed_only_output_test.swift +271 -0
  324. package/ios/tests/integration/output_control_test.swift +322 -0
  325. package/ios/tests/integration/run_integration_tests.sh +37 -0
  326. package/ios/tests/opus_support_test_macos.swift +154 -0
  327. package/ios/tests/standalone/audio_processing_test.swift +144 -0
  328. package/ios/tests/standalone/audio_recording_test.swift +277 -0
  329. package/ios/tests/standalone/audio_streaming_test.swift +249 -0
  330. package/ios/tests/standalone/standalone_test.swift +144 -0
  331. package/package.json +146 -0
  332. package/plugin/build/index.cjs +194 -0
  333. package/plugin/build/index.d.cts +22 -0
  334. package/plugin/build/index.js +194 -0
  335. package/plugin/src/index.ts +285 -0
  336. package/plugin/tsconfig.json +10 -0
  337. package/plugin/tsconfig.tsbuildinfo +1 -0
  338. package/prebuilt/wasm/mel-spectrogram.js +18 -0
  339. package/src/AudioAnalysis/AudioAnalysis.types.ts +226 -0
  340. package/src/AudioAnalysis/audio-features-wasm.d.ts +37 -0
  341. package/src/AudioAnalysis/audioFeaturesWasm.ts +200 -0
  342. package/src/AudioAnalysis/extractAudioAnalysis.ts +350 -0
  343. package/src/AudioAnalysis/extractAudioData.ts +17 -0
  344. package/src/AudioAnalysis/extractMelSpectrogram.ts +140 -0
  345. package/src/AudioAnalysis/extractPreview.ts +34 -0
  346. package/src/AudioAnalysis/extractWaveform.ts +22 -0
  347. package/src/AudioAnalysis/mel-spectrogram-wasm.d.ts +48 -0
  348. package/src/AudioAnalysis/melSpectrogramWasm.ts +179 -0
  349. package/src/AudioDeviceManager.ts +800 -0
  350. package/src/AudioRecorder.provider.tsx +57 -0
  351. package/src/AudioStudio.native.ts +6 -0
  352. package/src/AudioStudio.types.ts +899 -0
  353. package/src/AudioStudio.web.ts +911 -0
  354. package/src/AudioStudioModule.ts +984 -0
  355. package/src/WebRecorder.web.ts +1114 -0
  356. package/src/constants/platformLimitations.ts +118 -0
  357. package/src/constants.ts +21 -0
  358. package/src/events.ts +63 -0
  359. package/src/hooks/useAudioDevices.ts +213 -0
  360. package/src/index.ts +67 -0
  361. package/src/trimAudio.ts +94 -0
  362. package/src/types/crc-32.d.ts +9 -0
  363. package/src/useAudioRecorder.tsx +784 -0
  364. package/src/utils/BlobFix.ts +561 -0
  365. package/src/utils/audioProcessing.ts +205 -0
  366. package/src/utils/cleanNativeOptions.ts +18 -0
  367. package/src/utils/concatenateBuffers.ts +24 -0
  368. package/src/utils/convertPCMToFloat32.ts +170 -0
  369. package/src/utils/crc32.ts +59 -0
  370. package/src/utils/encodingToBitDepth.ts +18 -0
  371. package/src/utils/getWavFileInfo.ts +132 -0
  372. package/src/utils/writeWavHeader.ts +115 -0
  373. package/src/workers/InlineFeaturesExtractor.web.tsx +291 -0
  374. package/src/workers/inlineAudioWebWorker.web.tsx +186 -0
  375. package/src/workers/wasmGlueString.web.ts +23 -0
package/README.md ADDED
@@ -0,0 +1,167 @@
1
+ # @siteed/audio-studio
2
+
3
+ [![Version](https://img.shields.io/npm/v/@siteed/audio-studio.svg)](https://www.npmjs.com/package/@siteed/audio-studio)
4
+ [![Downloads](https://img.shields.io/npm/dt/@siteed/audio-studio.svg)](https://www.npmjs.com/package/@siteed/audio-studio)
5
+ [![License](https://img.shields.io/npm/l/@siteed/audio-studio.svg)](https://www.npmjs.com/package/@siteed/audio-studio)
6
+ [![GitHub stars](https://img.shields.io/github/stars/deeeed/audiolab.svg?style=social&label=Star)](https://github.com/deeeed/audiolab)
7
+
8
+ **Give it a GitHub star, if you found this repo useful.**
9
+
10
+ Cross-platform audio recording, analysis, and processing for React Native and Expo. Mel spectrogram and spectral feature extraction run through a shared C++ layer on iOS, Android, and web (via WASM).
11
+
12
+ > Formerly `@siteed/expo-audio-studio`. See [MIGRATION.md](../../MIGRATION.md) for upgrade steps.
13
+
14
+ <div align="center">
15
+ <div style="display: flex; justify-content: center; gap: 20px; margin: 30px 0;">
16
+ <div>
17
+ <h3>iOS</h3>
18
+ <img src="../../docs/ios.gif" alt="iOS Demo" width="280" />
19
+ </div>
20
+ <div>
21
+ <h3>Android</h3>
22
+ <img src="../../docs/android.gif" alt="Android Demo" width="280" />
23
+ </div>
24
+ </div>
25
+
26
+ <p>
27
+ <a href="https://apps.apple.com/app/audio-playground/id6739774966">
28
+ <img src="https://developer.apple.com/app-store/marketing/guidelines/images/badge-download-on-the-app-store.svg" alt="App Store" height="40" />
29
+ </a>
30
+ <a href="https://play.google.com/store/apps/details?id=net.siteed.audioplayground">
31
+ <img src="https://play.google.com/intl/en_us/badges/static/images/badges/en_badge_web_generic.png" alt="Google Play" height="40" />
32
+ </a>
33
+ </p>
34
+ <p><a href="https://deeeed.github.io/audiolab/playground">Try the web demo</a></p>
35
+ </div>
36
+
37
+ ## Features
38
+
39
+ - **Recording** — real-time streaming, dual-stream (raw PCM + compressed), background recording, zero-latency start via `prepareRecording`
40
+ - **Device management** — list/select input devices (Bluetooth, USB, wired), automatic fallback
41
+ - **Interruption handling** — auto pause/resume during phone calls
42
+ - **Audio analysis** — MFCC, spectral features, mel spectrogram, tempo, pitch, waveform preview
43
+ - **Native performance** — mel spectrogram and FFT-based features (MFCC, spectral centroid, etc.) computed in shared C++ on all platforms (JNI on Android, Obj-C++ bridge on iOS, WASM on web)
44
+ - **Trimming** — precision cut with multi-segment support (keep or remove ranges)
45
+ - **Notifications** — Android live waveform in notification, iOS media player integration
46
+ - **Consistent format** — WAV PCM output across all platforms
47
+
48
+ ## Install
49
+
50
+ ```bash
51
+ yarn add @siteed/audio-studio
52
+ ```
53
+
54
+ ## Quick Start
55
+
56
+ ```typescript
57
+ import { useAudioRecorder } from '@siteed/audio-studio';
58
+
59
+ const { startRecording, stopRecording, isRecording } = useAudioRecorder();
60
+
61
+ // Record
62
+ await startRecording({
63
+ sampleRate: 44100,
64
+ channels: 1,
65
+ encoding: 'pcm_16bit',
66
+ });
67
+
68
+ // ... later
69
+ const result = await stopRecording();
70
+ console.log('Saved to:', result.fileUri);
71
+ ```
72
+
73
+ ### Zero-Latency Recording
74
+
75
+ Pre-initialize to eliminate startup delay:
76
+
77
+ ```typescript
78
+ const { prepareRecording, startRecording, stopRecording } = useSharedAudioRecorder();
79
+
80
+ await prepareRecording({ sampleRate: 44100, channels: 1, encoding: 'pcm_16bit' });
81
+
82
+ // Later — starts instantly
83
+ await startRecording();
84
+ ```
85
+
86
+ ### Shared State Across Components
87
+
88
+ ```typescript
89
+ const AudioApp = () => (
90
+ <AudioRecorderProvider>
91
+ <RecordButton />
92
+ <AudioVisualizer />
93
+ </AudioRecorderProvider>
94
+ );
95
+ ```
96
+
97
+ ### Float32 Streaming (for ML / DSP)
98
+
99
+ Set `streamFormat: 'float32'` to get `Float32Array` on all platforms instead of base64:
100
+
101
+ ```typescript
102
+ await startRecording({
103
+ sampleRate: 16000,
104
+ channels: 1,
105
+ encoding: 'pcm_32bit',
106
+ streamFormat: 'float32',
107
+ onAudioStream: async (event) => {
108
+ const samples = event.data as Float32Array;
109
+ await myModel.feed(samples);
110
+ },
111
+ });
112
+ ```
113
+
114
+ ## Audio Analysis
115
+
116
+ ```typescript
117
+ import { extractAudioAnalysis, extractPreview, extractMelSpectrogram, trimAudio } from '@siteed/audio-studio';
118
+
119
+ // Feature extraction
120
+ const analysis = await extractAudioAnalysis({
121
+ fileUri: 'path/to/recording.wav',
122
+ features: { rms: true, zcr: true, mfcc: true, spectralCentroid: true }
123
+ });
124
+
125
+ // Lightweight waveform for visualization
126
+ const preview = await extractPreview({
127
+ fileUri: 'path/to/recording.wav',
128
+ pointsPerSecond: 50
129
+ });
130
+
131
+ // Mel spectrogram for ML
132
+ const mel = await extractMelSpectrogram({
133
+ fileUri: 'path/to/recording.wav',
134
+ nMels: 40, hopLengthMs: 10
135
+ });
136
+
137
+ // Trim audio
138
+ const trimmed = await trimAudio({
139
+ fileUri: 'path/to/recording.wav',
140
+ ranges: [{ startTimeMs: 1000, endTimeMs: 5000 }],
141
+ mode: 'keep'
142
+ });
143
+ ```
144
+
145
+ ### Which Method to Use
146
+
147
+ | Method | Cost | Use case |
148
+ |--------|------|----------|
149
+ | `extractPreview` | Light | Waveform visualization |
150
+ | `extractRawWavAnalysis` | Light | WAV metadata without decoding |
151
+ | `extractAudioData` | Medium | Raw PCM for custom processing |
152
+ | `extractAudioAnalysis` | Medium-Heavy | MFCC, spectral features, pitch, tempo |
153
+ | `extractMelSpectrogram` | Heavy | Frequency-domain for ML |
154
+
155
+ ## Docs
156
+
157
+ - [Getting Started Guide](https://deeeed.github.io/audiolab/docs/)
158
+ - [Contributing](./CONTRIBUTE.md)
159
+ - [AudioPlayground](https://deeeed.github.io/audiolab/playground) — live demo of all features
160
+ - [@siteed/expo-audio-ui](https://github.com/deeeed/audiolab/tree/main/packages/expo-audio-ui) — waveform, spectrogram, and audio control components
161
+
162
+ ## License
163
+
164
+ MIT — see [LICENSE](LICENSE).
165
+
166
+ ---
167
+ <sub>Created by [Arthur Breton](https://siteed.net)</sub>
@@ -0,0 +1,143 @@
1
+ apply plugin: 'com.android.library'
2
+ apply plugin: 'kotlin-android'
3
+ apply plugin: 'maven-publish'
4
+
5
+ group = 'net.siteed.audiostudio'
6
+ version = '0.1.0'
7
+
8
+ // These properties prevent plugin conflicts in all Expo versions
9
+ project.ext.isLibrary = true
10
+ project.ext.preventPluginConflict = true
11
+
12
+ buildscript {
13
+ def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
14
+ if (expoModulesCorePlugin.exists()) {
15
+ apply from: expoModulesCorePlugin
16
+ applyKotlinExpoModulesCorePlugin()
17
+ }
18
+
19
+ // Simple helper that allows the root project to override versions declared by this library.
20
+ ext.safeExtGet = { prop, fallback ->
21
+ rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
22
+ }
23
+
24
+ // Ensures backward compatibility
25
+ ext.getKotlinVersion = {
26
+ if (ext.has("kotlinVersion")) {
27
+ ext.kotlinVersion()
28
+ } else {
29
+ ext.safeExtGet("kotlinVersion", "1.8.10")
30
+ }
31
+ }
32
+
33
+ repositories {
34
+ mavenCentral()
35
+ google()
36
+ }
37
+
38
+ dependencies {
39
+ classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${getKotlinVersion()}")
40
+ }
41
+ }
42
+
43
+ afterEvaluate {
44
+ publishing {
45
+ publications {
46
+ release(MavenPublication) {
47
+ from components.release
48
+ }
49
+ }
50
+ repositories {
51
+ maven {
52
+ url = mavenLocal().url
53
+ }
54
+ }
55
+ }
56
+ }
57
+
58
+ android {
59
+ compileSdkVersion safeExtGet("compileSdkVersion", 34)
60
+
61
+ def agpVersion = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION
62
+ if (agpVersion.tokenize('.')[0].toInteger() < 8) {
63
+ compileOptions {
64
+ sourceCompatibility JavaVersion.VERSION_17
65
+ targetCompatibility JavaVersion.VERSION_17
66
+ }
67
+
68
+ tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
69
+ kotlinOptions {
70
+ jvmTarget = '17'
71
+ }
72
+ }
73
+ }
74
+
75
+ ndkVersion safeExtGet("ndkVersion", "27.1.12297006")
76
+
77
+ namespace "net.siteed.audiostudio"
78
+ defaultConfig {
79
+ minSdkVersion safeExtGet("minSdkVersion", 21)
80
+ targetSdkVersion safeExtGet("targetSdkVersion", 34)
81
+ versionCode 1
82
+ versionName "0.1.0"
83
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
84
+ externalNativeBuild {
85
+ cmake {
86
+ cppFlags "-frtti -fexceptions -Wall"
87
+ arguments "-DANDROID_STL=c++_shared"
88
+ abiFilters "x86", "x86_64", "arm64-v8a"
89
+ }
90
+ }
91
+ }
92
+ externalNativeBuild {
93
+ cmake {
94
+ path "src/main/CMakeLists.txt"
95
+ }
96
+ }
97
+ lintOptions {
98
+ abortOnError false
99
+ }
100
+ publishing {
101
+ singleVariant("release") {
102
+ withSourcesJar()
103
+ }
104
+ }
105
+ }
106
+
107
+ repositories {
108
+ mavenCentral()
109
+ google()
110
+ }
111
+
112
+ dependencies {
113
+ implementation project(':expo-modules-core')
114
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getKotlinVersion()}"
115
+
116
+ // Add AndroidX dependencies
117
+ implementation 'androidx.core:core-ktx:1.10.1'
118
+ implementation 'androidx.annotation:annotation:1.6.0'
119
+ implementation 'androidx.appcompat:appcompat:1.6.1'
120
+
121
+ // Add Kotlinx Coroutines for main code
122
+ implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3'
123
+ implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'
124
+
125
+ // Add testing dependencies
126
+ testImplementation 'junit:junit:4.13.2'
127
+ testImplementation 'org.jetbrains.kotlin:kotlin-test:1.8.10'
128
+ testImplementation 'org.jetbrains.kotlin:kotlin-test-junit:1.8.10'
129
+
130
+ // Add Android instrumented test dependencies
131
+ androidTestImplementation 'androidx.test:runner:1.5.2'
132
+ androidTestImplementation 'androidx.test.ext:junit:1.1.5'
133
+ androidTestImplementation 'androidx.test:core:1.5.0'
134
+ androidTestImplementation 'junit:junit:4.13.2'
135
+ androidTestImplementation 'androidx.test:rules:1.5.0'
136
+ androidTestImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3'
137
+ }
138
+
139
+ kotlin {
140
+ jvmToolchain {
141
+ languageVersion.set(JavaLanguageVersion.of(17))
142
+ }
143
+ }
@@ -0,0 +1,197 @@
1
+ package net.siteed.audiostudio
2
+
3
+ import androidx.test.ext.junit.runners.AndroidJUnit4
4
+ import androidx.test.platform.app.InstrumentationRegistry
5
+ import org.junit.Test
6
+ import org.junit.Assert.*
7
+ import org.junit.Before
8
+ import org.junit.After
9
+ import org.junit.runner.RunWith
10
+ import java.io.File
11
+ import kotlin.math.abs
12
+
13
+ /**
14
+ * Instrumented tests for AudioProcessor that require Android framework components.
15
+ * These tests run on an Android device/emulator and have access to MediaExtractor/MediaCodec.
16
+ */
17
+ @RunWith(AndroidJUnit4::class)
18
+ class AudioProcessorInstrumentedTest {
19
+ private lateinit var context: android.content.Context
20
+ private lateinit var audioProcessor: AudioProcessor
21
+ private lateinit var testFilesDir: File
22
+
23
+ @Before
24
+ fun setUp() {
25
+ context = InstrumentationRegistry.getInstrumentation().targetContext
26
+ testFilesDir = context.filesDir
27
+ audioProcessor = AudioProcessor(testFilesDir)
28
+
29
+ // Copy test assets to files directory
30
+ copyTestAssets()
31
+ }
32
+
33
+ @After
34
+ fun tearDown() {
35
+ // Clean up test files
36
+ testFilesDir.listFiles()?.forEach { file ->
37
+ if (file.name.endsWith(".wav")) {
38
+ file.delete()
39
+ }
40
+ }
41
+ }
42
+
43
+ private fun copyTestAssets() {
44
+ val assetManager = context.assets
45
+ val testFiles = listOf("jfk.wav", "chorus.wav", "recorder_hello_world.wav")
46
+
47
+ testFiles.forEach { fileName ->
48
+ try {
49
+ assetManager.open(fileName).use { input ->
50
+ File(testFilesDir, fileName).outputStream().use { output ->
51
+ input.copyTo(output)
52
+ }
53
+ }
54
+ } catch (e: Exception) {
55
+ // If asset doesn't exist, skip it
56
+ println("Warning: Test asset $fileName not found")
57
+ }
58
+ }
59
+ }
60
+
61
+ // ========== Audio Loading Tests ==========
62
+
63
+ @Test
64
+ fun testLoadAudioFromAnyFormat_loadsWavFile() {
65
+ // Given
66
+ val wavFile = File(testFilesDir, "jfk.wav")
67
+ assertTrue("Test file should exist", wavFile.exists())
68
+
69
+ // When
70
+ val audioData = audioProcessor.loadAudioFromAnyFormat(wavFile.absolutePath, null)
71
+
72
+ // Then
73
+ assertNotNull("Audio data should not be null", audioData)
74
+ assertEquals("Sample rate should be 16000", 16000, audioData!!.sampleRate)
75
+ assertEquals("Should be mono", 1, audioData.channels)
76
+ assertEquals("Should be 16-bit", 16, audioData.bitDepth)
77
+ assertTrue("Should have audio data", audioData.data.isNotEmpty())
78
+ assertTrue("Duration should be positive", audioData.durationMs > 0)
79
+ }
80
+
81
+ @Test
82
+ fun testLoadAudioFromAnyFormat_withDecodingConfig() {
83
+ // Given
84
+ val wavFile = File(testFilesDir, "jfk.wav")
85
+ val config = DecodingConfig(
86
+ targetSampleRate = 44100,
87
+ targetChannels = 2, // Test channel conversion - bug fixed
88
+ targetBitDepth = 16,
89
+ normalizeAudio = false
90
+ )
91
+
92
+ // When
93
+ val audioData = audioProcessor.loadAudioFromAnyFormat(wavFile.absolutePath, config)
94
+
95
+ // Then
96
+ assertNotNull("Audio data should not be null", audioData)
97
+ assertEquals("Sample rate should be converted to 44100", 44100, audioData!!.sampleRate)
98
+ assertEquals("Should be converted to stereo", 2, audioData.channels)
99
+ }
100
+
101
+ // ========== Audio Trimming Tests ==========
102
+
103
+ @Test
104
+ fun testTrimAudio_basicTrimming() {
105
+ // Given
106
+ val wavFile = File(testFilesDir, "jfk.wav")
107
+ val startTimeMs = 1000L
108
+ val endTimeMs = 3000L
109
+
110
+ // When
111
+ val trimmedAudio = audioProcessor.trimAudio(
112
+ fileUri = wavFile.absolutePath,
113
+ startTimeMs = startTimeMs,
114
+ endTimeMs = endTimeMs,
115
+ config = null,
116
+ outputFileName = "trimmed_jfk.wav"
117
+ )
118
+
119
+ // Then
120
+ assertNotNull("Trimmed audio should not be null", trimmedAudio)
121
+
122
+ // Verify the trimmed file was created
123
+ val trimmedFile = File(testFilesDir, "trimmed_jfk.wav")
124
+ assertTrue("Trimmed file should exist", trimmedFile.exists())
125
+ }
126
+
127
+ // ========== Mel Spectrogram Tests ==========
128
+
129
+ @Test
130
+ fun testExtractMelSpectrogram_basicGeneration() {
131
+ // Given
132
+ val wavFile = File(testFilesDir, "jfk.wav")
133
+ val audioData = audioProcessor.loadAudioFromAnyFormat(wavFile.absolutePath, null)
134
+ assertNotNull("Audio data should load", audioData)
135
+
136
+ // When
137
+ val melSpectrogram = audioProcessor.extractMelSpectrogram(
138
+ audioData = audioData!!,
139
+ windowSizeMs = 25f,
140
+ hopLengthMs = 10f,
141
+ nMels = 40,
142
+ fftLength = 512
143
+ )
144
+
145
+ // Then
146
+ assertNotNull("Mel spectrogram should not be null", melSpectrogram)
147
+ assertTrue("Should have time frames", melSpectrogram.spectrogram.isNotEmpty())
148
+ assertEquals("Should have 40 mel bins", 40, melSpectrogram.spectrogram[0].size)
149
+
150
+ // Verify timestamps
151
+ assertTrue("Should have timestamps", melSpectrogram.timeStamps.isNotEmpty())
152
+ assertEquals("Timestamps should match frames",
153
+ melSpectrogram.spectrogram.size, melSpectrogram.timeStamps.size)
154
+
155
+ // Verify frequencies
156
+ assertEquals("Should have 40 frequency bins", 40, melSpectrogram.frequencies.size)
157
+ assertTrue("Frequencies should be ascending",
158
+ melSpectrogram.frequencies.zip(melSpectrogram.frequencies.drop(1))
159
+ .all { (a, b) -> a < b })
160
+ }
161
+
162
+ // ========== Preview Generation Tests ==========
163
+
164
+ @Test
165
+ fun testGeneratePreview_basicPreview() {
166
+ // Given
167
+ val wavFile = File(testFilesDir, "chorus.wav")
168
+ val audioData = audioProcessor.loadAudioFromAnyFormat(wavFile.absolutePath, null)
169
+ assertNotNull("Audio data should load", audioData)
170
+
171
+ val config = RecordingConfig(
172
+ sampleRate = audioData!!.sampleRate,
173
+ channels = audioData.channels,
174
+ encoding = "pcm_16bit",
175
+ segmentDurationMs = 20 // 50 points per second
176
+ )
177
+
178
+ // When
179
+ val preview = audioProcessor.generatePreview(
180
+ audioData = audioData,
181
+ numberOfPoints = 100,
182
+ startTimeMs = null,
183
+ endTimeMs = null,
184
+ config = config
185
+ )
186
+
187
+ // Then
188
+ assertNotNull("Preview should not be null", preview)
189
+ assertEquals("Should have 100 data points", 100, preview.dataPoints.size)
190
+
191
+ // Verify amplitude range
192
+ assertTrue("Min amplitude should be reasonable", preview.amplitudeRange.min >= 0)
193
+ assertTrue("Max amplitude should be reasonable", preview.amplitudeRange.max <= 1)
194
+ assertTrue("Max should be greater than min",
195
+ preview.amplitudeRange.max > preview.amplitudeRange.min)
196
+ }
197
+ }