loukai-app 0.3.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 (290) hide show
  1. package/README.md +558 -0
  2. package/bin/loukai.js +32 -0
  3. package/package.json +243 -0
  4. package/src/main/appState.js +250 -0
  5. package/src/main/audioEngine.js +478 -0
  6. package/src/main/creator/conversionService.js +503 -0
  7. package/src/main/creator/downloadManager.js +1128 -0
  8. package/src/main/creator/ffmpegService.js +487 -0
  9. package/src/main/creator/installLogger.js +51 -0
  10. package/src/main/creator/keyDetection.js +212 -0
  11. package/src/main/creator/llmService.js +370 -0
  12. package/src/main/creator/lrclibService.js +340 -0
  13. package/src/main/creator/python/crepe_runner.py +189 -0
  14. package/src/main/creator/python/demucs_runner.py +158 -0
  15. package/src/main/creator/python/whisper_runner.py +172 -0
  16. package/src/main/creator/pythonRunner.js +268 -0
  17. package/src/main/creator/stemBuilder.js +491 -0
  18. package/src/main/creator/systemChecker.js +474 -0
  19. package/src/main/handlers/appHandlers.js +45 -0
  20. package/src/main/handlers/audioHandlers.js +33 -0
  21. package/src/main/handlers/autotuneHandlers.js +28 -0
  22. package/src/main/handlers/canvasHandlers.js +84 -0
  23. package/src/main/handlers/creatorHandlers.js +159 -0
  24. package/src/main/handlers/editorHandlers.js +98 -0
  25. package/src/main/handlers/effectsHandlers.js +100 -0
  26. package/src/main/handlers/fileHandlers.js +45 -0
  27. package/src/main/handlers/index.js +78 -0
  28. package/src/main/handlers/libraryHandlers.js +96 -0
  29. package/src/main/handlers/mixerHandlers.js +64 -0
  30. package/src/main/handlers/playerHandlers.js +39 -0
  31. package/src/main/handlers/preferencesHandlers.js +46 -0
  32. package/src/main/handlers/queueHandlers.js +81 -0
  33. package/src/main/handlers/rendererHandlers.js +63 -0
  34. package/src/main/handlers/settingsHandlers.js +42 -0
  35. package/src/main/handlers/webServerHandlers.js +105 -0
  36. package/src/main/main.js +2351 -0
  37. package/src/main/preload.js +252 -0
  38. package/src/main/settingsManager.js +139 -0
  39. package/src/main/statePersistence.js +193 -0
  40. package/src/main/utils/pathValidator.js +112 -0
  41. package/src/main/webServer.js +2535 -0
  42. package/src/native/autotune.js +417 -0
  43. package/src/renderer/adapters/ElectronBridge.js +677 -0
  44. package/src/renderer/canvas.html +80 -0
  45. package/src/renderer/components/App.jsx +303 -0
  46. package/src/renderer/components/AppRoot.jsx +37 -0
  47. package/src/renderer/components/AudioDeviceSettings.jsx +145 -0
  48. package/src/renderer/components/EffectsPanelWrapper.jsx +267 -0
  49. package/src/renderer/components/MixerTab.jsx +233 -0
  50. package/src/renderer/components/MixerTabWrapper.jsx +31 -0
  51. package/src/renderer/components/PortalSelect.jsx +239 -0
  52. package/src/renderer/components/QueueTab.jsx +116 -0
  53. package/src/renderer/components/RequestsListWrapper.jsx +78 -0
  54. package/src/renderer/components/ServerTab.jsx +472 -0
  55. package/src/renderer/components/SongInfoBarWrapper.jsx +77 -0
  56. package/src/renderer/components/StatusBar.jsx +92 -0
  57. package/src/renderer/components/TabNavigation.jsx +77 -0
  58. package/src/renderer/components/TransportControlsWrapper.jsx +69 -0
  59. package/src/renderer/components/creator/CreateTab.jsx +1236 -0
  60. package/src/renderer/dist/assets/kaiPlayer-CoMx__a_.js +2 -0
  61. package/src/renderer/dist/assets/kaiPlayer-CoMx__a_.js.map +1 -0
  62. package/src/renderer/dist/assets/microphoneEngine-BaCUhhQc.js +2 -0
  63. package/src/renderer/dist/assets/microphoneEngine-BaCUhhQc.js.map +1 -0
  64. package/src/renderer/dist/assets/player-DVrqp7N5.js +3 -0
  65. package/src/renderer/dist/assets/player-DVrqp7N5.js.map +1 -0
  66. package/src/renderer/dist/assets/songLoaders-BaTgGib4.js +2 -0
  67. package/src/renderer/dist/assets/songLoaders-BaTgGib4.js.map +1 -0
  68. package/src/renderer/dist/assets/webrtcManager-BhCHWceK.js +2 -0
  69. package/src/renderer/dist/assets/webrtcManager-BhCHWceK.js.map +1 -0
  70. package/src/renderer/dist/js/autoTuneWorklet.js +224 -0
  71. package/src/renderer/dist/js/micPitchDetectorWorklet.js +137 -0
  72. package/src/renderer/dist/js/musicAnalysisWorklet.js +216 -0
  73. package/src/renderer/dist/js/phaseVocoderWorklet.js +341 -0
  74. package/src/renderer/dist/js/soundtouch-worklet.js +1395 -0
  75. package/src/renderer/dist/renderer.css +1 -0
  76. package/src/renderer/dist/renderer.js +62 -0
  77. package/src/renderer/dist/renderer.js.map +1 -0
  78. package/src/renderer/dist/renderer.woff2 +0 -0
  79. package/src/renderer/hooks/useKeyboardShortcuts.js +154 -0
  80. package/src/renderer/index.html +24 -0
  81. package/src/renderer/index.html.backup +372 -0
  82. package/src/renderer/js/PlayerInterface.js +267 -0
  83. package/src/renderer/js/autoTuneWorklet.js +224 -0
  84. package/src/renderer/js/butterchurnVerify.js +46 -0
  85. package/src/renderer/js/canvas-app.js +114 -0
  86. package/src/renderer/js/cdgPlayer.js +685 -0
  87. package/src/renderer/js/kaiPlayer.js +1200 -0
  88. package/src/renderer/js/karaokeRenderer.js +3392 -0
  89. package/src/renderer/js/micPitchDetectorWorklet.js +137 -0
  90. package/src/renderer/js/microphoneEngine.js +656 -0
  91. package/src/renderer/js/musicAnalysisWorklet.js +216 -0
  92. package/src/renderer/js/phaseVocoderWorklet.js +341 -0
  93. package/src/renderer/js/player.js +232 -0
  94. package/src/renderer/js/referencePitchTracker.js +130 -0
  95. package/src/renderer/js/songLoaders.js +334 -0
  96. package/src/renderer/js/soundtouch-worklet.js +1395 -0
  97. package/src/renderer/js/webrtcManager.js +511 -0
  98. package/src/renderer/lib/butterchurn.min.js +6739 -0
  99. package/src/renderer/lib/butterchurnPresets.min.js +1 -0
  100. package/src/renderer/lib/cdgraphics-wrapper.js +16 -0
  101. package/src/renderer/lib/cdgraphics.js +299 -0
  102. package/src/renderer/public/js/autoTuneWorklet.js +224 -0
  103. package/src/renderer/public/js/micPitchDetectorWorklet.js +137 -0
  104. package/src/renderer/public/js/musicAnalysisWorklet.js +216 -0
  105. package/src/renderer/public/js/phaseVocoderWorklet.js +341 -0
  106. package/src/renderer/public/js/soundtouch-worklet.js +1395 -0
  107. package/src/renderer/react-entry.jsx +44 -0
  108. package/src/renderer/styles/tailwind.css +106 -0
  109. package/src/renderer/utils/qrCodeGenerator.js +98 -0
  110. package/src/renderer/vite.config.js +31 -0
  111. package/src/shared/adapters/BridgeInterface.js +195 -0
  112. package/src/shared/components/EffectsPanel.jsx +177 -0
  113. package/src/shared/components/LibraryPanel.jsx +701 -0
  114. package/src/shared/components/LineDetailCanvas.jsx +167 -0
  115. package/src/shared/components/LyricLine.jsx +505 -0
  116. package/src/shared/components/LyricRejection.jsx +84 -0
  117. package/src/shared/components/LyricSuggestion.jsx +80 -0
  118. package/src/shared/components/LyricsEditorCanvas.jsx +271 -0
  119. package/src/shared/components/MixerPanel.jsx +94 -0
  120. package/src/shared/components/PlayerControls.jsx +206 -0
  121. package/src/shared/components/PortalSelect.jsx +239 -0
  122. package/src/shared/components/QueueList.jsx +365 -0
  123. package/src/shared/components/QuickSearch.jsx +126 -0
  124. package/src/shared/components/RequestsList.jsx +121 -0
  125. package/src/shared/components/SongEditor.jsx +1362 -0
  126. package/src/shared/components/SongInfoBar.jsx +81 -0
  127. package/src/shared/components/ThemeToggle.jsx +106 -0
  128. package/src/shared/components/Toast.jsx +30 -0
  129. package/src/shared/components/VisualizationSettings.jsx +243 -0
  130. package/src/shared/constants.js +95 -0
  131. package/src/shared/context/BridgeContext.jsx +32 -0
  132. package/src/shared/contexts/AudioContext.jsx +37 -0
  133. package/src/shared/contexts/PlayerContext.jsx +66 -0
  134. package/src/shared/contexts/SettingsContext.jsx +50 -0
  135. package/src/shared/defaults.js +158 -0
  136. package/src/shared/formatUtils.js +59 -0
  137. package/src/shared/formatUtils.test.js +207 -0
  138. package/src/shared/hooks/useAppState.js +97 -0
  139. package/src/shared/hooks/useAudioEngine.js +264 -0
  140. package/src/shared/hooks/usePlayer.js +89 -0
  141. package/src/shared/hooks/useSettingsPersistence.js +74 -0
  142. package/src/shared/hooks/useWebRTC.js +118 -0
  143. package/src/shared/ipcContracts.js +299 -0
  144. package/src/shared/package.json +3 -0
  145. package/src/shared/services/creatorService.js +373 -0
  146. package/src/shared/services/creatorService.test.js +413 -0
  147. package/src/shared/services/editorService.js +213 -0
  148. package/src/shared/services/editorService.test.js +219 -0
  149. package/src/shared/services/effectsService.js +271 -0
  150. package/src/shared/services/effectsService.test.js +418 -0
  151. package/src/shared/services/libraryService.js +438 -0
  152. package/src/shared/services/libraryService.test.js +474 -0
  153. package/src/shared/services/mixerService.js +172 -0
  154. package/src/shared/services/mixerService.test.js +399 -0
  155. package/src/shared/services/playerService.js +221 -0
  156. package/src/shared/services/playerService.test.js +357 -0
  157. package/src/shared/services/preferencesService.js +219 -0
  158. package/src/shared/services/queueService.js +226 -0
  159. package/src/shared/services/queueService.test.js +430 -0
  160. package/src/shared/services/requestsService.js +155 -0
  161. package/src/shared/services/requestsService.test.js +362 -0
  162. package/src/shared/services/serverSettingsService.js +151 -0
  163. package/src/shared/services/settingsService.js +257 -0
  164. package/src/shared/services/settingsService.test.js +295 -0
  165. package/src/shared/state/StateManager.js +263 -0
  166. package/src/shared/utils/audio.js +42 -0
  167. package/src/shared/utils/format.js +32 -0
  168. package/src/shared/utils/lyricsUtils.js +162 -0
  169. package/src/test/setup.js +40 -0
  170. package/src/utils/cdgLoader.js +180 -0
  171. package/src/utils/m4aLoader.js +333 -0
  172. package/src/web/App.jsx +578 -0
  173. package/src/web/adapters/WebBridge.js +428 -0
  174. package/src/web/components/PlayerSettingsPanel.jsx +231 -0
  175. package/src/web/components/SongSearch.jsx +180 -0
  176. package/src/web/dist/assets/index-0H-RnRrV.js +51 -0
  177. package/src/web/dist/assets/index-0H-RnRrV.js.map +1 -0
  178. package/src/web/dist/assets/index-DYW2zB0u.css +1 -0
  179. package/src/web/dist/index.html +15 -0
  180. package/src/web/index.html +14 -0
  181. package/src/web/main.jsx +10 -0
  182. package/src/web/package-lock.json +1765 -0
  183. package/src/web/pages/SongRequestPage.jsx +619 -0
  184. package/src/web/styles/tailwind.css +68 -0
  185. package/src/web/vite.config.js +27 -0
  186. package/static/fonts/material-icons.woff2 +0 -0
  187. package/static/images/butterchurn-screenshots/Aderrasi - Potion of Spirits.png +0 -0
  188. package/static/images/butterchurn-screenshots/Aderrasi - Songflower _Moss Posy_.png +0 -0
  189. package/static/images/butterchurn-screenshots/Aderrasi - Storm of the Eye _Thunder_ - mash0000 - quasi pseudo meta concentrics.png +0 -0
  190. package/static/images/butterchurn-screenshots/Aderrasi _ Geiss - Airhandler _Kali Mix_ - Canvas Mix.png +0 -0
  191. package/static/images/butterchurn-screenshots/An AdamFX n Martin Infusion 2 flexi - Why The Sky Looks Diffrent Today - AdamFx n Martin Infusion - Tack Tile Disfunction B.png +0 -0
  192. package/static/images/butterchurn-screenshots/Cope - The Neverending Explosion of Red Liquid Fire.png +0 -0
  193. proton lights __Krash_s beat code_ _Phat_remix02b.png +0 -0
  194. package/static/images/butterchurn-screenshots/Eo_S_ _ Phat - cubetrace - v2.png +0 -0
  195. package/static/images/butterchurn-screenshots/Eo_S_ _ Zylot - skylight _Stained Glass Majesty mix_.png +0 -0
  196. package/static/images/butterchurn-screenshots/Flexi - alien fish pond.png +0 -0
  197. package/static/images/butterchurn-screenshots/Flexi - area 51.png +0 -0
  198. package/static/images/butterchurn-screenshots/Flexi - infused with the spiral.png +0 -0
  199. package/static/images/butterchurn-screenshots/Flexi - mindblob _shiny mix_.png +0 -0
  200. package/static/images/butterchurn-screenshots/Flexi - mindblob mix.png +0 -0
  201. package/static/images/butterchurn-screenshots/Flexi - predator-prey-spirals.png +0 -0
  202. package/static/images/butterchurn-screenshots/Flexi - smashing fractals _acid etching mix_.png +0 -0
  203. package/static/images/butterchurn-screenshots/Flexi - truly soft piece of software - this is generic texturing _Jelly_ .png +0 -0
  204. package/static/images/butterchurn-screenshots/Flexi _ Martin - astral projection.png +0 -0
  205. package/static/images/butterchurn-screenshots/Flexi _ Martin - cascading decay swing.png +0 -0
  206. package/static/images/butterchurn-screenshots/Flexi _ amandio c - piercing 05 - Kopie _2_ - Kopie.png +0 -0
  207. package/static/images/butterchurn-screenshots/Flexi _ stahlregen - jelly showoff parade.png +0 -0
  208. package/static/images/butterchurn-screenshots/Flexi_ fishbrain_ Geiss _ Martin - tokamak witchery.png +0 -0
  209. package/static/images/butterchurn-screenshots/Flexi_ martin _ geiss - dedicated to the sherwin maxawow.png +0 -0
  210. package/static/images/butterchurn-screenshots/Fumbling_Foo _ Flexi_ Martin_ Orb_ Unchained - Star Nova v7b.png +0 -0
  211. package/static/images/butterchurn-screenshots/Geiss - Cauldron - painterly 2 _saturation remix_.png +0 -0
  212. package/static/images/butterchurn-screenshots/Geiss - Reaction Diffusion 2.png +0 -0
  213. package/static/images/butterchurn-screenshots/Geiss - Spiral Artifact.png +0 -0
  214. package/static/images/butterchurn-screenshots/Geiss - Thumb Drum.png +0 -0
  215. package/static/images/butterchurn-screenshots/Geiss _ Flexi _ Martin - disconnected.png +0 -0
  216. package/static/images/butterchurn-screenshots/Geiss_ Flexi _ Stahlregen - Thumbdrum Tokamak _crossfiring aftermath jelly mashup_.png +0 -0
  217. package/static/images/butterchurn-screenshots/Goody - The Wild Vort.png +0 -0
  218. package/static/images/butterchurn-screenshots/Idiot - Star Of Annon.png +0 -0
  219. package/static/images/butterchurn-screenshots/Krash _ Illusion - Spiral Movement.png +0 -0
  220. package/static/images/butterchurn-screenshots/Martin - QBikal - Surface Turbulence IIb.png +0 -0
  221. package/static/images/butterchurn-screenshots/Martin - acid wiring.png +0 -0
  222. package/static/images/butterchurn-screenshots/Martin - charisma.png +0 -0
  223. package/static/images/butterchurn-screenshots/Martin - liquid arrows.png +0 -0
  224. package/static/images/butterchurn-screenshots/Milk Artist At our Best - FED - SlowFast Ft AdamFX n Martin - HD CosmoFX.png +0 -0
  225. package/static/images/butterchurn-screenshots/ORB - Waaa.png +0 -0
  226. package/static/images/butterchurn-screenshots/Phat_fiShbRaiN_Eo_S_Mandala_Chasers_remix.png +0 -0
  227. package/static/images/butterchurn-screenshots/Rovastar - Oozing Resistance.png +0 -0
  228. package/static/images/butterchurn-screenshots/Rovastar _ Loadus _ Geiss - FractalDrop _Triple Mix_.png +0 -0
  229. package/static/images/butterchurn-screenshots/TonyMilkdrop - Leonardo Da Vinci_s Balloon _Flexi - merry-go-round _ techstyle_.png +0 -0
  230. package/static/images/butterchurn-screenshots/TonyMilkdrop - Magellan_s Nebula _Flexi - you enter first _ multiverse_.png +0 -0
  231. package/static/images/butterchurn-screenshots/Unchained - Rewop.png +0 -0
  232. package/static/images/butterchurn-screenshots/Unchained - Unified Drag 2.png +0 -0
  233. package/static/images/butterchurn-screenshots/Unchained _ Rovastar - Wormhole Pillars _Hall of Shadows mix_.png +0 -0
  234. package/static/images/butterchurn-screenshots/Zylot - Paint Spill _Music Reactive Paint Mix_.png +0 -0
  235. package/static/images/butterchurn-screenshots/Zylot - Star Ornament.png +0 -0
  236. package/static/images/butterchurn-screenshots/Zylot - True Visionary _Final Mix_.png +0 -0
  237. package/static/images/butterchurn-screenshots/_Aderrasi - Wanderer in Curved Space - mash0000 - faclempt kibitzing meshuggana schmaltz _Geiss color mix_.png +0 -0
  238. package/static/images/butterchurn-screenshots/_Geiss - Artifact 01.png +0 -0
  239. package/static/images/butterchurn-screenshots/_Geiss - Desert Rose 2.png +0 -0
  240. package/static/images/butterchurn-screenshots/_Geiss - untitled.png +0 -0
  241. package/static/images/butterchurn-screenshots/_Mig_049.png +0 -0
  242. package/static/images/butterchurn-screenshots/_Mig_085.png +0 -0
  243. package/static/images/butterchurn-screenshots/_Rovastar _ Geiss - Hurricane Nightmare _Posterize Mix_.png +0 -0
  244. package/static/images/butterchurn-screenshots/___ Royal - Mashup _197_.png +0 -0
  245. package/static/images/butterchurn-screenshots/___ Royal - Mashup _220_.png +0 -0
  246. package/static/images/butterchurn-screenshots/___ Royal - Mashup _431_.png +0 -0
  247. package/static/images/butterchurn-screenshots/cope _ martin - mother-of-pearl.png +0 -0
  248. package/static/images/butterchurn-screenshots/fiShbRaiN _ Flexi - witchcraft 2_0.png +0 -0
  249. package/static/images/butterchurn-screenshots/flexi - bouncing balls _double mindblob neon mix_.png +0 -0
  250. package/static/images/butterchurn-screenshots/flexi - mom_ why the sky looks different today.png +0 -0
  251. package/static/images/butterchurn-screenshots/flexi - patternton_ district of media_ capitol of the united abstractions of fractopia.png +0 -0
  252. package/static/images/butterchurn-screenshots/flexi - swing out on the spiral.png +0 -0
  253. package/static/images/butterchurn-screenshots/flexi - what is the matrix.png +0 -0
  254. package/static/images/butterchurn-screenshots/flexi _ amandio c - organic _random mashup_.png +0 -0
  255. package/static/images/butterchurn-screenshots/flexi _ amandio c - organic12-3d-2_milk.png +0 -0
  256. package/static/images/butterchurn-screenshots/flexi _ fishbrain - neon mindblob grafitti.png +0 -0
  257. package/static/images/butterchurn-screenshots/flexi _ geiss - pogo cubes vs_ tokamak vs_ game of life _stahls jelly 4_5 finish_.png +0 -0
  258. package/static/images/butterchurn-screenshots/high-altitude basket unraveling - singh grooves nitrogen argon nz_.png +0 -0
  259. package/static/images/butterchurn-screenshots/martin - The Bridge of Khazad-Dum.png +0 -0
  260. package/static/images/butterchurn-screenshots/martin - angel flight.png +0 -0
  261. package/static/images/butterchurn-screenshots/martin - another kind of groove.png +0 -0
  262. package/static/images/butterchurn-screenshots/martin - bombyx mori.png +0 -0
  263. package/static/images/butterchurn-screenshots/martin - castle in the air.png +0 -0
  264. package/static/images/butterchurn-screenshots/martin - chain breaker.png +0 -0
  265. package/static/images/butterchurn-screenshots/martin - disco mix 4.png +0 -0
  266. package/static/images/butterchurn-screenshots/martin - extreme heat.png +0 -0
  267. package/static/images/butterchurn-screenshots/martin - frosty caves 2.png +0 -0
  268. package/static/images/butterchurn-screenshots/martin - fruit machine.png +0 -0
  269. package/static/images/butterchurn-screenshots/martin - ghost city.png +0 -0
  270. package/static/images/butterchurn-screenshots/martin - glass corridor.png +0 -0
  271. package/static/images/butterchurn-screenshots/martin - infinity _2010 update_.png +0 -0
  272. package/static/images/butterchurn-screenshots/martin - mandelbox explorer - high speed demo version.png +0 -0
  273. package/static/images/butterchurn-screenshots/martin - mucus cervix.png +0 -0
  274. package/static/images/butterchurn-screenshots/martin - reflections on black tiles.png +0 -0
  275. package/static/images/butterchurn-screenshots/martin - stormy sea _2010 update_.png +0 -0
  276. package/static/images/butterchurn-screenshots/martin - witchcraft reloaded.png +0 -0
  277. package/static/images/butterchurn-screenshots/martin _ flexi - diamond cutter _prismaticvortex_com_ - camille - i wish i wish i wish i was constrained.png +0 -0
  278. package/static/images/butterchurn-screenshots/martin _shadow harlequins shape code_ - fata morgana.png +0 -0
  279. package/static/images/butterchurn-screenshots/martin_ flexi_ fishbrain _ sto - enterstate _random mashup_.png +0 -0
  280. package/static/images/butterchurn-screenshots/sawtooth grin roam.png +0 -0
  281. package/static/images/butterchurn-screenshots/shifter - dark tides bdrv mix 2.png +0 -0
  282. package/static/images/butterchurn-screenshots/suksma - Rovastar - Sunflower Passion _Enlightment Mix__Phat_edit _ flexi und martin shaders - circumflex in character classes in regular expression.png +0 -0
  283. package/static/images/butterchurn-screenshots/suksma - heretical crosscut playpen.png +0 -0
  284. package/static/images/butterchurn-screenshots/suksma - uninitialized variabowl _hydroponic chronic_.png +0 -0
  285. package/static/images/butterchurn-screenshots/suksma - vector exp 1 - couldn_t not.png +0 -0
  286. package/static/images/butterchurn-screenshots/yin - 191 - Temporal singularities.png +0 -0
  287. package/static/images/logo-512.png +0 -0
  288. package/static/images/logo.png +0 -0
  289. package/static/loukai-logo.png +0 -0
  290. package/static/screenshot-generator.html +610 -0
@@ -0,0 +1,1395 @@
1
+ /*
2
+ * SoundTouch Audio Worklet v0.2.1 AudioWorklet using the
3
+ * SoundTouch audio processing library
4
+ *
5
+ * Copyright (c) Olli Parviainen
6
+ * Copyright (c) Ryan Berdeen
7
+ * Copyright (c) Jakub Fiala
8
+ * Copyright (c) Steve 'Cutter' Blades
9
+ *
10
+ * This library is free software; you can redistribute it and/or
11
+ * modify it under the terms of the GNU Lesser General Public
12
+ * License as published by the Free Software Foundation; either
13
+ * version 2.1 of the License, or (at your option) any later version.
14
+ *
15
+ * This library is distributed in the hope that it will be useful,
16
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18
+ * Lesser General Public License for more details.
19
+ *
20
+ * You should have received a copy of the GNU Lesser General Public
21
+ * License along with this library; if not, write to the Free Software
22
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23
+ */
24
+
25
+ 'use strict';
26
+
27
+ function _assertThisInitialized(e) {
28
+ if (void 0 === e)
29
+ throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
30
+ return e;
31
+ }
32
+ function _callSuper(t, o, e) {
33
+ return (
34
+ (o = _getPrototypeOf(o)),
35
+ _possibleConstructorReturn(
36
+ t,
37
+ _isNativeReflectConstruct()
38
+ ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor)
39
+ : o.apply(t, e)
40
+ )
41
+ );
42
+ }
43
+ function _classCallCheck(a, n) {
44
+ if (!(a instanceof n)) throw new TypeError('Cannot call a class as a function');
45
+ }
46
+ function _construct(t, e, r) {
47
+ if (_isNativeReflectConstruct()) return Reflect.construct.apply(null, arguments);
48
+ var o = [null];
49
+ o.push.apply(o, e);
50
+ var p = new (t.bind.apply(t, o))();
51
+ return (r && _setPrototypeOf(p, r.prototype), p);
52
+ }
53
+ function _defineProperties(e, r) {
54
+ for (var t = 0; t < r.length; t++) {
55
+ var o = r[t];
56
+ ((o.enumerable = o.enumerable || false),
57
+ (o.configurable = true),
58
+ 'value' in o && (o.writable = true),
59
+ Object.defineProperty(e, _toPropertyKey(o.key), o));
60
+ }
61
+ }
62
+ function _createClass(e, r, t) {
63
+ return (
64
+ r && _defineProperties(e.prototype, r),
65
+ t && _defineProperties(e, t),
66
+ Object.defineProperty(e, 'prototype', {
67
+ writable: false,
68
+ }),
69
+ e
70
+ );
71
+ }
72
+ function _get() {
73
+ return (
74
+ (_get =
75
+ 'undefined' != typeof Reflect && Reflect.get
76
+ ? Reflect.get.bind()
77
+ : function (e, t, r) {
78
+ var p = _superPropBase(e, t);
79
+ if (p) {
80
+ var n = Object.getOwnPropertyDescriptor(p, t);
81
+ return n.get ? n.get.call(arguments.length < 3 ? e : r) : n.value;
82
+ }
83
+ }),
84
+ _get.apply(null, arguments)
85
+ );
86
+ }
87
+ function _getPrototypeOf(t) {
88
+ return (
89
+ (_getPrototypeOf = Object.setPrototypeOf
90
+ ? Object.getPrototypeOf.bind()
91
+ : function (t) {
92
+ return t.__proto__ || Object.getPrototypeOf(t);
93
+ }),
94
+ _getPrototypeOf(t)
95
+ );
96
+ }
97
+ function _inherits(t, e) {
98
+ if ('function' != typeof e && null !== e)
99
+ throw new TypeError('Super expression must either be null or a function');
100
+ ((t.prototype = Object.create(e && e.prototype, {
101
+ constructor: {
102
+ value: t,
103
+ writable: true,
104
+ configurable: true,
105
+ },
106
+ })),
107
+ Object.defineProperty(t, 'prototype', {
108
+ writable: false,
109
+ }),
110
+ e && _setPrototypeOf(t, e));
111
+ }
112
+ function _isNativeFunction(t) {
113
+ try {
114
+ return -1 !== Function.toString.call(t).indexOf('[native code]');
115
+ } catch (n) {
116
+ return 'function' == typeof t;
117
+ }
118
+ }
119
+ function _isNativeReflectConstruct() {
120
+ try {
121
+ var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
122
+ } catch (t) {}
123
+ return (_isNativeReflectConstruct = function () {
124
+ return !!t;
125
+ })();
126
+ }
127
+ function _possibleConstructorReturn(t, e) {
128
+ if (e && ('object' == typeof e || 'function' == typeof e)) return e;
129
+ if (void 0 !== e) throw new TypeError('Derived constructors may only return object or undefined');
130
+ return _assertThisInitialized(t);
131
+ }
132
+ function _setPrototypeOf(t, e) {
133
+ return (
134
+ (_setPrototypeOf = Object.setPrototypeOf
135
+ ? Object.setPrototypeOf.bind()
136
+ : function (t, e) {
137
+ return ((t.__proto__ = e), t);
138
+ }),
139
+ _setPrototypeOf(t, e)
140
+ );
141
+ }
142
+ function _superPropBase(t, o) {
143
+ for (; !{}.hasOwnProperty.call(t, o) && null !== (t = _getPrototypeOf(t)); );
144
+ return t;
145
+ }
146
+ function _superPropGet(t, o, e, r) {
147
+ var p = _get(_getPrototypeOf(t.prototype), o, e);
148
+ return 'function' == typeof p
149
+ ? function (t) {
150
+ return p.apply(e, t);
151
+ }
152
+ : p;
153
+ }
154
+ function _toPrimitive(t, r) {
155
+ if ('object' != typeof t || !t) return t;
156
+ var e = t[Symbol.toPrimitive];
157
+ if (void 0 !== e) {
158
+ var i = e.call(t, r);
159
+ if ('object' != typeof i) return i;
160
+ throw new TypeError('@@toPrimitive must return a primitive value.');
161
+ }
162
+ return String(t);
163
+ }
164
+ function _toPropertyKey(t) {
165
+ var i = _toPrimitive(t, 'string');
166
+ return 'symbol' == typeof i ? i : i + '';
167
+ }
168
+ function _wrapNativeSuper(t) {
169
+ var r = 'function' == typeof Map ? new Map() : void 0;
170
+ return (
171
+ (_wrapNativeSuper = function (t) {
172
+ if (null === t || !_isNativeFunction(t)) return t;
173
+ if ('function' != typeof t)
174
+ throw new TypeError('Super expression must either be null or a function');
175
+ if (void 0 !== r) {
176
+ if (r.has(t)) return r.get(t);
177
+ r.set(t, Wrapper);
178
+ }
179
+ function Wrapper() {
180
+ return _construct(t, arguments, _getPrototypeOf(this).constructor);
181
+ }
182
+ return (
183
+ (Wrapper.prototype = Object.create(t.prototype, {
184
+ constructor: {
185
+ value: Wrapper,
186
+ enumerable: false,
187
+ writable: true,
188
+ configurable: true,
189
+ },
190
+ })),
191
+ _setPrototypeOf(Wrapper, t)
192
+ );
193
+ }),
194
+ _wrapNativeSuper(t)
195
+ );
196
+ }
197
+
198
+ var FifoSampleBuffer = (function () {
199
+ function FifoSampleBuffer() {
200
+ _classCallCheck(this, FifoSampleBuffer);
201
+ this._vector = new Float32Array();
202
+ this._position = 0;
203
+ this._frameCount = 0;
204
+ }
205
+ return _createClass(FifoSampleBuffer, [
206
+ {
207
+ key: 'vector',
208
+ get: function get() {
209
+ return this._vector;
210
+ },
211
+ },
212
+ {
213
+ key: 'position',
214
+ get: function get() {
215
+ return this._position;
216
+ },
217
+ },
218
+ {
219
+ key: 'startIndex',
220
+ get: function get() {
221
+ return this._position * 2;
222
+ },
223
+ },
224
+ {
225
+ key: 'frameCount',
226
+ get: function get() {
227
+ return this._frameCount;
228
+ },
229
+ },
230
+ {
231
+ key: 'endIndex',
232
+ get: function get() {
233
+ return (this._position + this._frameCount) * 2;
234
+ },
235
+ },
236
+ {
237
+ key: 'clear',
238
+ value: function clear() {
239
+ this.receive(this._frameCount);
240
+ this.rewind();
241
+ },
242
+ },
243
+ {
244
+ key: 'put',
245
+ value: function put(numFrames) {
246
+ this._frameCount += numFrames;
247
+ },
248
+ },
249
+ {
250
+ key: 'putSamples',
251
+ value: function putSamples(samples, position) {
252
+ var numFrames = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
253
+ position = position || 0;
254
+ var sourceOffset = position * 2;
255
+ if (!(numFrames >= 0)) {
256
+ numFrames = (samples.length - sourceOffset) / 2;
257
+ }
258
+ var numSamples = numFrames * 2;
259
+ this.ensureCapacity(numFrames + this._frameCount);
260
+ var destOffset = this.endIndex;
261
+ this.vector.set(samples.subarray(sourceOffset, sourceOffset + numSamples), destOffset);
262
+ this._frameCount += numFrames;
263
+ },
264
+ },
265
+ {
266
+ key: 'putBuffer',
267
+ value: function putBuffer(buffer, position) {
268
+ var numFrames = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
269
+ position = position || 0;
270
+ if (!(numFrames >= 0)) {
271
+ numFrames = buffer.frameCount - position;
272
+ }
273
+ this.putSamples(buffer.vector, buffer.position + position, numFrames);
274
+ },
275
+ },
276
+ {
277
+ key: 'receive',
278
+ value: function receive(numFrames) {
279
+ if (!(numFrames >= 0) || numFrames > this._frameCount) {
280
+ numFrames = this.frameCount;
281
+ }
282
+ this._frameCount -= numFrames;
283
+ this._position += numFrames;
284
+ },
285
+ },
286
+ {
287
+ key: 'receiveSamples',
288
+ value: function receiveSamples(output) {
289
+ var numFrames = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
290
+ var numSamples = numFrames * 2;
291
+ var sourceOffset = this.startIndex;
292
+ output.set(this._vector.subarray(sourceOffset, sourceOffset + numSamples));
293
+ this.receive(numFrames);
294
+ },
295
+ },
296
+ {
297
+ key: 'extract',
298
+ value: function extract(output) {
299
+ var position = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
300
+ var numFrames = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
301
+ var sourceOffset = this.startIndex + position * 2;
302
+ var numSamples = numFrames * 2;
303
+ output.set(this._vector.subarray(sourceOffset, sourceOffset + numSamples));
304
+ },
305
+ },
306
+ {
307
+ key: 'ensureCapacity',
308
+ value: function ensureCapacity() {
309
+ var numFrames = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
310
+ var minLength = parseInt(numFrames * 2);
311
+ if (this._vector.length < minLength) {
312
+ var newVector = new Float32Array(minLength);
313
+ newVector.set(this._vector.subarray(this.startIndex, this.endIndex));
314
+ this._vector = newVector;
315
+ this._position = 0;
316
+ } else {
317
+ this.rewind();
318
+ }
319
+ },
320
+ },
321
+ {
322
+ key: 'ensureAdditionalCapacity',
323
+ value: function ensureAdditionalCapacity() {
324
+ var numFrames = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
325
+ this.ensureCapacity(this._frameCount + numFrames);
326
+ },
327
+ },
328
+ {
329
+ key: 'rewind',
330
+ value: function rewind() {
331
+ if (this._position > 0) {
332
+ this._vector.set(this._vector.subarray(this.startIndex, this.endIndex));
333
+ this._position = 0;
334
+ }
335
+ },
336
+ },
337
+ ]);
338
+ })();
339
+ var AbstractFifoSamplePipe = (function () {
340
+ function AbstractFifoSamplePipe(createBuffers) {
341
+ _classCallCheck(this, AbstractFifoSamplePipe);
342
+ if (createBuffers) {
343
+ this._inputBuffer = new FifoSampleBuffer();
344
+ this._outputBuffer = new FifoSampleBuffer();
345
+ } else {
346
+ this._inputBuffer = this._outputBuffer = null;
347
+ }
348
+ }
349
+ return _createClass(AbstractFifoSamplePipe, [
350
+ {
351
+ key: 'inputBuffer',
352
+ get: function get() {
353
+ return this._inputBuffer;
354
+ },
355
+ set: function set(inputBuffer) {
356
+ this._inputBuffer = inputBuffer;
357
+ },
358
+ },
359
+ {
360
+ key: 'outputBuffer',
361
+ get: function get() {
362
+ return this._outputBuffer;
363
+ },
364
+ set: function set(outputBuffer) {
365
+ this._outputBuffer = outputBuffer;
366
+ },
367
+ },
368
+ {
369
+ key: 'clear',
370
+ value: function clear() {
371
+ this._inputBuffer.clear();
372
+ this._outputBuffer.clear();
373
+ },
374
+ },
375
+ ]);
376
+ })();
377
+ var RateTransposer = (function (_AbstractFifoSamplePi) {
378
+ function RateTransposer(createBuffers) {
379
+ var _this;
380
+ _classCallCheck(this, RateTransposer);
381
+ _this = _callSuper(this, RateTransposer, [createBuffers]);
382
+ _this.reset();
383
+ _this._rate = 1;
384
+ return _this;
385
+ }
386
+ _inherits(RateTransposer, _AbstractFifoSamplePi);
387
+ return _createClass(RateTransposer, [
388
+ {
389
+ key: 'rate',
390
+ set: function set(rate) {
391
+ this._rate = rate;
392
+ },
393
+ },
394
+ {
395
+ key: 'reset',
396
+ value: function reset() {
397
+ this.slopeCount = 0;
398
+ this.prevSampleL = 0;
399
+ this.prevSampleR = 0;
400
+ },
401
+ },
402
+ {
403
+ key: 'clone',
404
+ value: function clone() {
405
+ var result = new RateTransposer();
406
+ result.rate = this._rate;
407
+ return result;
408
+ },
409
+ },
410
+ {
411
+ key: 'process',
412
+ value: function process() {
413
+ var numFrames = this._inputBuffer.frameCount;
414
+ this._outputBuffer.ensureAdditionalCapacity(numFrames / this._rate + 1);
415
+ var numFramesOutput = this.transpose(numFrames);
416
+ this._inputBuffer.receive();
417
+ this._outputBuffer.put(numFramesOutput);
418
+ },
419
+ },
420
+ {
421
+ key: 'transpose',
422
+ value: function transpose() {
423
+ var numFrames = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
424
+ if (numFrames === 0) {
425
+ return 0;
426
+ }
427
+ var src = this._inputBuffer.vector;
428
+ var srcOffset = this._inputBuffer.startIndex;
429
+ var dest = this._outputBuffer.vector;
430
+ var destOffset = this._outputBuffer.endIndex;
431
+ var used = 0;
432
+ var i = 0;
433
+ while (this.slopeCount < 1.0) {
434
+ dest[destOffset + 2 * i] =
435
+ (1.0 - this.slopeCount) * this.prevSampleL + this.slopeCount * src[srcOffset];
436
+ dest[destOffset + 2 * i + 1] =
437
+ (1.0 - this.slopeCount) * this.prevSampleR + this.slopeCount * src[srcOffset + 1];
438
+ i = i + 1;
439
+ this.slopeCount += this._rate;
440
+ }
441
+ this.slopeCount -= 1.0;
442
+ if (numFrames !== 1) {
443
+ out: while (true) {
444
+ while (this.slopeCount > 1.0) {
445
+ this.slopeCount -= 1.0;
446
+ used = used + 1;
447
+ if (used >= numFrames - 1) {
448
+ break out;
449
+ }
450
+ }
451
+ var srcIndex = srcOffset + 2 * used;
452
+ dest[destOffset + 2 * i] =
453
+ (1.0 - this.slopeCount) * src[srcIndex] + this.slopeCount * src[srcIndex + 2];
454
+ dest[destOffset + 2 * i + 1] =
455
+ (1.0 - this.slopeCount) * src[srcIndex + 1] + this.slopeCount * src[srcIndex + 3];
456
+ i = i + 1;
457
+ this.slopeCount += this._rate;
458
+ }
459
+ }
460
+ this.prevSampleL = src[srcOffset + 2 * numFrames - 2];
461
+ this.prevSampleR = src[srcOffset + 2 * numFrames - 1];
462
+ return i;
463
+ },
464
+ },
465
+ ]);
466
+ })(AbstractFifoSamplePipe);
467
+ var FilterSupport = (function () {
468
+ function FilterSupport(pipe) {
469
+ _classCallCheck(this, FilterSupport);
470
+ this._pipe = pipe;
471
+ }
472
+ return _createClass(FilterSupport, [
473
+ {
474
+ key: 'pipe',
475
+ get: function get() {
476
+ return this._pipe;
477
+ },
478
+ },
479
+ {
480
+ key: 'inputBuffer',
481
+ get: function get() {
482
+ return this._pipe.inputBuffer;
483
+ },
484
+ },
485
+ {
486
+ key: 'outputBuffer',
487
+ get: function get() {
488
+ return this._pipe.outputBuffer;
489
+ },
490
+ },
491
+ {
492
+ key: 'fillInputBuffer',
493
+ value: function fillInputBuffer() {
494
+ throw new Error('fillInputBuffer() not overridden');
495
+ },
496
+ },
497
+ {
498
+ key: 'fillOutputBuffer',
499
+ value: function fillOutputBuffer() {
500
+ var numFrames = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
501
+ while (this.outputBuffer.frameCount < numFrames) {
502
+ var numInputFrames = 8192 * 2 - this.inputBuffer.frameCount;
503
+ this.fillInputBuffer(numInputFrames);
504
+ if (this.inputBuffer.frameCount < 8192 * 2) {
505
+ break;
506
+ }
507
+ this._pipe.process();
508
+ }
509
+ },
510
+ },
511
+ {
512
+ key: 'clear',
513
+ value: function clear() {
514
+ this._pipe.clear();
515
+ },
516
+ },
517
+ ]);
518
+ })();
519
+ var noop = function noop() {
520
+ return;
521
+ };
522
+ var SimpleFilter = (function (_FilterSupport) {
523
+ function SimpleFilter(sourceSound, pipe) {
524
+ var _this2;
525
+ var callback = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : noop;
526
+ _classCallCheck(this, SimpleFilter);
527
+ _this2 = _callSuper(this, SimpleFilter, [pipe]);
528
+ _this2.callback = callback;
529
+ _this2.sourceSound = sourceSound;
530
+ _this2.historyBufferSize = 22050;
531
+ _this2._sourcePosition = 0;
532
+ _this2.outputBufferPosition = 0;
533
+ _this2._position = 0;
534
+ return _this2;
535
+ }
536
+ _inherits(SimpleFilter, _FilterSupport);
537
+ return _createClass(SimpleFilter, [
538
+ {
539
+ key: 'position',
540
+ get: function get() {
541
+ return this._position;
542
+ },
543
+ set: function set(position) {
544
+ if (position > this._position) {
545
+ throw new RangeError('New position may not be greater than current position');
546
+ }
547
+ var newOutputBufferPosition = this.outputBufferPosition - (this._position - position);
548
+ if (newOutputBufferPosition < 0) {
549
+ throw new RangeError('New position falls outside of history buffer');
550
+ }
551
+ this.outputBufferPosition = newOutputBufferPosition;
552
+ this._position = position;
553
+ },
554
+ },
555
+ {
556
+ key: 'sourcePosition',
557
+ get: function get() {
558
+ return this._sourcePosition;
559
+ },
560
+ set: function set(sourcePosition) {
561
+ this.clear();
562
+ this._sourcePosition = sourcePosition;
563
+ },
564
+ },
565
+ {
566
+ key: 'onEnd',
567
+ value: function onEnd() {
568
+ this.callback();
569
+ },
570
+ },
571
+ {
572
+ key: 'fillInputBuffer',
573
+ value: function fillInputBuffer() {
574
+ var numFrames = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
575
+ var samples = new Float32Array(numFrames * 2);
576
+ var numFramesExtracted = this.sourceSound.extract(samples, numFrames, this._sourcePosition);
577
+ this._sourcePosition += numFramesExtracted;
578
+ this.inputBuffer.putSamples(samples, 0, numFramesExtracted);
579
+ },
580
+ },
581
+ {
582
+ key: 'extract',
583
+ value: function extract(target) {
584
+ var numFrames = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
585
+ this.fillOutputBuffer(this.outputBufferPosition + numFrames);
586
+ var numFramesExtracted = Math.min(
587
+ numFrames,
588
+ this.outputBuffer.frameCount - this.outputBufferPosition
589
+ );
590
+ this.outputBuffer.extract(target, this.outputBufferPosition, numFramesExtracted);
591
+ var currentFrames = this.outputBufferPosition + numFramesExtracted;
592
+ this.outputBufferPosition = Math.min(this.historyBufferSize, currentFrames);
593
+ this.outputBuffer.receive(Math.max(currentFrames - this.historyBufferSize, 0));
594
+ this._position += numFramesExtracted;
595
+ return numFramesExtracted;
596
+ },
597
+ },
598
+ {
599
+ key: 'handleSampleData',
600
+ value: function handleSampleData(event) {
601
+ this.extract(event.data, 4096);
602
+ },
603
+ },
604
+ {
605
+ key: 'clear',
606
+ value: function clear() {
607
+ _superPropGet(SimpleFilter, 'clear', this)([]);
608
+ this.outputBufferPosition = 0;
609
+ },
610
+ },
611
+ ]);
612
+ })(FilterSupport);
613
+ var USE_AUTO_SEQUENCE_LEN = 0;
614
+ var DEFAULT_SEQUENCE_MS = USE_AUTO_SEQUENCE_LEN;
615
+ var USE_AUTO_SEEKWINDOW_LEN = 0;
616
+ var DEFAULT_SEEKWINDOW_MS = USE_AUTO_SEEKWINDOW_LEN;
617
+ var DEFAULT_OVERLAP_MS = 8;
618
+ var _SCAN_OFFSETS = [
619
+ [
620
+ 124, 186, 248, 310, 372, 434, 496, 558, 620, 682, 744, 806, 868, 930, 992, 1054, 1116, 1178,
621
+ 1240, 1302, 1364, 1426, 1488, 0,
622
+ ],
623
+ [-100, -75, -50, -25, 25, 50, 75, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
624
+ [-20, -15, -10, -5, 5, 10, 15, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
625
+ [-4, -3, -2, -1, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
626
+ ];
627
+ var AUTOSEQ_TEMPO_LOW = 0.25;
628
+ var AUTOSEQ_TEMPO_TOP = 4.0;
629
+ var AUTOSEQ_AT_MIN = 125.0;
630
+ var AUTOSEQ_AT_MAX = 50.0;
631
+ var AUTOSEQ_K = (AUTOSEQ_AT_MAX - AUTOSEQ_AT_MIN) / (AUTOSEQ_TEMPO_TOP - AUTOSEQ_TEMPO_LOW);
632
+ var AUTOSEQ_C = AUTOSEQ_AT_MIN - AUTOSEQ_K * AUTOSEQ_TEMPO_LOW;
633
+ var AUTOSEEK_AT_MIN = 25.0;
634
+ var AUTOSEEK_AT_MAX = 15.0;
635
+ var AUTOSEEK_K = (AUTOSEEK_AT_MAX - AUTOSEEK_AT_MIN) / (AUTOSEQ_TEMPO_TOP - AUTOSEQ_TEMPO_LOW);
636
+ var AUTOSEEK_C = AUTOSEEK_AT_MIN - AUTOSEEK_K * AUTOSEQ_TEMPO_LOW;
637
+ var Stretch = (function (_AbstractFifoSamplePi2) {
638
+ function Stretch(createBuffers) {
639
+ var _this3;
640
+ _classCallCheck(this, Stretch);
641
+ _this3 = _callSuper(this, Stretch, [createBuffers]);
642
+ _this3._quickSeek = true;
643
+ _this3.midBufferDirty = false;
644
+ _this3.midBuffer = null;
645
+ _this3.overlapLength = 0;
646
+ _this3.autoSeqSetting = true;
647
+ _this3.autoSeekSetting = true;
648
+ _this3._tempo = 1;
649
+ _this3.setParameters(44100, DEFAULT_SEQUENCE_MS, DEFAULT_SEEKWINDOW_MS, DEFAULT_OVERLAP_MS);
650
+ return _this3;
651
+ }
652
+ _inherits(Stretch, _AbstractFifoSamplePi2);
653
+ return _createClass(Stretch, [
654
+ {
655
+ key: 'clear',
656
+ value: function clear() {
657
+ _superPropGet(Stretch, 'clear', this)([]);
658
+ this.clearMidBuffer();
659
+ },
660
+ },
661
+ {
662
+ key: 'clearMidBuffer',
663
+ value: function clearMidBuffer() {
664
+ if (this.midBufferDirty) {
665
+ this.midBufferDirty = false;
666
+ this.midBuffer = null;
667
+ }
668
+ },
669
+ },
670
+ {
671
+ key: 'setParameters',
672
+ value: function setParameters(sampleRate, sequenceMs, seekWindowMs, overlapMs) {
673
+ if (sampleRate > 0) {
674
+ this.sampleRate = sampleRate;
675
+ }
676
+ if (overlapMs > 0) {
677
+ this.overlapMs = overlapMs;
678
+ }
679
+ if (sequenceMs > 0) {
680
+ this.sequenceMs = sequenceMs;
681
+ this.autoSeqSetting = false;
682
+ } else {
683
+ this.autoSeqSetting = true;
684
+ }
685
+ if (seekWindowMs > 0) {
686
+ this.seekWindowMs = seekWindowMs;
687
+ this.autoSeekSetting = false;
688
+ } else {
689
+ this.autoSeekSetting = true;
690
+ }
691
+ this.calculateSequenceParameters();
692
+ this.calculateOverlapLength(this.overlapMs);
693
+ this.tempo = this._tempo;
694
+ },
695
+ },
696
+ {
697
+ key: 'tempo',
698
+ get: function get() {
699
+ return this._tempo;
700
+ },
701
+ set: function set(newTempo) {
702
+ var intskip;
703
+ this._tempo = newTempo;
704
+ this.calculateSequenceParameters();
705
+ this.nominalSkip = this._tempo * (this.seekWindowLength - this.overlapLength);
706
+ this.skipFract = 0;
707
+ intskip = Math.floor(this.nominalSkip + 0.5);
708
+ this.sampleReq =
709
+ Math.max(intskip + this.overlapLength, this.seekWindowLength) + this.seekLength;
710
+ },
711
+ },
712
+ {
713
+ key: 'inputChunkSize',
714
+ get: function get() {
715
+ return this.sampleReq;
716
+ },
717
+ },
718
+ {
719
+ key: 'outputChunkSize',
720
+ get: function get() {
721
+ return this.overlapLength + Math.max(0, this.seekWindowLength - 2 * this.overlapLength);
722
+ },
723
+ },
724
+ {
725
+ key: 'calculateOverlapLength',
726
+ value: function calculateOverlapLength() {
727
+ var overlapInMsec = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
728
+ var newOvl;
729
+ newOvl = (this.sampleRate * overlapInMsec) / 1000;
730
+ newOvl = newOvl < 16 ? 16 : newOvl;
731
+ newOvl -= newOvl % 8;
732
+ this.overlapLength = newOvl;
733
+ this.refMidBuffer = new Float32Array(this.overlapLength * 2);
734
+ this.midBuffer = new Float32Array(this.overlapLength * 2);
735
+ },
736
+ },
737
+ {
738
+ key: 'checkLimits',
739
+ value: function checkLimits(x, mi, ma) {
740
+ return x < mi ? mi : x > ma ? ma : x;
741
+ },
742
+ },
743
+ {
744
+ key: 'calculateSequenceParameters',
745
+ value: function calculateSequenceParameters() {
746
+ var seq;
747
+ var seek;
748
+ if (this.autoSeqSetting) {
749
+ seq = AUTOSEQ_C + AUTOSEQ_K * this._tempo;
750
+ seq = this.checkLimits(seq, AUTOSEQ_AT_MAX, AUTOSEQ_AT_MIN);
751
+ this.sequenceMs = Math.floor(seq + 0.5);
752
+ }
753
+ if (this.autoSeekSetting) {
754
+ seek = AUTOSEEK_C + AUTOSEEK_K * this._tempo;
755
+ seek = this.checkLimits(seek, AUTOSEEK_AT_MAX, AUTOSEEK_AT_MIN);
756
+ this.seekWindowMs = Math.floor(seek + 0.5);
757
+ }
758
+ this.seekWindowLength = Math.floor((this.sampleRate * this.sequenceMs) / 1000);
759
+ this.seekLength = Math.floor((this.sampleRate * this.seekWindowMs) / 1000);
760
+ },
761
+ },
762
+ {
763
+ key: 'quickSeek',
764
+ set: function set(enable) {
765
+ this._quickSeek = enable;
766
+ },
767
+ },
768
+ {
769
+ key: 'clone',
770
+ value: function clone() {
771
+ var result = new Stretch();
772
+ result.tempo = this._tempo;
773
+ result.setParameters(this.sampleRate, this.sequenceMs, this.seekWindowMs, this.overlapMs);
774
+ return result;
775
+ },
776
+ },
777
+ {
778
+ key: 'seekBestOverlapPosition',
779
+ value: function seekBestOverlapPosition() {
780
+ return this._quickSeek
781
+ ? this.seekBestOverlapPositionStereoQuick()
782
+ : this.seekBestOverlapPositionStereo();
783
+ },
784
+ },
785
+ {
786
+ key: 'seekBestOverlapPositionStereo',
787
+ value: function seekBestOverlapPositionStereo() {
788
+ var bestOffset;
789
+ var bestCorrelation;
790
+ var correlation;
791
+ var i = 0;
792
+ this.preCalculateCorrelationReferenceStereo();
793
+ bestOffset = 0;
794
+ bestCorrelation = Number.MIN_VALUE;
795
+ for (; i < this.seekLength; i = i + 1) {
796
+ correlation = this.calculateCrossCorrelationStereo(2 * i, this.refMidBuffer);
797
+ if (correlation > bestCorrelation) {
798
+ bestCorrelation = correlation;
799
+ bestOffset = i;
800
+ }
801
+ }
802
+ return bestOffset;
803
+ },
804
+ },
805
+ {
806
+ key: 'seekBestOverlapPositionStereoQuick',
807
+ value: function seekBestOverlapPositionStereoQuick() {
808
+ var bestOffset;
809
+ var bestCorrelation;
810
+ var correlation;
811
+ var scanCount = 0;
812
+ var correlationOffset;
813
+ var tempOffset;
814
+ this.preCalculateCorrelationReferenceStereo();
815
+ bestCorrelation = Number.MIN_VALUE;
816
+ bestOffset = 0;
817
+ correlationOffset = 0;
818
+ tempOffset = 0;
819
+ for (; scanCount < 4; scanCount = scanCount + 1) {
820
+ var j = 0;
821
+ while (_SCAN_OFFSETS[scanCount][j]) {
822
+ tempOffset = correlationOffset + _SCAN_OFFSETS[scanCount][j];
823
+ if (tempOffset >= this.seekLength) {
824
+ break;
825
+ }
826
+ correlation = this.calculateCrossCorrelationStereo(2 * tempOffset, this.refMidBuffer);
827
+ if (correlation > bestCorrelation) {
828
+ bestCorrelation = correlation;
829
+ bestOffset = tempOffset;
830
+ }
831
+ j = j + 1;
832
+ }
833
+ correlationOffset = bestOffset;
834
+ }
835
+ return bestOffset;
836
+ },
837
+ },
838
+ {
839
+ key: 'preCalculateCorrelationReferenceStereo',
840
+ value: function preCalculateCorrelationReferenceStereo() {
841
+ var i = 0;
842
+ var context;
843
+ var temp;
844
+ for (; i < this.overlapLength; i = i + 1) {
845
+ temp = i * (this.overlapLength - i);
846
+ context = i * 2;
847
+ this.refMidBuffer[context] = this.midBuffer[context] * temp;
848
+ this.refMidBuffer[context + 1] = this.midBuffer[context + 1] * temp;
849
+ }
850
+ },
851
+ },
852
+ {
853
+ key: 'calculateCrossCorrelationStereo',
854
+ value: function calculateCrossCorrelationStereo(mixingPosition, compare) {
855
+ var mixing = this._inputBuffer.vector;
856
+ mixingPosition += this._inputBuffer.startIndex;
857
+ var correlation = 0;
858
+ var i = 2;
859
+ var calcLength = 2 * this.overlapLength;
860
+ var mixingOffset;
861
+ for (; i < calcLength; i = i + 2) {
862
+ mixingOffset = i + mixingPosition;
863
+ correlation +=
864
+ mixing[mixingOffset] * compare[i] + mixing[mixingOffset + 1] * compare[i + 1];
865
+ }
866
+ return correlation;
867
+ },
868
+ },
869
+ {
870
+ key: 'overlap',
871
+ value: function overlap(overlapPosition) {
872
+ this.overlapStereo(2 * overlapPosition);
873
+ },
874
+ },
875
+ {
876
+ key: 'overlapStereo',
877
+ value: function overlapStereo(inputPosition) {
878
+ var input = this._inputBuffer.vector;
879
+ inputPosition += this._inputBuffer.startIndex;
880
+ var output = this._outputBuffer.vector;
881
+ var outputPosition = this._outputBuffer.endIndex;
882
+ var i = 0;
883
+ var context;
884
+ var tempFrame;
885
+ var frameScale = 1 / this.overlapLength;
886
+ var fi;
887
+ var inputOffset;
888
+ var outputOffset;
889
+ for (; i < this.overlapLength; i = i + 1) {
890
+ tempFrame = (this.overlapLength - i) * frameScale;
891
+ fi = i * frameScale;
892
+ context = 2 * i;
893
+ inputOffset = context + inputPosition;
894
+ outputOffset = context + outputPosition;
895
+ output[outputOffset + 0] =
896
+ input[inputOffset + 0] * fi + this.midBuffer[context + 0] * tempFrame;
897
+ output[outputOffset + 1] =
898
+ input[inputOffset + 1] * fi + this.midBuffer[context + 1] * tempFrame;
899
+ }
900
+ },
901
+ },
902
+ {
903
+ key: 'process',
904
+ value: function process() {
905
+ var offset;
906
+ var temp;
907
+ var overlapSkip;
908
+ if (this.midBuffer === null) {
909
+ if (this._inputBuffer.frameCount < this.overlapLength) {
910
+ return;
911
+ }
912
+ this.midBuffer = new Float32Array(this.overlapLength * 2);
913
+ this._inputBuffer.receiveSamples(this.midBuffer, this.overlapLength);
914
+ }
915
+ while (this._inputBuffer.frameCount >= this.sampleReq) {
916
+ offset = this.seekBestOverlapPosition();
917
+ this._outputBuffer.ensureAdditionalCapacity(this.overlapLength);
918
+ this.overlap(Math.floor(offset));
919
+ this._outputBuffer.put(this.overlapLength);
920
+ temp = this.seekWindowLength - 2 * this.overlapLength;
921
+ if (temp > 0) {
922
+ this._outputBuffer.putBuffer(this._inputBuffer, offset + this.overlapLength, temp);
923
+ }
924
+ var start =
925
+ this._inputBuffer.startIndex +
926
+ 2 * (offset + this.seekWindowLength - this.overlapLength);
927
+ this.midBuffer.set(
928
+ this._inputBuffer.vector.subarray(start, start + 2 * this.overlapLength)
929
+ );
930
+ this.skipFract += this.nominalSkip;
931
+ overlapSkip = Math.floor(this.skipFract);
932
+ this.skipFract -= overlapSkip;
933
+ this._inputBuffer.receive(overlapSkip);
934
+ }
935
+ },
936
+ },
937
+ ]);
938
+ })(AbstractFifoSamplePipe);
939
+ var testFloatEqual = function testFloatEqual(a, b) {
940
+ return (a > b ? a - b : b - a) > 1e-10;
941
+ };
942
+ var SoundTouch = (function () {
943
+ function SoundTouch() {
944
+ _classCallCheck(this, SoundTouch);
945
+ this.transposer = new RateTransposer(false);
946
+ this.stretch = new Stretch(false);
947
+ this._inputBuffer = new FifoSampleBuffer();
948
+ this._intermediateBuffer = new FifoSampleBuffer();
949
+ this._outputBuffer = new FifoSampleBuffer();
950
+ this._rate = 0;
951
+ this._tempo = 0;
952
+ this.virtualPitch = 1.0;
953
+ this.virtualRate = 1.0;
954
+ this.virtualTempo = 1.0;
955
+ this.calculateEffectiveRateAndTempo();
956
+ }
957
+ return _createClass(SoundTouch, [
958
+ {
959
+ key: 'clear',
960
+ value: function clear() {
961
+ this.transposer.clear();
962
+ this.stretch.clear();
963
+ },
964
+ },
965
+ {
966
+ key: 'clone',
967
+ value: function clone() {
968
+ var result = new SoundTouch();
969
+ result.rate = this.rate;
970
+ result.tempo = this.tempo;
971
+ return result;
972
+ },
973
+ },
974
+ {
975
+ key: 'rate',
976
+ get: function get() {
977
+ return this._rate;
978
+ },
979
+ set: function set(rate) {
980
+ this.virtualRate = rate;
981
+ this.calculateEffectiveRateAndTempo();
982
+ },
983
+ },
984
+ {
985
+ key: 'rateChange',
986
+ set: function set(rateChange) {
987
+ this._rate = 1.0 + 0.01 * rateChange;
988
+ },
989
+ },
990
+ {
991
+ key: 'tempo',
992
+ get: function get() {
993
+ return this._tempo;
994
+ },
995
+ set: function set(tempo) {
996
+ this.virtualTempo = tempo;
997
+ this.calculateEffectiveRateAndTempo();
998
+ },
999
+ },
1000
+ {
1001
+ key: 'tempoChange',
1002
+ set: function set(tempoChange) {
1003
+ this.tempo = 1.0 + 0.01 * tempoChange;
1004
+ },
1005
+ },
1006
+ {
1007
+ key: 'pitch',
1008
+ set: function set(pitch) {
1009
+ this.virtualPitch = pitch;
1010
+ this.calculateEffectiveRateAndTempo();
1011
+ },
1012
+ },
1013
+ {
1014
+ key: 'pitchOctaves',
1015
+ set: function set(pitchOctaves) {
1016
+ this.pitch = Math.exp(0.69314718056 * pitchOctaves);
1017
+ this.calculateEffectiveRateAndTempo();
1018
+ },
1019
+ },
1020
+ {
1021
+ key: 'pitchSemitones',
1022
+ set: function set(pitchSemitones) {
1023
+ this.pitchOctaves = pitchSemitones / 12.0;
1024
+ },
1025
+ },
1026
+ {
1027
+ key: 'inputBuffer',
1028
+ get: function get() {
1029
+ return this._inputBuffer;
1030
+ },
1031
+ },
1032
+ {
1033
+ key: 'outputBuffer',
1034
+ get: function get() {
1035
+ return this._outputBuffer;
1036
+ },
1037
+ },
1038
+ {
1039
+ key: 'calculateEffectiveRateAndTempo',
1040
+ value: function calculateEffectiveRateAndTempo() {
1041
+ var previousTempo = this._tempo;
1042
+ var previousRate = this._rate;
1043
+ this._tempo = this.virtualTempo / this.virtualPitch;
1044
+ this._rate = this.virtualRate * this.virtualPitch;
1045
+ if (testFloatEqual(this._tempo, previousTempo)) {
1046
+ this.stretch.tempo = this._tempo;
1047
+ }
1048
+ if (testFloatEqual(this._rate, previousRate)) {
1049
+ this.transposer.rate = this._rate;
1050
+ }
1051
+ if (this._rate > 1.0) {
1052
+ if (this._outputBuffer != this.transposer.outputBuffer) {
1053
+ this.stretch.inputBuffer = this._inputBuffer;
1054
+ this.stretch.outputBuffer = this._intermediateBuffer;
1055
+ this.transposer.inputBuffer = this._intermediateBuffer;
1056
+ this.transposer.outputBuffer = this._outputBuffer;
1057
+ }
1058
+ } else {
1059
+ if (this._outputBuffer != this.stretch.outputBuffer) {
1060
+ this.transposer.inputBuffer = this._inputBuffer;
1061
+ this.transposer.outputBuffer = this._intermediateBuffer;
1062
+ this.stretch.inputBuffer = this._intermediateBuffer;
1063
+ this.stretch.outputBuffer = this._outputBuffer;
1064
+ }
1065
+ }
1066
+ },
1067
+ },
1068
+ {
1069
+ key: 'process',
1070
+ value: function process() {
1071
+ if (this._rate > 1.0) {
1072
+ this.stretch.process();
1073
+ this.transposer.process();
1074
+ } else {
1075
+ this.transposer.process();
1076
+ this.stretch.process();
1077
+ }
1078
+ },
1079
+ },
1080
+ ]);
1081
+ })();
1082
+ var WebAudioBufferSource = (function () {
1083
+ function WebAudioBufferSource(buffer) {
1084
+ _classCallCheck(this, WebAudioBufferSource);
1085
+ this.buffer = buffer;
1086
+ this._position = 0;
1087
+ }
1088
+ return _createClass(WebAudioBufferSource, [
1089
+ {
1090
+ key: 'dualChannel',
1091
+ get: function get() {
1092
+ return this.buffer.numberOfChannels > 1;
1093
+ },
1094
+ },
1095
+ {
1096
+ key: 'position',
1097
+ get: function get() {
1098
+ return this._position;
1099
+ },
1100
+ set: function set(value) {
1101
+ this._position = value;
1102
+ },
1103
+ },
1104
+ {
1105
+ key: 'extract',
1106
+ value: function extract(target) {
1107
+ var numFrames = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
1108
+ var position = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
1109
+ this.position = position;
1110
+ var left = this.buffer.getChannelData(0);
1111
+ var right = this.dualChannel
1112
+ ? this.buffer.getChannelData(1)
1113
+ : this.buffer.getChannelData(0);
1114
+ var i = 0;
1115
+ for (; i < numFrames; i++) {
1116
+ target[i * 2] = left[i + position];
1117
+ target[i * 2 + 1] = right[i + position];
1118
+ }
1119
+ return Math.min(numFrames, left.length - position);
1120
+ },
1121
+ },
1122
+ ]);
1123
+ })();
1124
+ var getWebAudioNode = function getWebAudioNode(context, filter) {
1125
+ var sourcePositionCallback =
1126
+ arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : noop;
1127
+ var bufferSize = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 4096;
1128
+ var node = context.createScriptProcessor(bufferSize, 2, 2);
1129
+ var samples = new Float32Array(bufferSize * 2);
1130
+ node.onaudioprocess = function (event) {
1131
+ var left = event.outputBuffer.getChannelData(0);
1132
+ var right = event.outputBuffer.getChannelData(1);
1133
+ var framesExtracted = filter.extract(samples, bufferSize);
1134
+ sourcePositionCallback(filter.sourcePosition);
1135
+ if (framesExtracted === 0) {
1136
+ filter.onEnd();
1137
+ }
1138
+ var i = 0;
1139
+ for (; i < framesExtracted; i++) {
1140
+ left[i] = samples[i * 2];
1141
+ right[i] = samples[i * 2 + 1];
1142
+ }
1143
+ };
1144
+ return node;
1145
+ };
1146
+ var pad = function pad(n, width, z) {
1147
+ z = z || '0';
1148
+ n = n + '';
1149
+ return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
1150
+ };
1151
+ var minsSecs = function minsSecs(secs) {
1152
+ var mins = Math.floor(secs / 60);
1153
+ var seconds = secs - mins * 60;
1154
+ return ''.concat(mins, ':').concat(pad(parseInt(seconds), 2));
1155
+ };
1156
+ var onUpdate = function onUpdate(sourcePosition) {
1157
+ var currentTimePlayed = this.timePlayed;
1158
+ var sampleRate = this.sampleRate;
1159
+ this.sourcePosition = sourcePosition;
1160
+ this.timePlayed = sourcePosition / sampleRate;
1161
+ if (currentTimePlayed !== this.timePlayed) {
1162
+ var timePlayed = new CustomEvent('play', {
1163
+ detail: {
1164
+ timePlayed: this.timePlayed,
1165
+ formattedTimePlayed: this.formattedTimePlayed,
1166
+ percentagePlayed: this.percentagePlayed,
1167
+ },
1168
+ });
1169
+ this._node.dispatchEvent(timePlayed);
1170
+ }
1171
+ };
1172
+ (function () {
1173
+ function PitchShifter(context, buffer, bufferSize) {
1174
+ var _this4 = this;
1175
+ var onEnd = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : noop;
1176
+ _classCallCheck(this, PitchShifter);
1177
+ this._soundtouch = new SoundTouch();
1178
+ var source = new WebAudioBufferSource(buffer);
1179
+ this.timePlayed = 0;
1180
+ this.sourcePosition = 0;
1181
+ this._filter = new SimpleFilter(source, this._soundtouch, onEnd);
1182
+ this._node = getWebAudioNode(
1183
+ context,
1184
+ this._filter,
1185
+ function (sourcePostion) {
1186
+ return onUpdate.call(_this4, sourcePostion);
1187
+ },
1188
+ bufferSize
1189
+ );
1190
+ this.tempo = 1;
1191
+ this.rate = 1;
1192
+ this.duration = buffer.duration;
1193
+ this.sampleRate = context.sampleRate;
1194
+ this.listeners = [];
1195
+ }
1196
+ return _createClass(PitchShifter, [
1197
+ {
1198
+ key: 'formattedDuration',
1199
+ get: function get() {
1200
+ return minsSecs(this.duration);
1201
+ },
1202
+ },
1203
+ {
1204
+ key: 'formattedTimePlayed',
1205
+ get: function get() {
1206
+ return minsSecs(this.timePlayed);
1207
+ },
1208
+ },
1209
+ {
1210
+ key: 'percentagePlayed',
1211
+ get: function get() {
1212
+ return (100 * this._filter.sourcePosition) / (this.duration * this.sampleRate);
1213
+ },
1214
+ set: function set(perc) {
1215
+ this._filter.sourcePosition = parseInt(perc * this.duration * this.sampleRate);
1216
+ this.sourcePosition = this._filter.sourcePosition;
1217
+ this.timePlayed = this.sourcePosition / this.sampleRate;
1218
+ },
1219
+ },
1220
+ {
1221
+ key: 'node',
1222
+ get: function get() {
1223
+ return this._node;
1224
+ },
1225
+ },
1226
+ {
1227
+ key: 'pitch',
1228
+ set: function set(pitch) {
1229
+ this._soundtouch.pitch = pitch;
1230
+ },
1231
+ },
1232
+ {
1233
+ key: 'pitchSemitones',
1234
+ set: function set(semitone) {
1235
+ this._soundtouch.pitchSemitones = semitone;
1236
+ },
1237
+ },
1238
+ {
1239
+ key: 'rate',
1240
+ set: function set(rate) {
1241
+ this._soundtouch.rate = rate;
1242
+ },
1243
+ },
1244
+ {
1245
+ key: 'tempo',
1246
+ set: function set(tempo) {
1247
+ this._soundtouch.tempo = tempo;
1248
+ },
1249
+ },
1250
+ {
1251
+ key: 'connect',
1252
+ value: function connect(toNode) {
1253
+ this._node.connect(toNode);
1254
+ },
1255
+ },
1256
+ {
1257
+ key: 'disconnect',
1258
+ value: function disconnect() {
1259
+ this._node.disconnect();
1260
+ },
1261
+ },
1262
+ {
1263
+ key: 'on',
1264
+ value: function on(eventName, cb) {
1265
+ this.listeners.push({
1266
+ name: eventName,
1267
+ cb: cb,
1268
+ });
1269
+ this._node.addEventListener(eventName, function (event) {
1270
+ return cb(event.detail);
1271
+ });
1272
+ },
1273
+ },
1274
+ {
1275
+ key: 'off',
1276
+ value: function off() {
1277
+ var _this5 = this;
1278
+ var eventName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
1279
+ var listeners = this.listeners;
1280
+ if (eventName) {
1281
+ listeners = listeners.filter(function (e) {
1282
+ return e.name === eventName;
1283
+ });
1284
+ }
1285
+ listeners.forEach(function (e) {
1286
+ _this5._node.removeEventListener(e.name, function (event) {
1287
+ return e.cb(event.detail);
1288
+ });
1289
+ });
1290
+ },
1291
+ },
1292
+ ]);
1293
+ })();
1294
+
1295
+ var SoundTouchWorklet = (function (_AudioWorkletProcesso) {
1296
+ function SoundTouchWorklet() {
1297
+ var _this;
1298
+ _classCallCheck(this, SoundTouchWorklet);
1299
+ _this = _callSuper(this, SoundTouchWorklet);
1300
+ _this.bufferSize = 128;
1301
+ _this._samples = new Float32Array(_this.bufferSize * 2);
1302
+ _this._pipe = new SoundTouch();
1303
+ return _this;
1304
+ }
1305
+ _inherits(SoundTouchWorklet, _AudioWorkletProcesso);
1306
+ return _createClass(
1307
+ SoundTouchWorklet,
1308
+ [
1309
+ {
1310
+ key: 'process',
1311
+ value: function process(inputs, outputs, parameters) {
1312
+ var _parameters$rate$, _parameters$tempo$, _parameters$pitch$, _parameters$pitchSemi;
1313
+ if (!inputs[0].length) return true;
1314
+ var leftInput = inputs[0][0];
1315
+ var rightInput = inputs[0].length > 1 ? inputs[0][1] : inputs[0][0];
1316
+ var leftOutput = outputs[0][0];
1317
+ var rightOutput = outputs[0].length > 1 ? outputs[0][1] : outputs[0][0];
1318
+ var samples = this._samples;
1319
+ if (!leftOutput || !leftOutput.length) return false;
1320
+ var rate =
1321
+ (_parameters$rate$ = parameters.rate[0]) !== null && _parameters$rate$ !== void 0
1322
+ ? _parameters$rate$
1323
+ : parameters.rate;
1324
+ var tempo =
1325
+ (_parameters$tempo$ = parameters.tempo[0]) !== null && _parameters$tempo$ !== void 0
1326
+ ? _parameters$tempo$
1327
+ : parameters.tempo;
1328
+ var pitch =
1329
+ (_parameters$pitch$ = parameters.pitch[0]) !== null && _parameters$pitch$ !== void 0
1330
+ ? _parameters$pitch$
1331
+ : parameters.pitch;
1332
+ var pitchSemitones =
1333
+ (_parameters$pitchSemi = parameters.pitchSemitones[0]) !== null &&
1334
+ _parameters$pitchSemi !== void 0
1335
+ ? _parameters$pitchSemi
1336
+ : parameters.pitchSemitones;
1337
+ this._pipe.rate = rate;
1338
+ this._pipe.tempo = tempo;
1339
+ this._pipe.pitch = pitch * Math.pow(2, pitchSemitones / 12);
1340
+ for (var i = 0; i < leftInput.length; i++) {
1341
+ samples[i * 2] = leftInput[i];
1342
+ samples[i * 2 + 1] = rightInput[i];
1343
+ }
1344
+ this._pipe.inputBuffer.putSamples(samples, 0, leftInput.length);
1345
+ this._pipe.process();
1346
+ var processedSamples = new Float32Array(leftInput.length * 2);
1347
+ this._pipe.outputBuffer.receiveSamples(processedSamples, leftOutput.length);
1348
+ for (var _i = 0; _i < leftInput.length; _i++) {
1349
+ leftOutput[_i] = processedSamples[_i * 2];
1350
+ rightOutput[_i] = processedSamples[_i * 2 + 1];
1351
+ if (isNaN(leftOutput[_i]) || isNaN(rightOutput[_i])) {
1352
+ leftOutput[_i] = 0;
1353
+ rightOutput[_i] = 0;
1354
+ }
1355
+ }
1356
+ return true;
1357
+ },
1358
+ },
1359
+ ],
1360
+ [
1361
+ {
1362
+ key: 'parameterDescriptors',
1363
+ get: function get() {
1364
+ return [
1365
+ {
1366
+ name: 'rate',
1367
+ defaultValue: 1.0,
1368
+ minValue: 0.25,
1369
+ maxValue: 4.0,
1370
+ },
1371
+ {
1372
+ name: 'tempo',
1373
+ defaultValue: 1.0,
1374
+ minValue: 0.25,
1375
+ maxValue: 4.0,
1376
+ },
1377
+ {
1378
+ name: 'pitch',
1379
+ defaultValue: 1.0,
1380
+ minValue: 0.25,
1381
+ maxValue: 4.0,
1382
+ },
1383
+ {
1384
+ name: 'pitchSemitones',
1385
+ defaultValue: 0,
1386
+ minValue: -24,
1387
+ maxValue: 24,
1388
+ },
1389
+ ];
1390
+ },
1391
+ },
1392
+ ]
1393
+ );
1394
+ })(_wrapNativeSuper(AudioWorkletProcessor));
1395
+ registerProcessor('soundtouch-processor', SoundTouchWorklet);