@swf2es/player-hosts 0.0.0-stage → 0.1.1

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 (405) hide show
  1. package/LICENSE +202 -0
  2. package/LICENSE.third-party +759 -0
  3. package/README.md +43 -2
  4. package/dist/indexeddb.d.ts +27 -0
  5. package/dist/indexeddb.d.ts.map +1 -0
  6. package/dist/indexeddb.js +170 -0
  7. package/dist/indexeddb.js.map +1 -0
  8. package/dist/node-worker.d.ts +2 -0
  9. package/dist/node-worker.d.ts.map +1 -0
  10. package/dist/node-worker.js +12 -0
  11. package/dist/node-worker.js.map +1 -0
  12. package/dist/node.d.ts +8 -0
  13. package/dist/node.d.ts.map +1 -0
  14. package/dist/node.js +43 -0
  15. package/dist/node.js.map +1 -0
  16. package/dist/precompiled.d.ts +31 -0
  17. package/dist/precompiled.d.ts.map +1 -0
  18. package/dist/precompiled.js +125 -0
  19. package/dist/precompiled.js.map +1 -0
  20. package/dist/stage3d.d.ts +13 -0
  21. package/dist/stage3d.d.ts.map +1 -0
  22. package/dist/stage3d.js +61 -0
  23. package/dist/stage3d.js.map +1 -0
  24. package/dist/thread/codegen/codegen.js +308 -0
  25. package/dist/thread/codegen/index.js +405 -0
  26. package/dist/thread/format/abc-names.js +126 -0
  27. package/dist/thread/format/actions.js +222 -0
  28. package/dist/thread/format/air-descriptor.js +63 -0
  29. package/dist/thread/format/api-versions.js +22 -0
  30. package/dist/thread/format/bitmap.js +199 -0
  31. package/dist/thread/format/button.js +60 -0
  32. package/dist/thread/format/compression.js +200 -0
  33. package/dist/thread/format/display.js +305 -0
  34. package/dist/thread/format/filters.js +136 -0
  35. package/dist/thread/format/font.js +168 -0
  36. package/dist/thread/format/index.js +26 -0
  37. package/dist/thread/format/pbj.js +484 -0
  38. package/dist/thread/format/shape.js +411 -0
  39. package/dist/thread/format/sound.js +91 -0
  40. package/dist/thread/format/swf.js +163 -0
  41. package/dist/thread/format/tags.js +58 -0
  42. package/dist/thread/format/text.js +135 -0
  43. package/dist/thread/format/zip.js +91 -0
  44. package/dist/thread/native/audio/binary.js +3 -0
  45. package/dist/thread/native/audio/index.js +72 -0
  46. package/dist/thread/native/base64.js +9 -0
  47. package/dist/thread/native/compress/binary.js +3 -0
  48. package/dist/thread/native/compress/index.js +145 -0
  49. package/dist/thread/native/instance.js +49 -0
  50. package/dist/thread/native/mp3/binary.js +3 -0
  51. package/dist/thread/native/mp3/index.js +48 -0
  52. package/dist/thread/native/render/binary.js +3 -0
  53. package/dist/thread/native/render/bitmap-kernel.js +591 -0
  54. package/dist/thread/native/render/draw-kernel.js +204 -0
  55. package/dist/thread/native/render/dxt-encoder.js +94 -0
  56. package/dist/thread/native/render/index.js +10 -0
  57. package/dist/thread/native/render/lines.js +122 -0
  58. package/dist/thread/native/render/module.js +26 -0
  59. package/dist/thread/native/render/pixel-ops.js +235 -0
  60. package/dist/thread/native/render/tessellator.js +250 -0
  61. package/dist/thread/player/avm1/amf.js +507 -0
  62. package/dist/thread/player/avm1/avm1.js +1304 -0
  63. package/dist/thread/player/avm1/bindings.js +214 -0
  64. package/dist/thread/player/avm1/classes.js +75 -0
  65. package/dist/thread/player/avm1/clips.js +229 -0
  66. package/dist/thread/player/avm1/compile.js +140 -0
  67. package/dist/thread/player/avm1/external.js +79 -0
  68. package/dist/thread/player/avm1/focus.js +278 -0
  69. package/dist/thread/player/avm1/globals/BitmapData.js +542 -0
  70. package/dist/thread/player/avm1/globals/Button.js +31 -0
  71. package/dist/thread/player/avm1/globals/Color.js +115 -0
  72. package/dist/thread/player/avm1/globals/ExternalInterface.js +310 -0
  73. package/dist/thread/player/avm1/globals/FileReference.js +217 -0
  74. package/dist/thread/player/avm1/globals/Key.js +60 -0
  75. package/dist/thread/player/avm1/globals/LoadVars.js +208 -0
  76. package/dist/thread/player/avm1/globals/LocalConnection.js +92 -0
  77. package/dist/thread/player/avm1/globals/MovieClip.js +1070 -0
  78. package/dist/thread/player/avm1/globals/MovieClipLoader.js +90 -0
  79. package/dist/thread/player/avm1/globals/NetConnection.js +261 -0
  80. package/dist/thread/player/avm1/globals/PrintJob.js +37 -0
  81. package/dist/thread/player/avm1/globals/Selection.js +62 -0
  82. package/dist/thread/player/avm1/globals/SharedObject.js +245 -0
  83. package/dist/thread/player/avm1/globals/Sound.js +238 -0
  84. package/dist/thread/player/avm1/globals/Stage.js +12 -0
  85. package/dist/thread/player/avm1/globals/StyleSheet.js +205 -0
  86. package/dist/thread/player/avm1/globals/TextField.js +396 -0
  87. package/dist/thread/player/avm1/globals/TextFormat.js +194 -0
  88. package/dist/thread/player/avm1/globals/TextSnapshot.js +88 -0
  89. package/dist/thread/player/avm1/globals/XML.js +396 -0
  90. package/dist/thread/player/avm1/globals/XMLNode.js +413 -0
  91. package/dist/thread/player/avm1/globals/XMLSocket.js +205 -0
  92. package/dist/thread/player/avm1/globals/drawing.js +202 -0
  93. package/dist/thread/player/avm1/globals/filters.js +635 -0
  94. package/dist/thread/player/avm1/globals/geom.js +600 -0
  95. package/dist/thread/player/avm1/input.js +483 -0
  96. package/dist/thread/player/avm1/keyboard.js +113 -0
  97. package/dist/thread/player/avm1/loads.js +352 -0
  98. package/dist/thread/player/avm1/net.js +219 -0
  99. package/dist/thread/player/avm1/paths.js +104 -0
  100. package/dist/thread/player/avm1/pointer.js +512 -0
  101. package/dist/thread/player/avm1/queue.js +303 -0
  102. package/dist/thread/player/avm1/sound.js +106 -0
  103. package/dist/thread/player/avm1/swf.js +141 -0
  104. package/dist/thread/player/avm1/timers.js +113 -0
  105. package/dist/thread/player/bitmap/bitmap.js +627 -0
  106. package/dist/thread/player/bitmap/draw.js +68 -0
  107. package/dist/thread/player/bitmap/dxt.js +11 -0
  108. package/dist/thread/player/bitmap/filters.js +656 -0
  109. package/dist/thread/player/bitmap/images.js +240 -0
  110. package/dist/thread/player/bitmap/kernel.js +65 -0
  111. package/dist/thread/player/bitmap/ops.js +1239 -0
  112. package/dist/thread/player/bitmap/pixel-bender.js +911 -0
  113. package/dist/thread/player/bitmap/png.js +139 -0
  114. package/dist/thread/player/bitmap/turbulence.js +89 -0
  115. package/dist/thread/player/clock.js +182 -0
  116. package/dist/thread/player/display/bitmapobject.js +25 -0
  117. package/dist/thread/player/display/bounds.js +520 -0
  118. package/dist/thread/player/display/buttonobject.js +305 -0
  119. package/dist/thread/player/display/color.js +40 -0
  120. package/dist/thread/player/display/container.js +150 -0
  121. package/dist/thread/player/display/display.js +14 -0
  122. package/dist/thread/player/display/displayobject.js +664 -0
  123. package/dist/thread/player/display/drawing.js +613 -0
  124. package/dist/thread/player/display/filters.js +285 -0
  125. package/dist/thread/player/display/geometry.js +189 -0
  126. package/dist/thread/player/display/gradients.js +117 -0
  127. package/dist/thread/player/display/graphicsdata.js +592 -0
  128. package/dist/thread/player/display/instantiate.js +71 -0
  129. package/dist/thread/player/display/matrix3d.js +373 -0
  130. package/dist/thread/player/display/morph.js +226 -0
  131. package/dist/thread/player/display/movieclip.js +680 -0
  132. package/dist/thread/player/display/perspective.js +193 -0
  133. package/dist/thread/player/display/scale9.js +236 -0
  134. package/dist/thread/player/display/shapeobject.js +131 -0
  135. package/dist/thread/player/display/shapes.js +407 -0
  136. package/dist/thread/player/display/textobjects.js +222 -0
  137. package/dist/thread/player/display/timeline.js +471 -0
  138. package/dist/thread/player/display/value-lists.js +40 -0
  139. package/dist/thread/player/display/videoobject.js +6 -0
  140. package/dist/thread/player/display/walk.js +127 -0
  141. package/dist/thread/player/files.js +334 -0
  142. package/dist/thread/player/hosts.js +207 -0
  143. package/dist/thread/player/input/avm1.js +82 -0
  144. package/dist/thread/player/input/context-menu.js +63 -0
  145. package/dist/thread/player/input/keyboard.js +458 -0
  146. package/dist/thread/player/input/pointer.js +863 -0
  147. package/dist/thread/player/input/text-editor.js +319 -0
  148. package/dist/thread/player/input/touch.js +209 -0
  149. package/dist/thread/player/localconnection.js +90 -0
  150. package/dist/thread/player/media/audio.js +376 -0
  151. package/dist/thread/player/media/dynamic-sound.js +90 -0
  152. package/dist/thread/player/media/extract.js +135 -0
  153. package/dist/thread/player/media/mp3.js +152 -0
  154. package/dist/thread/player/media/sounds.js +507 -0
  155. package/dist/thread/player/media/streaming-audio.js +133 -0
  156. package/dist/thread/player/player.js +616 -0
  157. package/dist/thread/player/playerglobal/air/net/WebSocket.js +250 -0
  158. package/dist/thread/player/playerglobal/air-library.js +8 -0
  159. package/dist/thread/player/playerglobal/flash/accessibility/Accessibility.js +21 -0
  160. package/dist/thread/player/playerglobal/flash/crypto/generateRandomBytes.js +32 -0
  161. package/dist/thread/player/playerglobal/flash/data/EncryptedLocalStore.js +61 -0
  162. package/dist/thread/player/playerglobal/flash/desktop/Clipboard.js +173 -0
  163. package/dist/thread/player/playerglobal/flash/desktop/NativeApplication.js +179 -0
  164. package/dist/thread/player/playerglobal/flash/display/AVM1Movie.js +19 -0
  165. package/dist/thread/player/playerglobal/flash/display/Bitmap.js +58 -0
  166. package/dist/thread/player/playerglobal/flash/display/BitmapData.js +633 -0
  167. package/dist/thread/player/playerglobal/flash/display/DisplayObject.js +614 -0
  168. package/dist/thread/player/playerglobal/flash/display/DisplayObjectContainer.js +224 -0
  169. package/dist/thread/player/playerglobal/flash/display/Graphics.js +345 -0
  170. package/dist/thread/player/playerglobal/flash/display/InteractiveObject.js +87 -0
  171. package/dist/thread/player/playerglobal/flash/display/Loader.js +79 -0
  172. package/dist/thread/player/playerglobal/flash/display/LoaderInfo.js +128 -0
  173. package/dist/thread/player/playerglobal/flash/display/MovieClip.js +194 -0
  174. package/dist/thread/player/playerglobal/flash/display/NativeWindow.js +245 -0
  175. package/dist/thread/player/playerglobal/flash/display/Shader.js +26 -0
  176. package/dist/thread/player/playerglobal/flash/display/ShaderData.js +85 -0
  177. package/dist/thread/player/playerglobal/flash/display/ShaderInput.js +64 -0
  178. package/dist/thread/player/playerglobal/flash/display/ShaderJob.js +181 -0
  179. package/dist/thread/player/playerglobal/flash/display/ShaderParameter.js +23 -0
  180. package/dist/thread/player/playerglobal/flash/display/Shape.js +13 -0
  181. package/dist/thread/player/playerglobal/flash/display/SimpleButton.js +103 -0
  182. package/dist/thread/player/playerglobal/flash/display/Sprite.js +84 -0
  183. package/dist/thread/player/playerglobal/flash/display/Stage.js +231 -0
  184. package/dist/thread/player/playerglobal/flash/display/Stage3D.js +54 -0
  185. package/dist/thread/player/playerglobal/flash/display/shaders.js +228 -0
  186. package/dist/thread/player/playerglobal/flash/events/Event.js +58 -0
  187. package/dist/thread/player/playerglobal/flash/events/EventDispatcher.js +103 -0
  188. package/dist/thread/player/playerglobal/flash/events/GestureEvent.js +34 -0
  189. package/dist/thread/player/playerglobal/flash/events/HTTPStatusEvent.js +8 -0
  190. package/dist/thread/player/playerglobal/flash/events/KeyboardEvent.js +51 -0
  191. package/dist/thread/player/playerglobal/flash/events/MouseEvent.js +59 -0
  192. package/dist/thread/player/playerglobal/flash/events/PressAndTapGestureEvent.js +30 -0
  193. package/dist/thread/player/playerglobal/flash/events/TimerEvent.js +16 -0
  194. package/dist/thread/player/playerglobal/flash/events/TouchEvent.js +45 -0
  195. package/dist/thread/player/playerglobal/flash/external/ExternalInterface.js +73 -0
  196. package/dist/thread/player/playerglobal/flash/filesystem/File.js +340 -0
  197. package/dist/thread/player/playerglobal/flash/filesystem/FileStream.js +453 -0
  198. package/dist/thread/player/playerglobal/flash/filesystem/paths.js +156 -0
  199. package/dist/thread/player/playerglobal/flash/filesystem/writes.js +143 -0
  200. package/dist/thread/player/playerglobal/flash/filters/BevelFilter.js +4 -0
  201. package/dist/thread/player/playerglobal/flash/filters/BitmapFilter.js +205 -0
  202. package/dist/thread/player/playerglobal/flash/filters/BlurFilter.js +4 -0
  203. package/dist/thread/player/playerglobal/flash/filters/ColorMatrixFilter.js +11 -0
  204. package/dist/thread/player/playerglobal/flash/filters/ConvolutionFilter.js +26 -0
  205. package/dist/thread/player/playerglobal/flash/filters/DisplacementMapFilter.js +51 -0
  206. package/dist/thread/player/playerglobal/flash/filters/DropShadowFilter.js +4 -0
  207. package/dist/thread/player/playerglobal/flash/filters/GlowFilter.js +4 -0
  208. package/dist/thread/player/playerglobal/flash/filters/GradientBevelFilter.js +4 -0
  209. package/dist/thread/player/playerglobal/flash/filters/GradientGlowFilter.js +4 -0
  210. package/dist/thread/player/playerglobal/flash/filters/ShaderFilter.js +53 -0
  211. package/dist/thread/player/playerglobal/flash/geom/Matrix3D.js +361 -0
  212. package/dist/thread/player/playerglobal/flash/geom/PerspectiveProjection.js +122 -0
  213. package/dist/thread/player/playerglobal/flash/geom/Transform.js +245 -0
  214. package/dist/thread/player/playerglobal/flash/geom/Utils3D.js +85 -0
  215. package/dist/thread/player/playerglobal/flash/globalization/Collator.js +149 -0
  216. package/dist/thread/player/playerglobal/flash/globalization/CurrencyFormatter.js +272 -0
  217. package/dist/thread/player/playerglobal/flash/globalization/CurrencyParseResult.js +21 -0
  218. package/dist/thread/player/playerglobal/flash/globalization/DateTimeFormatter.js +463 -0
  219. package/dist/thread/player/playerglobal/flash/globalization/LocaleID.js +144 -0
  220. package/dist/thread/player/playerglobal/flash/globalization/NumberFormatter.js +444 -0
  221. package/dist/thread/player/playerglobal/flash/globalization/NumberParseResult.js +22 -0
  222. package/dist/thread/player/playerglobal/flash/globalization/StringTools.js +59 -0
  223. package/dist/thread/player/playerglobal/flash/globalization/locale.js +190 -0
  224. package/dist/thread/player/playerglobal/flash/media/Camera.js +89 -0
  225. package/dist/thread/player/playerglobal/flash/media/Microphone.js +126 -0
  226. package/dist/thread/player/playerglobal/flash/media/Sound.js +543 -0
  227. package/dist/thread/player/playerglobal/flash/media/SoundMixer.js +74 -0
  228. package/dist/thread/player/playerglobal/flash/media/SoundTransform.js +40 -0
  229. package/dist/thread/player/playerglobal/flash/media/Video.js +43 -0
  230. package/dist/thread/player/playerglobal/flash/net/FileFilter.js +27 -0
  231. package/dist/thread/player/playerglobal/flash/net/FileReference.js +197 -0
  232. package/dist/thread/player/playerglobal/flash/net/LocalConnection.js +167 -0
  233. package/dist/thread/player/playerglobal/flash/net/NetConnection.js +155 -0
  234. package/dist/thread/player/playerglobal/flash/net/SharedObject.js +299 -0
  235. package/dist/thread/player/playerglobal/flash/net/Socket.js +282 -0
  236. package/dist/thread/player/playerglobal/flash/net/URLRequest.js +93 -0
  237. package/dist/thread/player/playerglobal/flash/net/URLStream.js +146 -0
  238. package/dist/thread/player/playerglobal/flash/net/XMLSocket.js +14 -0
  239. package/dist/thread/player/playerglobal/flash/net/local-modern.js +142 -0
  240. package/dist/thread/player/playerglobal/flash/net/local-values.js +217 -0
  241. package/dist/thread/player/playerglobal/flash/net/navigateToURL.js +29 -0
  242. package/dist/thread/player/playerglobal/flash/profiler/Telemetry.js +25 -0
  243. package/dist/thread/player/playerglobal/flash/sensors/Accelerometer.js +12 -0
  244. package/dist/thread/player/playerglobal/flash/system/ApplicationDomain.js +69 -0
  245. package/dist/thread/player/playerglobal/flash/system/Capabilities.js +163 -0
  246. package/dist/thread/player/playerglobal/flash/system/FSCommandHost.js +17 -0
  247. package/dist/thread/player/playerglobal/flash/system/Security.js +46 -0
  248. package/dist/thread/player/playerglobal/flash/system/SecurityDomain.js +21 -0
  249. package/dist/thread/player/playerglobal/flash/system/System.js +73 -0
  250. package/dist/thread/player/playerglobal/flash/system/Worker.js +112 -0
  251. package/dist/thread/player/playerglobal/flash/text/Font.js +95 -0
  252. package/dist/thread/player/playerglobal/flash/text/StaticText.js +16 -0
  253. package/dist/thread/player/playerglobal/flash/text/StyleSheet.js +65 -0
  254. package/dist/thread/player/playerglobal/flash/text/TextField.js +707 -0
  255. package/dist/thread/player/playerglobal/flash/text/TextRenderer.js +77 -0
  256. package/dist/thread/player/playerglobal/flash/text/engine/FontDescription.js +141 -0
  257. package/dist/thread/player/playerglobal/flash/text/engine/TabStop.js +46 -0
  258. package/dist/thread/player/playerglobal/flash/trace/Trace.js +17 -0
  259. package/dist/thread/player/playerglobal/flash/ui/ContextMenu.js +17 -0
  260. package/dist/thread/player/playerglobal/flash/ui/GameInput.js +19 -0
  261. package/dist/thread/player/playerglobal/flash/ui/Keyboard.js +27 -0
  262. package/dist/thread/player/playerglobal/flash/ui/Mouse.js +127 -0
  263. package/dist/thread/player/playerglobal/flash/ui/Multitouch.js +46 -0
  264. package/dist/thread/player/playerglobal/flash/utils/ByteArray.js +155 -0
  265. package/dist/thread/player/playerglobal/flash/utils/Timer.js +25 -0
  266. package/dist/thread/player/playerglobal/flash/xml/XMLDocument.js +74 -0
  267. package/dist/thread/player/playerglobal/index.js +224 -0
  268. package/dist/thread/player/playerglobal/libraries.js +10 -0
  269. package/dist/thread/player/playerglobal/playerglobal-library.js +22 -0
  270. package/dist/thread/player/playerglobal/toplevel.js +122 -0
  271. package/dist/thread/player/scripting/clipboard.js +146 -0
  272. package/dist/thread/player/scripting/code.js +900 -0
  273. package/dist/thread/player/scripting/evaluate.js +144 -0
  274. package/dist/thread/player/scripting/events.js +172 -0
  275. package/dist/thread/player/scripting/handover.js +182 -0
  276. package/dist/thread/player/scripting/lazy.js +38 -0
  277. package/dist/thread/player/scripting/lifecycle.js +272 -0
  278. package/dist/thread/player/scripting/loads.js +860 -0
  279. package/dist/thread/player/scripting/sha256.js +95 -0
  280. package/dist/thread/player/scripting/symbols.js +348 -0
  281. package/dist/thread/player/scripting/timers.js +434 -0
  282. package/dist/thread/player/scripting/workers.js +923 -0
  283. package/dist/thread/player/scripting.js +1018 -0
  284. package/dist/thread/player/stage.js +4 -0
  285. package/dist/thread/player/text/csm.js +113 -0
  286. package/dist/thread/player/text/css.js +167 -0
  287. package/dist/thread/player/text/fonts.js +97 -0
  288. package/dist/thread/player/text/layout.js +393 -0
  289. package/dist/thread/player/text/static.js +109 -0
  290. package/dist/thread/player/text/text.js +431 -0
  291. package/dist/thread/player/workers/thread.js +159 -0
  292. package/dist/thread/player/workers/wire.js +198 -0
  293. package/dist/thread/player-hosts/web-worker.js +19 -0
  294. package/dist/thread/runtime/avm1/activation.js +89 -0
  295. package/dist/thread/runtime/avm1/case.js +249 -0
  296. package/dist/thread/runtime/avm1/clips.js +334 -0
  297. package/dist/thread/runtime/avm1/control.js +280 -0
  298. package/dist/thread/runtime/avm1/errors.js +50 -0
  299. package/dist/thread/runtime/avm1/functions.js +249 -0
  300. package/dist/thread/runtime/avm1/globals/array.js +549 -0
  301. package/dist/thread/runtime/avm1/globals/broadcaster.js +131 -0
  302. package/dist/thread/runtime/avm1/globals/date.js +436 -0
  303. package/dist/thread/runtime/avm1/globals/global.js +344 -0
  304. package/dist/thread/runtime/avm1/globals/math.js +139 -0
  305. package/dist/thread/runtime/avm1/globals/number.js +93 -0
  306. package/dist/thread/runtime/avm1/globals/string.js +201 -0
  307. package/dist/thread/runtime/avm1/globals/timers.js +129 -0
  308. package/dist/thread/runtime/avm1/host.js +5 -0
  309. package/dist/thread/runtime/avm1/index.js +14 -0
  310. package/dist/thread/runtime/avm1/inheritance.js +132 -0
  311. package/dist/thread/runtime/avm1/numbers.js +298 -0
  312. package/dist/thread/runtime/avm1/objects.js +896 -0
  313. package/dist/thread/runtime/avm1/operators.js +170 -0
  314. package/dist/thread/runtime/avm1/realm.js +529 -0
  315. package/dist/thread/runtime/avm1/runtime.js +882 -0
  316. package/dist/thread/runtime/avm1/scope.js +385 -0
  317. package/dist/thread/runtime/avm1/urls.js +180 -0
  318. package/dist/thread/runtime/avm1/values.js +97 -0
  319. package/dist/thread/runtime/avm2/amf-classes.js +66 -0
  320. package/dist/thread/runtime/avm2/amf.js +801 -0
  321. package/dist/thread/runtime/avm2/array-conversion.js +100 -0
  322. package/dist/thread/runtime/avm2/builtin-library.js +21 -0
  323. package/dist/thread/runtime/avm2/cache-fill.js +86 -0
  324. package/dist/thread/runtime/avm2/classes.js +211 -0
  325. package/dist/thread/runtime/avm2/definitions.js +69 -0
  326. package/dist/thread/runtime/avm2/descriptors.js +5 -0
  327. package/dist/thread/runtime/avm2/dictionary-keys.js +295 -0
  328. package/dist/thread/runtime/avm2/domain-memory.js +75 -0
  329. package/dist/thread/runtime/avm2/domain.js +280 -0
  330. package/dist/thread/runtime/avm2/dynamic-properties.js +182 -0
  331. package/dist/thread/runtime/avm2/enumeration.js +393 -0
  332. package/dist/thread/runtime/avm2/errors.js +45 -0
  333. package/dist/thread/runtime/avm2/float-library.js +66 -0
  334. package/dist/thread/runtime/avm2/float.js +26 -0
  335. package/dist/thread/runtime/avm2/hooks.js +19 -0
  336. package/dist/thread/runtime/avm2/index.js +38 -0
  337. package/dist/thread/runtime/avm2/messages.js +177 -0
  338. package/dist/thread/runtime/avm2/method-factories.js +95 -0
  339. package/dist/thread/runtime/avm2/modules.js +105 -0
  340. package/dist/thread/runtime/avm2/names.js +248 -0
  341. package/dist/thread/runtime/avm2/natives/aliases.js +47 -0
  342. package/dist/thread/runtime/avm2/natives/array.js +390 -0
  343. package/dist/thread/runtime/avm2/natives/bytearray.js +1227 -0
  344. package/dist/thread/runtime/avm2/natives/case.js +88 -0
  345. package/dist/thread/runtime/avm2/natives/concurrent.js +199 -0
  346. package/dist/thread/runtime/avm2/natives/date.js +581 -0
  347. package/dist/thread/runtime/avm2/natives/define.js +130 -0
  348. package/dist/thread/runtime/avm2/natives/describe.js +351 -0
  349. package/dist/thread/runtime/avm2/natives/dictionary.js +12 -0
  350. package/dist/thread/runtime/avm2/natives/float-vector.js +81 -0
  351. package/dist/thread/runtime/avm2/natives/float.js +96 -0
  352. package/dist/thread/runtime/avm2/natives/index.js +64 -0
  353. package/dist/thread/runtime/avm2/natives/json.js +514 -0
  354. package/dist/thread/runtime/avm2/natives/number.js +162 -0
  355. package/dist/thread/runtime/avm2/natives/object.js +237 -0
  356. package/dist/thread/runtime/avm2/natives/proxy.js +75 -0
  357. package/dist/thread/runtime/avm2/natives/regexp.js +485 -0
  358. package/dist/thread/runtime/avm2/natives/shell-workers.js +404 -0
  359. package/dist/thread/runtime/avm2/natives/shell.js +557 -0
  360. package/dist/thread/runtime/avm2/natives/sort.js +377 -0
  361. package/dist/thread/runtime/avm2/natives/string.js +132 -0
  362. package/dist/thread/runtime/avm2/natives/sync.js +821 -0
  363. package/dist/thread/runtime/avm2/natives/toplevel.js +139 -0
  364. package/dist/thread/runtime/avm2/natives/vector-elements.js +46 -0
  365. package/dist/thread/runtime/avm2/natives/vector.js +406 -0
  366. package/dist/thread/runtime/avm2/natives/xml/access.js +633 -0
  367. package/dist/thread/runtime/avm2/natives/xml/build.js +291 -0
  368. package/dist/thread/runtime/avm2/natives/xml/chars.js +112 -0
  369. package/dist/thread/runtime/avm2/natives/xml/escape.js +38 -0
  370. package/dist/thread/runtime/avm2/natives/xml/names.js +204 -0
  371. package/dist/thread/runtime/avm2/natives/xml/node.js +272 -0
  372. package/dist/thread/runtime/avm2/natives/xml/operators.js +69 -0
  373. package/dist/thread/runtime/avm2/natives/xml/parser.js +356 -0
  374. package/dist/thread/runtime/avm2/natives/xml/strings.js +191 -0
  375. package/dist/thread/runtime/avm2/natives/xml/values.js +122 -0
  376. package/dist/thread/runtime/avm2/natives/xml/xml.js +645 -0
  377. package/dist/thread/runtime/avm2/number-strings.js +110 -0
  378. package/dist/thread/runtime/avm2/numbers.js +558 -0
  379. package/dist/thread/runtime/avm2/options.js +16 -0
  380. package/dist/thread/runtime/avm2/player-messages.js +550 -0
  381. package/dist/thread/runtime/avm2/property-cache.js +135 -0
  382. package/dist/thread/runtime/avm2/runtime.js +2644 -0
  383. package/dist/thread/runtime/avm2/traits.js +509 -0
  384. package/dist/thread/runtime/index.js +7 -0
  385. package/dist/web-worker.d.ts +2 -0
  386. package/dist/web-worker.d.ts.map +1 -0
  387. package/dist/web-worker.js +20 -0
  388. package/dist/web-worker.js.map +1 -0
  389. package/dist/websocket.d.ts +4 -0
  390. package/dist/websocket.d.ts.map +1 -0
  391. package/dist/websocket.js +27 -0
  392. package/dist/websocket.js.map +1 -0
  393. package/dist/workers.d.ts +35 -0
  394. package/dist/workers.d.ts.map +1 -0
  395. package/dist/workers.js +171 -0
  396. package/dist/workers.js.map +1 -0
  397. package/package.json +62 -3
  398. package/src/indexeddb.ts +227 -0
  399. package/src/node-worker.ts +13 -0
  400. package/src/node.ts +49 -0
  401. package/src/precompiled.ts +166 -0
  402. package/src/stage3d.ts +76 -0
  403. package/src/web-worker.ts +24 -0
  404. package/src/websocket.ts +32 -0
  405. package/src/workers.ts +255 -0
@@ -0,0 +1,376 @@
1
+ import { decodeAdpcm, NellymoserDecoder } from "../../native/audio/index.js";
2
+ import { mp3HeaderFrame } from "./mp3.js";
3
+ import { browserStream } from "./streaming-audio.js";
4
+ /** Below Firefox's limit for a scheduled stop, 2^23 s, with room for the context's own clock. */
5
+ const SCHEDULED_STOP_LIMIT = 2 ** 22;
6
+ /** The browser's decoder handles MP3; SWF's two uncompressed forms need no codec. */
7
+ export function browserAudioHost() {
8
+ const Context = globalThis.AudioContext;
9
+ if (!Context) {
10
+ return null;
11
+ }
12
+ let context = null;
13
+ let closed = false;
14
+ const streams = new Set();
15
+ // Closed, it decodes nothing more: a new context would outlive the player.
16
+ const getContext = () => {
17
+ if (closed) {
18
+ throw new Error("the audio host is closed");
19
+ }
20
+ context ??= new Context();
21
+ return context;
22
+ };
23
+ return {
24
+ stream(mix, refill) {
25
+ const stream = browserStream(getContext(), mix, refill, () => streams.delete(stream));
26
+ streams.add(stream);
27
+ return stream;
28
+ },
29
+ close() {
30
+ // A browser keeps a context, and its thread, until it is closed.
31
+ closed = true;
32
+ for (const stream of streams) {
33
+ stream.stop();
34
+ }
35
+ void context?.close().catch(() => { });
36
+ context = null;
37
+ },
38
+ async decode(given) {
39
+ const ctx = getContext();
40
+ const source = given instanceof Uint8Array
41
+ ? given
42
+ : given.format === 1
43
+ ? adpcmSound(given)
44
+ : isNellymoser(given.format)
45
+ ? nellymoserSound(given)
46
+ : given;
47
+ let buffer;
48
+ if (source instanceof Uint8Array || source.format === 2) {
49
+ const data = (source instanceof Uint8Array ? source : source.data).slice();
50
+ if (!(source instanceof Uint8Array)) {
51
+ // SWF supplies the delay itself. Keep the header frame's silence,
52
+ // without letting the browser trim it by Xing/LAME metadata too.
53
+ const header = mp3HeaderFrame(data);
54
+ if (header) {
55
+ data.fill(0, header[0] + 4, header[1]);
56
+ }
57
+ }
58
+ buffer = await ctx.decodeAudioData(data.buffer);
59
+ }
60
+ else if (source.format === 0 || source.format === 3) {
61
+ buffer = ctx.createBuffer(source.channels, source.sampleCount, source.sampleRate);
62
+ const view = new DataView(source.data.buffer, source.data.byteOffset, source.data.byteLength);
63
+ const channels = Array.from({ length: source.channels }, (_, i) => buffer.getChannelData(i));
64
+ const bytesPerFrame = source.channels * (source.sampleSize / 8);
65
+ const frames = Math.min(source.sampleCount, Math.floor(source.data.byteLength / bytesPerFrame));
66
+ if (source.sampleSize === 8) {
67
+ for (let i = 0; i < frames; i++) {
68
+ for (let channel = 0; channel < source.channels; channel++) {
69
+ channels[channel][i] = (view.getUint8(i * bytesPerFrame + channel) - 128) / 128;
70
+ }
71
+ }
72
+ }
73
+ else {
74
+ for (let i = 0; i < frames; i++) {
75
+ for (let channel = 0; channel < source.channels; channel++) {
76
+ channels[channel][i] = view.getInt16(i * bytesPerFrame + channel * 2, true) / 32768;
77
+ }
78
+ }
79
+ }
80
+ }
81
+ else {
82
+ throw new Error(`Unsupported SWF sound format ${source.format}`);
83
+ }
84
+ // DefineSound's offsets count from after the encoder delay, in its
85
+ // own sample rate; Web Audio may have resampled the decoded buffer.
86
+ const origin = !(source instanceof Uint8Array) && source.format === 2
87
+ ? Math.max(0, source.seekSamples) / source.sampleRate
88
+ : 0;
89
+ const duration = !(source instanceof Uint8Array) && source.format === 2
90
+ ? Math.max(0, Math.min(buffer.duration - origin, source.sampleCount / source.sampleRate))
91
+ : buffer.duration;
92
+ return {
93
+ durationMs: duration * 1000,
94
+ play(startMs, loops, mix, shape) {
95
+ const offset = Math.max(0, startMs / 1000);
96
+ const end = Math.min(duration, (shape?.endMs ?? Infinity) / 1000);
97
+ const keepsTime = shape?.atMs !== undefined;
98
+ const at = Math.max(0, (shape?.atMs ?? 0) / 1000);
99
+ const length = end - offset;
100
+ const total = length * Math.max(1, loops);
101
+ if (length <= 0 || at >= total) {
102
+ return null;
103
+ }
104
+ const sourceNode = ctx.createBufferSource();
105
+ let ended = false;
106
+ let started = false;
107
+ let beganAt = 0;
108
+ let from = 0;
109
+ let position = Number.NaN;
110
+ const positionMs = () => started && !ended
111
+ ? Math.min(total, from + Math.max(0, ctx.currentTime - beganAt)) * 1000
112
+ : position;
113
+ const finish = () => {
114
+ if (ended) {
115
+ return;
116
+ }
117
+ position = positionMs();
118
+ ended = true;
119
+ ctx.removeEventListener?.("statechange", running);
120
+ sourceNode.disconnect();
121
+ splitter.disconnect();
122
+ for (const gain of [...gains, ...levels]) {
123
+ gain.disconnect();
124
+ }
125
+ merger.disconnect();
126
+ };
127
+ sourceNode.buffer = buffer;
128
+ const splitter = ctx.createChannelSplitter(2);
129
+ const merger = ctx.createChannelMerger(2);
130
+ const gains = Array.from({ length: 4 }, () => ctx.createGain());
131
+ const right = buffer.numberOfChannels === 1 ? 0 : 1;
132
+ sourceNode.onended = finish;
133
+ sourceNode.connect(splitter);
134
+ // An envelope scales each source channel, a mono one as both, before the mix crosses them.
135
+ const levels = shape?.envelope ? [ctx.createGain(), ctx.createGain()] : [];
136
+ if (shape?.envelope) {
137
+ splitter.connect(levels[0], 0);
138
+ splitter.connect(levels[1], right);
139
+ levels[0].connect(gains[0]);
140
+ levels[0].connect(gains[1]);
141
+ levels[1].connect(gains[2]);
142
+ levels[1].connect(gains[3]);
143
+ }
144
+ else {
145
+ splitter.connect(gains[0], 0);
146
+ splitter.connect(gains[1], 0);
147
+ splitter.connect(gains[2], right);
148
+ splitter.connect(gains[3], right);
149
+ }
150
+ gains[0].connect(merger, 0, 0);
151
+ gains[1].connect(merger, 0, 1);
152
+ gains[2].connect(merger, 0, 0);
153
+ gains[3].connect(merger, 0, 1);
154
+ merger.connect(ctx.destination);
155
+ const setMix = (next) => {
156
+ gains[0].gain.value = next.volume * next.leftToLeft;
157
+ gains[1].gain.value = next.volume * next.leftToRight;
158
+ gains[2].gain.value = next.volume * next.rightToLeft;
159
+ gains[3].gain.value = next.volume * next.rightToRight;
160
+ };
161
+ setMix(mix);
162
+ sourceNode.loop = loops > 1;
163
+ sourceNode.loopStart = origin + offset;
164
+ sourceNode.loopEnd = origin + end;
165
+ const asked = performance.now();
166
+ // `late` seconds after it was asked for, as a stream waits for the device to run.
167
+ const begin = (late) => {
168
+ from = at + late;
169
+ if (from >= total) {
170
+ position = total * 1000;
171
+ finish();
172
+ return;
173
+ }
174
+ started = true;
175
+ beganAt = ctx.currentTime;
176
+ if (shape?.envelope) {
177
+ envelopeLevels(levels[0].gain, levels[1].gain, shape.envelope, ctx.currentTime, from);
178
+ }
179
+ if (loops > 1) {
180
+ sourceNode.start(0, origin + offset + (from % length));
181
+ // Firefox refuses a stop time past 2^23 s (about 97 days) with a RangeError,
182
+ // which a loop count such as 999999 asks for; a loop that long is ended by
183
+ // stop() instead, and the channel's completion is timed by the player's clock.
184
+ const remaining = total - from;
185
+ if (ctx.currentTime + remaining < SCHEDULED_STOP_LIMIT) {
186
+ sourceNode.stop(ctx.currentTime + remaining);
187
+ }
188
+ }
189
+ else if (origin + end < buffer.duration) {
190
+ sourceNode.start(0, origin + offset + from, length - from);
191
+ }
192
+ else {
193
+ sourceNode.start(0, origin + offset + from);
194
+ }
195
+ };
196
+ // A suspended context's time stands still, before the page's first
197
+ // gesture or a slow resume: a stream starts when it runs, as far in
198
+ // as the wait; any other sound plays whole once it does.
199
+ function running() {
200
+ if (ctx.state === "running" && !started && !ended) {
201
+ ctx.removeEventListener?.("statechange", running);
202
+ begin((performance.now() - asked) / 1000);
203
+ }
204
+ }
205
+ if (keepsTime && ctx.state === "suspended") {
206
+ ctx.addEventListener?.("statechange", running);
207
+ }
208
+ else {
209
+ begin(0);
210
+ }
211
+ void ctx.resume().catch(() => { });
212
+ return {
213
+ stop: () => {
214
+ if (!ended) {
215
+ if (started) {
216
+ try {
217
+ sourceNode.stop();
218
+ }
219
+ catch {
220
+ // Already stopped, or stopped by the browser: disconnected all the same.
221
+ }
222
+ }
223
+ finish();
224
+ }
225
+ },
226
+ setMix,
227
+ get ended() {
228
+ return ended;
229
+ },
230
+ get positionMs() {
231
+ return positionMs();
232
+ },
233
+ };
234
+ },
235
+ };
236
+ },
237
+ };
238
+ }
239
+ /**
240
+ * An envelope as gain automation, `at` seconds into it at `now`: the first
241
+ * point's level held before it, as Ruffle holds it, then lines between
242
+ * points; a late start begins at the level the lines reach by then.
243
+ */
244
+ function envelopeLevels(left, right, envelope, now, at) {
245
+ const ms = at * 1000;
246
+ let level = envelope[0] ?? { ms: 0, left: 1, right: 1 };
247
+ for (let i = 0; i < envelope.length && envelope[i].ms <= ms; i++) {
248
+ const next = envelope[i + 1];
249
+ level = envelope[i];
250
+ if (next && next.ms > ms && next.ms > level.ms) {
251
+ const t = (ms - level.ms) / (next.ms - level.ms);
252
+ level = {
253
+ ms,
254
+ left: level.left + (next.left - level.left) * t,
255
+ right: level.right + (next.right - level.right) * t,
256
+ };
257
+ break;
258
+ }
259
+ }
260
+ left.setValueAtTime(level.left, now);
261
+ right.setValueAtTime(level.right, now);
262
+ for (const point of envelope) {
263
+ if (point.ms >= ms) {
264
+ left.linearRampToValueAtTime(point.left, now + (point.ms - ms) / 1000);
265
+ right.linearRampToValueAtTime(point.right, now + (point.ms - ms) / 1000);
266
+ }
267
+ }
268
+ }
269
+ /** 16-bit samples as uncompressed little-endian bytes, SWF's format 3. */
270
+ function pcmBytes(samples) {
271
+ const bytes = new Uint8Array(samples.length * 2);
272
+ const view = new DataView(bytes.buffer);
273
+ for (let i = 0; i < samples.length; i++) {
274
+ view.setInt16(i * 2, samples[i], true);
275
+ }
276
+ return bytes;
277
+ }
278
+ /** Whether `format` is Nellymoser's: 4 and 5 at 16 and 8 kHz, 6 at any rate. */
279
+ function isNellymoser(format) {
280
+ return format === 4 || format === 5 || format === 6;
281
+ }
282
+ /** The sample rate of Nellymoser in `format`: 16 or 8 kHz for 4 and 5 whatever their flags say, `flagged` for 6. */
283
+ function nellymoserRate(format, flagged) {
284
+ return format === 4 ? 16000 : format === 5 ? 8000 : flagged;
285
+ }
286
+ /** Samples from -1 to 1 as 16-bit ones. */
287
+ function int16Samples(samples) {
288
+ const out = new Int16Array(samples.length);
289
+ for (let i = 0; i < samples.length; i++) {
290
+ const v = Math.round(samples[i] * 32768);
291
+ out[i] = v > 32767 ? 32767 : v < -32768 ? -32768 : v;
292
+ }
293
+ return out;
294
+ }
295
+ /** A Nellymoser DefineSound, which is mono, as the uncompressed sound it decodes to, cut to its count. */
296
+ function nellymoserSound(sound) {
297
+ const decoded = new NellymoserDecoder().decode(sound.data);
298
+ const samples = decoded.subarray(0, Math.min(decoded.length, sound.sampleCount));
299
+ return {
300
+ ...sound,
301
+ format: 3,
302
+ sampleRate: nellymoserRate(sound.format, sound.sampleRate),
303
+ sampleSize: 16,
304
+ channels: 1,
305
+ sampleCount: samples.length,
306
+ data: pcmBytes(int16Samples(samples)),
307
+ };
308
+ }
309
+ /** An ADPCM DefineSound as the uncompressed sound it decodes to. */
310
+ function adpcmSound(sound) {
311
+ const samples = decodeAdpcm(sound.data, sound.channels);
312
+ return {
313
+ ...sound,
314
+ format: 3,
315
+ sampleSize: 16,
316
+ sampleCount: samples.length / sound.channels,
317
+ data: pcmBytes(samples),
318
+ };
319
+ }
320
+ /**
321
+ * A timeline's stream as one sound, its blocks back to back, and the
322
+ * sample each block starts at, the last entry the end. MP3 blocks give
323
+ * their counts; PCM's are whole frames of their bytes; each ADPCM block
324
+ * is a sound of its own, headers and all; Nellymoser's decode one after
325
+ * another, each block's overlap carried into the next.
326
+ */
327
+ export function streamSound(head, blocks) {
328
+ const parts = [];
329
+ const starts = [0];
330
+ const adpcm = head.format === 1;
331
+ const nellymoser = isNellymoser(head.format) ? new NellymoserDecoder() : null;
332
+ const decoded = adpcm || nellymoser !== null;
333
+ const sampleSize = decoded ? 16 : head.sampleSize;
334
+ const channels = nellymoser ? 1 : head.channels;
335
+ const frameBytes = channels * (sampleSize / 8);
336
+ let samples = 0;
337
+ for (const block of blocks) {
338
+ let data = block.data;
339
+ let count;
340
+ if (head.format === 2) {
341
+ count = block.sampleCount ?? 0;
342
+ }
343
+ else {
344
+ if (adpcm) {
345
+ data = pcmBytes(decodeAdpcm(data, head.channels));
346
+ }
347
+ else if (nellymoser) {
348
+ data = pcmBytes(int16Samples(nellymoser.decode(data)));
349
+ }
350
+ count = Math.floor(data.length / frameBytes);
351
+ data = data.subarray(0, count * frameBytes);
352
+ }
353
+ parts.push(data);
354
+ samples += count;
355
+ starts.push(samples);
356
+ }
357
+ const data = new Uint8Array(parts.reduce((sum, part) => sum + part.length, 0));
358
+ let at = 0;
359
+ for (const part of parts) {
360
+ data.set(part, at);
361
+ at += part.length;
362
+ }
363
+ return {
364
+ sound: {
365
+ id: 0,
366
+ format: decoded ? 3 : head.format,
367
+ sampleRate: nellymoser ? nellymoserRate(head.format, head.sampleRate) : head.sampleRate,
368
+ sampleSize,
369
+ channels,
370
+ sampleCount: samples,
371
+ seekSamples: 0,
372
+ data,
373
+ },
374
+ starts,
375
+ };
376
+ }
@@ -0,0 +1,90 @@
1
+ // SampleDataEvent's bytes belong to the script; only detached float buffers reach the audio host.
2
+ import { avm2 } from "../../runtime/index.js";
3
+ import { dispatchEvent } from "../scripting/events.js";
4
+ import { mixerMix, outputMix } from "./sounds.js";
5
+ export function startDynamicSound(s, owner, state, onFailure) {
6
+ const data = s.rt.construct(s.rt.classNamed("flash.utils::ByteArray"));
7
+ const bytes = avm2.bytesOf(s.rt, data);
8
+ let generated = 0;
9
+ let requestOffset = 0;
10
+ let finished = false;
11
+ let requesting = false;
12
+ let ready = false;
13
+ let starting = true;
14
+ let stream;
15
+ const position = () => stream?.positionMs ?? Math.min((generated * 1000) / 44100, s.timers.now - state.started);
16
+ const request = () => {
17
+ // AIR preserves the ByteArray's contents and endian, resetting only its write cursor.
18
+ bytes.position = 0;
19
+ const event = s.rt.construct(s.rt.classNamed("flash.events::SampleDataEvent"), "sampleData", false, false, generated + requestOffset, data);
20
+ dispatchEvent(s, owner, event);
21
+ if (state.stopped) {
22
+ return;
23
+ }
24
+ const frames = Math.floor(bytes.position / 8);
25
+ if (frames > 8192 || bytes.position > bytes.length) {
26
+ finished = true;
27
+ stream?.finish();
28
+ s.reportUncaught(frames > 8192 ? s.rt.error("RangeError", 2004) : s.rt.error("flash.errors::EOFError", 2030));
29
+ return;
30
+ }
31
+ if (frames > 0) {
32
+ const channels = [new Float32Array(frames), new Float32Array(frames)];
33
+ for (let i = 0; i < frames; i++) {
34
+ for (let c = 0; c < 2; c++) {
35
+ const sample = bytes.view.getFloat32(i * 8 + c * 4, bytes.littleEndian);
36
+ channels[c][i] = Number.isFinite(sample) ? sample : 0;
37
+ }
38
+ }
39
+ generated += frames;
40
+ stream?.append(channels);
41
+ }
42
+ if (frames < 2048) {
43
+ finished = true;
44
+ stream?.finish();
45
+ }
46
+ };
47
+ const pump = () => {
48
+ if (!ready || requesting || finished || state.stopped) {
49
+ return;
50
+ }
51
+ requesting = true;
52
+ try {
53
+ if (generated - (position() * 44100) / 1000 < 8192) {
54
+ request();
55
+ }
56
+ }
57
+ catch (error) {
58
+ if (starting) {
59
+ throw error;
60
+ }
61
+ finished = true;
62
+ onFailure(error);
63
+ }
64
+ finally {
65
+ requesting = false;
66
+ }
67
+ };
68
+ state.dynamic = {
69
+ position: () => state.start + position(),
70
+ pump,
71
+ complete: () => finished && (stream ? stream.ended === true : position() >= generated / 44.1),
72
+ };
73
+ stream = s.audio?.stream?.(outputMix(state.mix, mixerMix(s)), pump);
74
+ state.playing = stream ?? null;
75
+ ready = true;
76
+ pump();
77
+ // AIR fills another buffer synchronously when the first supplied the full 8192 frames.
78
+ if (!finished && !state.stopped && generated === 8192) {
79
+ requesting = true;
80
+ try {
81
+ request();
82
+ }
83
+ finally {
84
+ requesting = false;
85
+ }
86
+ }
87
+ // AIR applies startTime to later request positions, after its synchronous initial fill.
88
+ requestOffset = Math.floor(state.start * 44.1);
89
+ starting = false;
90
+ }
@@ -0,0 +1,135 @@
1
+ import { decodeAdpcm, NellymoserDecoder } from "../../native/audio/index.js";
2
+ import { Mp3Decoder, mp3Available } from "../../native/mp3/index.js";
3
+ import { mp3Frames } from "./mp3.js";
4
+ export const EXTRACT_RATE = 44100;
5
+ /**
6
+ * Whole MP3 frames, including a header frame's silence, without gapless
7
+ * trimming. None where the engine could not compile the decoder: extract
8
+ * then writes nothing, as Flash does for a sound it cannot decode.
9
+ */
10
+ export function mp3Source(bytes) {
11
+ const mp3 = mp3Frames(bytes);
12
+ if (!mp3?.whole.length || !mp3Available()) {
13
+ return null;
14
+ }
15
+ const frames = (mp3.whole.length / 2) * mp3.samplesPerFrame;
16
+ const channels = Array.from({ length: mp3.channels }, () => new Float32Array(frames));
17
+ const decoder = new Mp3Decoder();
18
+ let at = 0;
19
+ for (let k = 0; k < mp3.whole.length; k += 2) {
20
+ const count = decoder.read(bytes.subarray(mp3.whole[k], mp3.whole[k + 1]));
21
+ if (decoder.channels === mp3.channels && decoder.rate === mp3.rate) {
22
+ const take = Math.min(count, mp3.samplesPerFrame);
23
+ for (let i = 0; i < take; i++) {
24
+ for (let c = 0; c < mp3.channels; c++) {
25
+ channels[c][at + i] = decoder.pcm[i * mp3.channels + c];
26
+ }
27
+ }
28
+ }
29
+ at += mp3.samplesPerFrame;
30
+ }
31
+ return { rate: mp3.rate, channels, skip: 0, whole: false };
32
+ }
33
+ /** An uncompressed, ADPCM or Nellymoser DefineSound's samples to extract, or null for another format. */
34
+ export function embeddedSource(sound) {
35
+ const n = sound.channels;
36
+ const source = { rate: sound.sampleRate, skip: 0, whole: true };
37
+ if (sound.format === 1) {
38
+ return { ...source, ...adpcmSource(sound.data, n) };
39
+ }
40
+ // Mono, at the rate its flags give, as adl extracts it, formats 4 and 5
41
+ // too, which play at 16 and 8 kHz (audio.ts). adl's own extract of it is
42
+ // erratic past 4096 samples a call and near the sound's end
43
+ // (scripts/SoundExtractNellymoser.as): those are not copied.
44
+ if (sound.format === 4 || sound.format === 5 || sound.format === 6) {
45
+ const samples = new NellymoserDecoder().decode(sound.data);
46
+ return {
47
+ ...source,
48
+ channels: [samples.subarray(0, Math.min(samples.length, sound.sampleCount))],
49
+ };
50
+ }
51
+ if (sound.format !== 0 && sound.format !== 3) {
52
+ return null;
53
+ }
54
+ const view = new DataView(sound.data.buffer, sound.data.byteOffset, sound.data.byteLength);
55
+ const size = sound.sampleSize / 8;
56
+ const frames = Math.min(sound.sampleCount, Math.floor(sound.data.byteLength / (size * n)));
57
+ return {
58
+ ...source,
59
+ channels: deinterleave(frames, n, (i) => size === 1 ? (view.getUint8(i) - 128) / 128 : view.getInt16(i * 2, true) / 32768),
60
+ };
61
+ }
62
+ /** Samples adl decodes in blocks of 2048, the last run on past the data as if its bits went on as zeros. */
63
+ const ADPCM_BLOCK = 2048;
64
+ /** Samples a packet: its header's and 4095 codes'. */
65
+ const ADPCM_PACKET = 4096;
66
+ /**
67
+ * An ADPCM sound's samples as adl extracts them: blocks of samples, the
68
+ * last running on as if the data's bits went on as zeros (where adl reads
69
+ * on into whatever follows the data), though a script may start only
70
+ * within the data. A start's packet's offset in bits is reckoned in 32
71
+ * bits: where that wraps negative, adl starts from the first packet, as
72
+ * far into it as the start is into its own.
73
+ */
74
+ function adpcmSource(data, n) {
75
+ const frames = decodeAdpcm(data, n).length / n;
76
+ const padded = (Math.floor(frames / ADPCM_BLOCK) + 1) * ADPCM_BLOCK;
77
+ const bits = data.length ? (data[0] >> 6) + 2 : 4;
78
+ const more = new Uint8Array(data.length + Math.ceil(((padded - frames) * bits * n) / 8) + 8 * n);
79
+ more.set(data);
80
+ const samples = decodeAdpcm(more, n);
81
+ const packetBits = 22 * n + (ADPCM_PACKET - 1) * bits * n;
82
+ return {
83
+ channels: deinterleave(padded, n, (i) => samples[i] / 32768),
84
+ starts: frames,
85
+ seek: (start) => Math.imul(Math.floor(start / ADPCM_PACKET), packetBits) < 0 ? start % ADPCM_PACKET : start,
86
+ };
87
+ }
88
+ function deinterleave(frames, n, at) {
89
+ const channels = Array.from({ length: n }, () => new Float32Array(frames));
90
+ for (let i = 0; i < frames; i++) {
91
+ for (let c = 0; c < n; c++) {
92
+ channels[c][i] = at(i * n + c);
93
+ }
94
+ }
95
+ return channels;
96
+ }
97
+ /** Samples at `rate` brought to 44.1 kHz as loadPCMFromByteArray does: each output sample the one it falls in. */
98
+ export function toExtractRate(channels, rate) {
99
+ if (rate === EXTRACT_RATE) {
100
+ return channels;
101
+ }
102
+ const frames = Math.floor((channels[0].length * EXTRACT_RATE) / rate);
103
+ return channels.map((channel) => {
104
+ const out = new Float32Array(frames);
105
+ for (let i = 0; i < frames; i++) {
106
+ out[i] = channel[Math.floor((i * rate) / EXTRACT_RATE)];
107
+ }
108
+ return out;
109
+ });
110
+ }
111
+ /**
112
+ * Up to `length` samples from `position`, interleaved, and the position
113
+ * after them. What extract returns is how many it wrote, but once the
114
+ * sound runs out, how many of its own samples it read, as adl counts them.
115
+ */
116
+ export function extractSamples(source, position, length) {
117
+ const total = source.channels[0].length - source.skip;
118
+ const ratio = EXTRACT_RATE / source.rate;
119
+ const room = Math.max(0, total - position);
120
+ const wanted = Math.floor(length);
121
+ let written = wanted > 0 ? Math.min(wanted, Math.floor(room * ratio)) : 0;
122
+ if (source.whole) {
123
+ written = Math.floor(Math.floor(written / ratio) * ratio);
124
+ }
125
+ const read = Math.min(room, Math.ceil(written / ratio));
126
+ const [left, right = left] = source.channels;
127
+ const samples = new Float32Array(written * 2);
128
+ for (let i = 0; i < written; i++) {
129
+ const at = source.skip + position + Math.floor(i / ratio);
130
+ samples[i * 2] = left[at];
131
+ samples[i * 2 + 1] = right[at];
132
+ }
133
+ const end = position + read >= total;
134
+ return { samples, position: position + read, count: end ? read : written };
135
+ }