@adatechnology/game-audio 0.3.6 → 0.5.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 (1054) hide show
  1. package/README.md +20 -0
  2. package/assets/sfx/CREDITOS.md +1046 -0
  3. package/assets/sfx/ambiente/ambience_city_day_01.ogg +0 -0
  4. package/assets/sfx/ambiente/ambience_city_day_02.ogg +0 -0
  5. package/assets/sfx/ambiente/ambience_construction_01.ogg +0 -0
  6. package/assets/sfx/ambiente/ambience_night_01.ogg +0 -0
  7. package/assets/sfx/ambiente/ambience_room_tone_01.ogg +0 -0
  8. package/assets/sfx/ambiente/ambience_room_tone_02.ogg +0 -0
  9. package/assets/sfx/ambiente/ambience_rural_day_01.ogg +0 -0
  10. package/assets/sfx/ambiente/ambience_rural_day_02.ogg +0 -0
  11. package/assets/sfx/ambiente/rain_loop_01.ogg +0 -0
  12. package/assets/sfx/ambiente/water_river_loop_01.ogg +0 -0
  13. package/assets/sfx/ambiente/water_river_loop_02.ogg +0 -0
  14. package/assets/sfx/ambiente/water_river_loop_03.ogg +0 -0
  15. package/assets/sfx/ambiente/water_splash_01.ogg +0 -0
  16. package/assets/sfx/ambiente/water_splash_02.ogg +0 -0
  17. package/assets/sfx/ambiente/water_splash_03.ogg +0 -0
  18. package/assets/sfx/ambiente/water_splash_04.ogg +0 -0
  19. package/assets/sfx/ambiente/water_splash_05.ogg +0 -0
  20. package/assets/sfx/ambiente/water_splash_06.ogg +0 -0
  21. package/assets/sfx/ambiente/water_splash_07.ogg +0 -0
  22. package/assets/sfx/ambiente/water_splash_08.ogg +0 -0
  23. package/assets/sfx/ambiente/water_splash_09.ogg +0 -0
  24. package/assets/sfx/ambiente/water_splash_10.ogg +0 -0
  25. package/assets/sfx/ambiente/water_splash_11.ogg +0 -0
  26. package/assets/sfx/ambiente/water_splash_12.ogg +0 -0
  27. package/assets/sfx/ambiente/water_splash_13.ogg +0 -0
  28. package/assets/sfx/ambiente/water_splash_14.ogg +0 -0
  29. package/assets/sfx/ambiente/water_splash_15.ogg +0 -0
  30. package/assets/sfx/armas/bolt_lift_medium_01.ogg +0 -0
  31. package/assets/sfx/armas/bolt_lift_medium_02.ogg +0 -0
  32. package/assets/sfx/armas/bolt_lift_medium_03.ogg +0 -0
  33. package/assets/sfx/armas/bolt_lift_medium_04.ogg +0 -0
  34. package/assets/sfx/armas/bolt_lift_medium_05.ogg +0 -0
  35. package/assets/sfx/armas/bolt_lock_medium_01.ogg +0 -0
  36. package/assets/sfx/armas/bolt_lock_medium_02.ogg +0 -0
  37. package/assets/sfx/armas/bolt_lock_medium_03.ogg +0 -0
  38. package/assets/sfx/armas/bolt_lock_medium_04.ogg +0 -0
  39. package/assets/sfx/armas/bolt_lock_medium_05.ogg +0 -0
  40. package/assets/sfx/armas/bolt_pull_heavy_01.ogg +0 -0
  41. package/assets/sfx/armas/bolt_pull_medium_01.ogg +0 -0
  42. package/assets/sfx/armas/bolt_pull_medium_02.ogg +0 -0
  43. package/assets/sfx/armas/bolt_pull_medium_03.ogg +0 -0
  44. package/assets/sfx/armas/bolt_pull_medium_04.ogg +0 -0
  45. package/assets/sfx/armas/bolt_pull_medium_05.ogg +0 -0
  46. package/assets/sfx/armas/bolt_pull_medium_06.ogg +0 -0
  47. package/assets/sfx/armas/bolt_push_heavy_01.ogg +0 -0
  48. package/assets/sfx/armas/bolt_push_medium_01.ogg +0 -0
  49. package/assets/sfx/armas/bolt_push_medium_02.ogg +0 -0
  50. package/assets/sfx/armas/bolt_push_medium_03.ogg +0 -0
  51. package/assets/sfx/armas/bolt_push_medium_04.ogg +0 -0
  52. package/assets/sfx/armas/bolt_push_medium_05.ogg +0 -0
  53. package/assets/sfx/armas/bolt_push_medium_06.ogg +0 -0
  54. package/assets/sfx/armas/casing_drop_concreto_01.ogg +0 -0
  55. package/assets/sfx/armas/casing_drop_concreto_02.ogg +0 -0
  56. package/assets/sfx/armas/casing_drop_concreto_03.ogg +0 -0
  57. package/assets/sfx/armas/casing_drop_metal_01.ogg +0 -0
  58. package/assets/sfx/armas/casing_drop_metal_02.ogg +0 -0
  59. package/assets/sfx/armas/casing_drop_metal_03.ogg +0 -0
  60. package/assets/sfx/armas/casing_drop_terra_01.ogg +0 -0
  61. package/assets/sfx/armas/casing_drop_terra_02.ogg +0 -0
  62. package/assets/sfx/armas/casing_drop_terra_03.ogg +0 -0
  63. package/assets/sfx/armas/charging_handle_pull_light_01.ogg +0 -0
  64. package/assets/sfx/armas/charging_handle_pull_light_02.ogg +0 -0
  65. package/assets/sfx/armas/charging_handle_pull_light_03.ogg +0 -0
  66. package/assets/sfx/armas/charging_handle_pull_light_04.ogg +0 -0
  67. package/assets/sfx/armas/charging_handle_pull_medium_01.ogg +0 -0
  68. package/assets/sfx/armas/charging_handle_pull_medium_02.ogg +0 -0
  69. package/assets/sfx/armas/charging_handle_pull_medium_03.ogg +0 -0
  70. package/assets/sfx/armas/charging_handle_pull_medium_04.ogg +0 -0
  71. package/assets/sfx/armas/charging_handle_pull_medium_05.ogg +0 -0
  72. package/assets/sfx/armas/charging_handle_release_medium_01.ogg +0 -0
  73. package/assets/sfx/armas/charging_handle_release_medium_02.ogg +0 -0
  74. package/assets/sfx/armas/charging_handle_release_medium_03.ogg +0 -0
  75. package/assets/sfx/armas/charging_handle_release_medium_04.ogg +0 -0
  76. package/assets/sfx/armas/charging_handle_release_medium_05.ogg +0 -0
  77. package/assets/sfx/armas/cylinder_close_light_01.ogg +0 -0
  78. package/assets/sfx/armas/cylinder_close_light_02.ogg +0 -0
  79. package/assets/sfx/armas/cylinder_close_light_03.ogg +0 -0
  80. package/assets/sfx/armas/cylinder_close_light_04.ogg +0 -0
  81. package/assets/sfx/armas/cylinder_close_light_05.ogg +0 -0
  82. package/assets/sfx/armas/cylinder_eject_light_01.ogg +0 -0
  83. package/assets/sfx/armas/cylinder_eject_light_02.ogg +0 -0
  84. package/assets/sfx/armas/cylinder_eject_light_03.ogg +0 -0
  85. package/assets/sfx/armas/cylinder_open_light_01.ogg +0 -0
  86. package/assets/sfx/armas/cylinder_open_light_02.ogg +0 -0
  87. package/assets/sfx/armas/cylinder_open_light_03.ogg +0 -0
  88. package/assets/sfx/armas/cylinder_open_light_04.ogg +0 -0
  89. package/assets/sfx/armas/cylinder_open_light_05.ogg +0 -0
  90. package/assets/sfx/armas/lever_close_medium_01.ogg +0 -0
  91. package/assets/sfx/armas/lever_close_medium_02.ogg +0 -0
  92. package/assets/sfx/armas/lever_open_medium_01.ogg +0 -0
  93. package/assets/sfx/armas/lever_open_medium_02.ogg +0 -0
  94. package/assets/sfx/armas/mag_out_heavy_01.ogg +0 -0
  95. package/assets/sfx/armas/mag_out_heavy_02.ogg +0 -0
  96. package/assets/sfx/armas/mag_out_light_01.ogg +0 -0
  97. package/assets/sfx/armas/mag_out_light_02.ogg +0 -0
  98. package/assets/sfx/armas/mag_out_light_03.ogg +0 -0
  99. package/assets/sfx/armas/mag_out_light_04.ogg +0 -0
  100. package/assets/sfx/armas/mag_out_medium_01.ogg +0 -0
  101. package/assets/sfx/armas/mag_out_medium_02.ogg +0 -0
  102. package/assets/sfx/armas/mag_out_medium_03.ogg +0 -0
  103. package/assets/sfx/armas/mag_seat_heavy_01.ogg +0 -0
  104. package/assets/sfx/armas/mag_seat_heavy_02.ogg +0 -0
  105. package/assets/sfx/armas/mag_seat_light_01.ogg +0 -0
  106. package/assets/sfx/armas/mag_seat_light_02.ogg +0 -0
  107. package/assets/sfx/armas/mag_seat_light_03.ogg +0 -0
  108. package/assets/sfx/armas/mag_seat_light_04.ogg +0 -0
  109. package/assets/sfx/armas/mag_seat_light_05.ogg +0 -0
  110. package/assets/sfx/armas/mag_seat_light_06.ogg +0 -0
  111. package/assets/sfx/armas/mag_seat_medium_01.ogg +0 -0
  112. package/assets/sfx/armas/mag_seat_medium_02.ogg +0 -0
  113. package/assets/sfx/armas/mag_seat_medium_03.ogg +0 -0
  114. package/assets/sfx/armas/pistol_22lr_close_01.ogg +0 -0
  115. package/assets/sfx/armas/pistol_22lr_close_02.ogg +0 -0
  116. package/assets/sfx/armas/pistol_22lr_far_01.ogg +0 -0
  117. package/assets/sfx/armas/pistol_22lr_far_02.ogg +0 -0
  118. package/assets/sfx/armas/pistol_22lr_far_03.ogg +0 -0
  119. package/assets/sfx/armas/pistol_22lr_far_04.ogg +0 -0
  120. package/assets/sfx/armas/pistol_45_close_01.ogg +0 -0
  121. package/assets/sfx/armas/pistol_45_close_02.ogg +0 -0
  122. package/assets/sfx/armas/pistol_45_close_03.ogg +0 -0
  123. package/assets/sfx/armas/pistol_45_close_04.ogg +0 -0
  124. package/assets/sfx/armas/pistol_45_close_05.ogg +0 -0
  125. package/assets/sfx/armas/pistol_45_far_01.ogg +0 -0
  126. package/assets/sfx/armas/pistol_45_far_02.ogg +0 -0
  127. package/assets/sfx/armas/pistol_45_far_03.ogg +0 -0
  128. package/assets/sfx/armas/pistol_45_far_04.ogg +0 -0
  129. package/assets/sfx/armas/pistol_9mm_close_01.ogg +0 -0
  130. package/assets/sfx/armas/pistol_9mm_close_02.ogg +0 -0
  131. package/assets/sfx/armas/pistol_9mm_close_03.ogg +0 -0
  132. package/assets/sfx/armas/pistol_9mm_close_04.ogg +0 -0
  133. package/assets/sfx/armas/pistol_9mm_close_05.ogg +0 -0
  134. package/assets/sfx/armas/pistol_9mm_close_06.ogg +0 -0
  135. package/assets/sfx/armas/pistol_9mm_far_01.ogg +0 -0
  136. package/assets/sfx/armas/pistol_9mm_far_02.ogg +0 -0
  137. package/assets/sfx/armas/pistol_9mm_far_03.ogg +0 -0
  138. package/assets/sfx/armas/pistol_9mm_far_04.ogg +0 -0
  139. package/assets/sfx/armas/pump_back_heavy_01.ogg +0 -0
  140. package/assets/sfx/armas/pump_back_heavy_02.ogg +0 -0
  141. package/assets/sfx/armas/pump_back_heavy_03.ogg +0 -0
  142. package/assets/sfx/armas/pump_back_heavy_04.ogg +0 -0
  143. package/assets/sfx/armas/pump_back_heavy_05.ogg +0 -0
  144. package/assets/sfx/armas/pump_forward_heavy_01.ogg +0 -0
  145. package/assets/sfx/armas/pump_forward_heavy_02.ogg +0 -0
  146. package/assets/sfx/armas/pump_forward_heavy_03.ogg +0 -0
  147. package/assets/sfx/armas/revolver_38_357_close_01.ogg +0 -0
  148. package/assets/sfx/armas/revolver_38_357_close_02.ogg +0 -0
  149. package/assets/sfx/armas/revolver_38_357_close_03.ogg +0 -0
  150. package/assets/sfx/armas/revolver_38_357_close_04.ogg +0 -0
  151. package/assets/sfx/armas/revolver_38_357_far_01.ogg +0 -0
  152. package/assets/sfx/armas/revolver_38_357_far_02.ogg +0 -0
  153. package/assets/sfx/armas/revolver_38_357_far_03.ogg +0 -0
  154. package/assets/sfx/armas/revolver_38_357_far_04.ogg +0 -0
  155. package/assets/sfx/armas/rifle_308_3006_close_01.ogg +0 -0
  156. package/assets/sfx/armas/rifle_308_3006_close_02.ogg +0 -0
  157. package/assets/sfx/armas/rifle_308_3006_close_03.ogg +0 -0
  158. package/assets/sfx/armas/rifle_308_3006_close_04.ogg +0 -0
  159. package/assets/sfx/armas/rifle_308_3006_close_05.ogg +0 -0
  160. package/assets/sfx/armas/rifle_308_3006_close_06.ogg +0 -0
  161. package/assets/sfx/armas/rifle_308_3006_far_01.ogg +0 -0
  162. package/assets/sfx/armas/rifle_308_3006_far_02.ogg +0 -0
  163. package/assets/sfx/armas/rifle_308_3006_far_03.ogg +0 -0
  164. package/assets/sfx/armas/rifle_308_3006_far_04.ogg +0 -0
  165. package/assets/sfx/armas/rifle_308_3006_far_05.ogg +0 -0
  166. package/assets/sfx/armas/rifle_308_3006_far_06.ogg +0 -0
  167. package/assets/sfx/armas/rifle_5_56_close_01.ogg +0 -0
  168. package/assets/sfx/armas/rifle_5_56_close_02.ogg +0 -0
  169. package/assets/sfx/armas/rifle_5_56_close_03.ogg +0 -0
  170. package/assets/sfx/armas/rifle_5_56_close_04.ogg +0 -0
  171. package/assets/sfx/armas/rifle_5_56_close_05.ogg +0 -0
  172. package/assets/sfx/armas/rifle_5_56_far_01.ogg +0 -0
  173. package/assets/sfx/armas/rifle_5_56_far_02.ogg +0 -0
  174. package/assets/sfx/armas/rifle_5_56_far_03.ogg +0 -0
  175. package/assets/sfx/armas/rifle_5_56_far_04.ogg +0 -0
  176. package/assets/sfx/armas/rifle_7_62x39_close_01.ogg +0 -0
  177. package/assets/sfx/armas/rifle_7_62x39_close_02.ogg +0 -0
  178. package/assets/sfx/armas/rifle_7_62x39_close_03.ogg +0 -0
  179. package/assets/sfx/armas/rifle_7_62x39_close_04.ogg +0 -0
  180. package/assets/sfx/armas/rifle_7_62x39_close_05.ogg +0 -0
  181. package/assets/sfx/armas/rifle_7_62x39_close_06.ogg +0 -0
  182. package/assets/sfx/armas/rifle_7_62x39_close_07.ogg +0 -0
  183. package/assets/sfx/armas/rifle_7_62x39_close_08.ogg +0 -0
  184. package/assets/sfx/armas/rifle_7_62x39_close_09.ogg +0 -0
  185. package/assets/sfx/armas/rifle_7_62x39_close_10.ogg +0 -0
  186. package/assets/sfx/armas/rifle_7_62x39_close_11.ogg +0 -0
  187. package/assets/sfx/armas/rifle_7_62x39_close_12.ogg +0 -0
  188. package/assets/sfx/armas/rifle_7_62x39_far_01.ogg +0 -0
  189. package/assets/sfx/armas/rifle_7_62x39_far_02.ogg +0 -0
  190. package/assets/sfx/armas/rifle_7_62x39_far_03.ogg +0 -0
  191. package/assets/sfx/armas/shell_insert_heavy_01.ogg +0 -0
  192. package/assets/sfx/armas/shell_insert_heavy_02.ogg +0 -0
  193. package/assets/sfx/armas/shell_insert_heavy_03.ogg +0 -0
  194. package/assets/sfx/armas/shell_insert_heavy_04.ogg +0 -0
  195. package/assets/sfx/armas/shell_insert_heavy_05.ogg +0 -0
  196. package/assets/sfx/armas/shell_insert_heavy_06.ogg +0 -0
  197. package/assets/sfx/armas/shell_insert_heavy_07.ogg +0 -0
  198. package/assets/sfx/armas/shell_insert_heavy_08.ogg +0 -0
  199. package/assets/sfx/armas/shell_insert_heavy_09.ogg +0 -0
  200. package/assets/sfx/armas/shotgun_12_close_01.ogg +0 -0
  201. package/assets/sfx/armas/shotgun_12_close_02.ogg +0 -0
  202. package/assets/sfx/armas/shotgun_12_close_03.ogg +0 -0
  203. package/assets/sfx/armas/shotgun_12_close_04.ogg +0 -0
  204. package/assets/sfx/armas/shotgun_12_close_05.ogg +0 -0
  205. package/assets/sfx/armas/shotgun_12_close_06.ogg +0 -0
  206. package/assets/sfx/armas/shotgun_12_far_01.ogg +0 -0
  207. package/assets/sfx/armas/shotgun_12_far_02.ogg +0 -0
  208. package/assets/sfx/armas/shotgun_12_far_03.ogg +0 -0
  209. package/assets/sfx/armas/shotgun_12_far_04.ogg +0 -0
  210. package/assets/sfx/armas/shotgun_12_far_05.ogg +0 -0
  211. package/assets/sfx/armas/shotgun_12_far_06.ogg +0 -0
  212. package/assets/sfx/armas/slide_release_light_01.ogg +0 -0
  213. package/assets/sfx/armas/slide_release_light_02.ogg +0 -0
  214. package/assets/sfx/armas/slide_release_light_03.ogg +0 -0
  215. package/assets/sfx/armas/slide_release_light_04.ogg +0 -0
  216. package/assets/sfx/armas/slide_release_light_05.ogg +0 -0
  217. package/assets/sfx/armas/slide_release_light_06.ogg +0 -0
  218. package/assets/sfx/armas/slide_release_medium_01.ogg +0 -0
  219. package/assets/sfx/armas/slide_release_medium_02.ogg +0 -0
  220. package/assets/sfx/armas/slide_release_medium_03.ogg +0 -0
  221. package/assets/sfx/armas/slide_release_medium_04.ogg +0 -0
  222. package/assets/sfx/armas/sniper_338_300wm_close_01.ogg +0 -0
  223. package/assets/sfx/armas/sniper_338_300wm_close_02.ogg +0 -0
  224. package/assets/sfx/armas/sniper_338_300wm_close_03.ogg +0 -0
  225. package/assets/sfx/armas/sniper_338_300wm_close_04.ogg +0 -0
  226. package/assets/sfx/armas/sniper_338_300wm_close_05.ogg +0 -0
  227. package/assets/sfx/armas/sniper_338_300wm_close_06.ogg +0 -0
  228. package/assets/sfx/armas/sniper_338_300wm_close_07.ogg +0 -0
  229. package/assets/sfx/armas/sniper_338_300wm_far_01.ogg +0 -0
  230. package/assets/sfx/armas/sniper_338_300wm_far_02.ogg +0 -0
  231. package/assets/sfx/armas/sniper_338_300wm_far_03.ogg +0 -0
  232. package/assets/sfx/armas/sniper_338_300wm_far_04.ogg +0 -0
  233. package/assets/sfx/armas/sniper_338_300wm_far_05.ogg +0 -0
  234. package/assets/sfx/armas/sniper_338_300wm_far_06.ogg +0 -0
  235. package/assets/sfx/armas/speedloader_light_01.ogg +0 -0
  236. package/assets/sfx/armas/speedloader_light_02.ogg +0 -0
  237. package/assets/sfx/armas/speedloader_light_03.ogg +0 -0
  238. package/assets/sfx/armas/speedloader_light_04.ogg +0 -0
  239. package/assets/sfx/armas/speedloader_light_05.ogg +0 -0
  240. package/assets/sfx/armas/speedloader_light_06.ogg +0 -0
  241. package/assets/sfx/armas/speedloader_light_07.ogg +0 -0
  242. package/assets/sfx/armas/speedloader_light_08.ogg +0 -0
  243. package/assets/sfx/armas/suppressed_pistol_close_01.ogg +0 -0
  244. package/assets/sfx/armas/suppressed_pistol_close_02.ogg +0 -0
  245. package/assets/sfx/armas/suppressed_pistol_close_03.ogg +0 -0
  246. package/assets/sfx/armas/suppressed_pistol_close_04.ogg +0 -0
  247. package/assets/sfx/armas/suppressed_pistol_close_05.ogg +0 -0
  248. package/assets/sfx/armas/suppressed_pistol_far_01.ogg +0 -0
  249. package/assets/sfx/armas/suppressed_pistol_far_02.ogg +0 -0
  250. package/assets/sfx/armas/suppressed_pistol_far_03.ogg +0 -0
  251. package/assets/sfx/armas/suppressed_pistol_far_04.ogg +0 -0
  252. package/assets/sfx/armas/suppressed_pistol_far_05.ogg +0 -0
  253. package/assets/sfx/armas/suppressed_rifle_close_01.ogg +0 -0
  254. package/assets/sfx/armas/suppressed_rifle_close_02.ogg +0 -0
  255. package/assets/sfx/armas/suppressed_rifle_close_03.ogg +0 -0
  256. package/assets/sfx/armas/suppressed_rifle_close_04.ogg +0 -0
  257. package/assets/sfx/armas/suppressed_rifle_far_01.ogg +0 -0
  258. package/assets/sfx/armas/suppressed_rifle_far_02.ogg +0 -0
  259. package/assets/sfx/armas/suppressed_rifle_far_03.ogg +0 -0
  260. package/assets/sfx/armas/suppressed_rifle_far_04.ogg +0 -0
  261. package/assets/sfx/explosoes-fogo/debris_rain_mixed_01.ogg +0 -0
  262. package/assets/sfx/explosoes-fogo/debris_rain_mixed_02.ogg +0 -0
  263. package/assets/sfx/explosoes-fogo/debris_rain_mixed_03.ogg +0 -0
  264. package/assets/sfx/explosoes-fogo/debris_rain_mixed_04.ogg +0 -0
  265. package/assets/sfx/explosoes-fogo/debris_rain_mixed_05.ogg +0 -0
  266. package/assets/sfx/explosoes-fogo/debris_rain_mixed_06.ogg +0 -0
  267. package/assets/sfx/explosoes-fogo/debris_rain_mixed_07.ogg +0 -0
  268. package/assets/sfx/explosoes-fogo/debris_rain_stone_01.ogg +0 -0
  269. package/assets/sfx/explosoes-fogo/debris_rain_stone_02.ogg +0 -0
  270. package/assets/sfx/explosoes-fogo/debris_rain_stone_03.ogg +0 -0
  271. package/assets/sfx/explosoes-fogo/debris_rain_stone_04.ogg +0 -0
  272. package/assets/sfx/explosoes-fogo/debris_rain_stone_05.ogg +0 -0
  273. package/assets/sfx/explosoes-fogo/debris_rain_stone_06.ogg +0 -0
  274. package/assets/sfx/explosoes-fogo/debris_rain_stone_07.ogg +0 -0
  275. package/assets/sfx/explosoes-fogo/debris_rain_stone_08.ogg +0 -0
  276. package/assets/sfx/explosoes-fogo/debris_rain_stone_09.ogg +0 -0
  277. package/assets/sfx/explosoes-fogo/explosion_big_01.ogg +0 -0
  278. package/assets/sfx/explosoes-fogo/explosion_big_02.ogg +0 -0
  279. package/assets/sfx/explosoes-fogo/explosion_big_03.ogg +0 -0
  280. package/assets/sfx/explosoes-fogo/explosion_big_04.ogg +0 -0
  281. package/assets/sfx/explosoes-fogo/explosion_big_05.ogg +0 -0
  282. package/assets/sfx/explosoes-fogo/explosion_car_01.ogg +0 -0
  283. package/assets/sfx/explosoes-fogo/explosion_car_02.ogg +0 -0
  284. package/assets/sfx/explosoes-fogo/explosion_car_03.ogg +0 -0
  285. package/assets/sfx/explosoes-fogo/explosion_car_04.ogg +0 -0
  286. package/assets/sfx/explosoes-fogo/explosion_far_close_01.ogg +0 -0
  287. package/assets/sfx/explosoes-fogo/explosion_far_close_02.ogg +0 -0
  288. package/assets/sfx/explosoes-fogo/explosion_far_close_03.ogg +0 -0
  289. package/assets/sfx/explosoes-fogo/explosion_far_close_04.ogg +0 -0
  290. package/assets/sfx/explosoes-fogo/explosion_flashbang_01.ogg +0 -0
  291. package/assets/sfx/explosoes-fogo/explosion_flashbang_02.ogg +0 -0
  292. package/assets/sfx/explosoes-fogo/explosion_grenade_01.ogg +0 -0
  293. package/assets/sfx/explosoes-fogo/explosion_grenade_02.ogg +0 -0
  294. package/assets/sfx/explosoes-fogo/explosion_grenade_03.ogg +0 -0
  295. package/assets/sfx/explosoes-fogo/explosion_grenade_04.ogg +0 -0
  296. package/assets/sfx/explosoes-fogo/explosion_grenade_05.ogg +0 -0
  297. package/assets/sfx/explosoes-fogo/explosion_grenade_06.ogg +0 -0
  298. package/assets/sfx/explosoes-fogo/explosion_small_bang_01.ogg +0 -0
  299. package/assets/sfx/explosoes-fogo/explosion_small_bang_02.ogg +0 -0
  300. package/assets/sfx/explosoes-fogo/explosion_small_bang_03.ogg +0 -0
  301. package/assets/sfx/explosoes-fogo/explosion_small_bang_04.ogg +0 -0
  302. package/assets/sfx/explosoes-fogo/explosion_small_bang_05.ogg +0 -0
  303. package/assets/sfx/explosoes-fogo/explosion_small_bang_06.ogg +0 -0
  304. package/assets/sfx/explosoes-fogo/explosion_small_bang_07.ogg +0 -0
  305. package/assets/sfx/explosoes-fogo/explosion_small_bang_08.ogg +0 -0
  306. package/assets/sfx/explosoes-fogo/explosion_small_bang_09.ogg +0 -0
  307. package/assets/sfx/explosoes-fogo/explosion_small_bang_10.ogg +0 -0
  308. package/assets/sfx/explosoes-fogo/fire_crackle_01.ogg +0 -0
  309. package/assets/sfx/explosoes-fogo/fire_crackle_02.ogg +0 -0
  310. package/assets/sfx/explosoes-fogo/fire_crackle_03.ogg +0 -0
  311. package/assets/sfx/explosoes-fogo/fire_crackle_05.ogg +0 -0
  312. package/assets/sfx/explosoes-fogo/fire_crackle_07.ogg +0 -0
  313. package/assets/sfx/explosoes-fogo/fire_extinguish_01.ogg +0 -0
  314. package/assets/sfx/explosoes-fogo/fire_extinguish_02.ogg +0 -0
  315. package/assets/sfx/explosoes-fogo/fire_ignite_01.ogg +0 -0
  316. package/assets/sfx/explosoes-fogo/fire_ignite_02.ogg +0 -0
  317. package/assets/sfx/explosoes-fogo/fire_ignite_03.ogg +0 -0
  318. package/assets/sfx/explosoes-fogo/fire_ignite_04.ogg +0 -0
  319. package/assets/sfx/explosoes-fogo/fire_loop_01.ogg +0 -0
  320. package/assets/sfx/explosoes-fogo/fire_loop_03.ogg +0 -0
  321. package/assets/sfx/explosoes-fogo/fire_loop_04.ogg +0 -0
  322. package/assets/sfx/explosoes-fogo/fire_loop_small_01.ogg +0 -0
  323. package/assets/sfx/explosoes-fogo/fire_pop_01.ogg +0 -0
  324. package/assets/sfx/explosoes-fogo/fire_pop_02.ogg +0 -0
  325. package/assets/sfx/explosoes-fogo/fire_pop_03.ogg +0 -0
  326. package/assets/sfx/explosoes-fogo/flamethrower_loop_01.ogg +0 -0
  327. package/assets/sfx/explosoes-fogo/gas_leak_01.ogg +0 -0
  328. package/assets/sfx/explosoes-fogo/molotov_break_ignite_01.ogg +0 -0
  329. package/assets/sfx/explosoes-fogo/molotov_break_ignite_02.ogg +0 -0
  330. package/assets/sfx/impactos/ceramic_hit_close_01.ogg +0 -0
  331. package/assets/sfx/impactos/concrete_block_drag_close_01.ogg +0 -0
  332. package/assets/sfx/impactos/concrete_block_drag_close_02.ogg +0 -0
  333. package/assets/sfx/impactos/concrete_block_drag_close_03.ogg +0 -0
  334. package/assets/sfx/impactos/concrete_block_drag_close_04.ogg +0 -0
  335. package/assets/sfx/impactos/concrete_block_drag_close_05.ogg +0 -0
  336. package/assets/sfx/impactos/concrete_block_drag_close_06.ogg +0 -0
  337. package/assets/sfx/impactos/concrete_block_drag_close_07.ogg +0 -0
  338. package/assets/sfx/impactos/crack_close_01.ogg +0 -0
  339. package/assets/sfx/impactos/crack_close_02.ogg +0 -0
  340. package/assets/sfx/impactos/crack_close_03.ogg +0 -0
  341. package/assets/sfx/impactos/crack_close_04.ogg +0 -0
  342. package/assets/sfx/impactos/crack_close_05.ogg +0 -0
  343. package/assets/sfx/impactos/crack_close_06.ogg +0 -0
  344. package/assets/sfx/impactos/crack_close_07.ogg +0 -0
  345. package/assets/sfx/impactos/crack_close_08.ogg +0 -0
  346. package/assets/sfx/impactos/crack_close_09.ogg +0 -0
  347. package/assets/sfx/impactos/crack_close_10.ogg +0 -0
  348. package/assets/sfx/impactos/crumble_close_01.ogg +0 -0
  349. package/assets/sfx/impactos/crumble_close_02.ogg +0 -0
  350. package/assets/sfx/impactos/crumble_close_03.ogg +0 -0
  351. package/assets/sfx/impactos/crumble_close_04.ogg +0 -0
  352. package/assets/sfx/impactos/crumble_close_05.ogg +0 -0
  353. package/assets/sfx/impactos/flesh_fruit_splat_close_01.ogg +0 -0
  354. package/assets/sfx/impactos/flesh_fruit_splat_close_02.ogg +0 -0
  355. package/assets/sfx/impactos/flesh_fruit_splat_close_03.ogg +0 -0
  356. package/assets/sfx/impactos/furniture_push_wood_close_01.ogg +0 -0
  357. package/assets/sfx/impactos/glass_blunt_heavy_close_01.ogg +0 -0
  358. package/assets/sfx/impactos/glass_blunt_heavy_close_02.ogg +0 -0
  359. package/assets/sfx/impactos/glass_blunt_heavy_close_03.ogg +0 -0
  360. package/assets/sfx/impactos/glass_blunt_heavy_close_04.ogg +0 -0
  361. package/assets/sfx/impactos/glass_blunt_heavy_close_05.ogg +0 -0
  362. package/assets/sfx/impactos/glass_blunt_light_close_01.ogg +0 -0
  363. package/assets/sfx/impactos/glass_blunt_light_close_02.ogg +0 -0
  364. package/assets/sfx/impactos/glass_blunt_light_close_03.ogg +0 -0
  365. package/assets/sfx/impactos/glass_blunt_light_close_04.ogg +0 -0
  366. package/assets/sfx/impactos/glass_blunt_light_close_05.ogg +0 -0
  367. package/assets/sfx/impactos/glass_blunt_medium_close_01.ogg +0 -0
  368. package/assets/sfx/impactos/glass_blunt_medium_close_02.ogg +0 -0
  369. package/assets/sfx/impactos/glass_blunt_medium_close_03.ogg +0 -0
  370. package/assets/sfx/impactos/glass_blunt_medium_close_04.ogg +0 -0
  371. package/assets/sfx/impactos/glass_blunt_medium_close_05.ogg +0 -0
  372. package/assets/sfx/impactos/glass_bottle_break_close_01.ogg +0 -0
  373. package/assets/sfx/impactos/glass_debris_fall_close_01.ogg +0 -0
  374. package/assets/sfx/impactos/glass_debris_fall_close_02.ogg +0 -0
  375. package/assets/sfx/impactos/glass_debris_fall_close_03.ogg +0 -0
  376. package/assets/sfx/impactos/glass_debris_fall_close_04.ogg +0 -0
  377. package/assets/sfx/impactos/glass_shatter_close_01.ogg +0 -0
  378. package/assets/sfx/impactos/glass_shatter_close_02.ogg +0 -0
  379. package/assets/sfx/impactos/glass_shatter_close_03.ogg +0 -0
  380. package/assets/sfx/impactos/glass_shatter_close_04.ogg +0 -0
  381. package/assets/sfx/impactos/glass_shatter_close_05.ogg +0 -0
  382. package/assets/sfx/impactos/glass_shatter_close_06.ogg +0 -0
  383. package/assets/sfx/impactos/glass_shatter_close_07.ogg +0 -0
  384. package/assets/sfx/impactos/glass_shatter_close_08.ogg +0 -0
  385. package/assets/sfx/impactos/glass_shatter_close_09.ogg +0 -0
  386. package/assets/sfx/impactos/gravel_hit_close_21.ogg +0 -0
  387. package/assets/sfx/impactos/gravel_hit_close_22.ogg +0 -0
  388. package/assets/sfx/impactos/gravel_hit_close_23.ogg +0 -0
  389. package/assets/sfx/impactos/gravel_hit_close_24.ogg +0 -0
  390. package/assets/sfx/impactos/gravel_hit_close_25.ogg +0 -0
  391. package/assets/sfx/impactos/gravel_hit_close_26.ogg +0 -0
  392. package/assets/sfx/impactos/gravel_hit_close_27.ogg +0 -0
  393. package/assets/sfx/impactos/gravel_hit_close_28.ogg +0 -0
  394. package/assets/sfx/impactos/gravel_hit_close_29.ogg +0 -0
  395. package/assets/sfx/impactos/impact_generic_light_close_01.ogg +0 -0
  396. package/assets/sfx/impactos/impact_generic_light_close_02.ogg +0 -0
  397. package/assets/sfx/impactos/impact_generic_light_close_03.ogg +0 -0
  398. package/assets/sfx/impactos/impact_generic_light_close_04.ogg +0 -0
  399. package/assets/sfx/impactos/impact_generic_light_close_05.ogg +0 -0
  400. package/assets/sfx/impactos/masonry_blunt_close_01.ogg +0 -0
  401. package/assets/sfx/impactos/masonry_blunt_close_02.ogg +0 -0
  402. package/assets/sfx/impactos/masonry_blunt_close_03.ogg +0 -0
  403. package/assets/sfx/impactos/masonry_blunt_close_04.ogg +0 -0
  404. package/assets/sfx/impactos/masonry_blunt_close_05.ogg +0 -0
  405. package/assets/sfx/impactos/masonry_blunt_close_06.ogg +0 -0
  406. package/assets/sfx/impactos/masonry_blunt_close_07.ogg +0 -0
  407. package/assets/sfx/impactos/masonry_bullet_close_01.ogg +0 -0
  408. package/assets/sfx/impactos/masonry_bullet_close_02.ogg +0 -0
  409. package/assets/sfx/impactos/masonry_bullet_close_03.ogg +0 -0
  410. package/assets/sfx/impactos/masonry_bullet_close_04.ogg +0 -0
  411. package/assets/sfx/impactos/masonry_bullet_close_05.ogg +0 -0
  412. package/assets/sfx/impactos/masonry_bullet_close_21.ogg +0 -0
  413. package/assets/sfx/impactos/masonry_bullet_close_22.ogg +0 -0
  414. package/assets/sfx/impactos/masonry_bullet_close_23.ogg +0 -0
  415. package/assets/sfx/impactos/masonry_bullet_close_24.ogg +0 -0
  416. package/assets/sfx/impactos/masonry_bullet_close_25.ogg +0 -0
  417. package/assets/sfx/impactos/masonry_bullet_close_26.ogg +0 -0
  418. package/assets/sfx/impactos/masonry_bullet_close_27.ogg +0 -0
  419. package/assets/sfx/impactos/masonry_bullet_close_28.ogg +0 -0
  420. package/assets/sfx/impactos/metal_blunt_close_01.ogg +0 -0
  421. package/assets/sfx/impactos/metal_blunt_close_02.ogg +0 -0
  422. package/assets/sfx/impactos/metal_blunt_close_03.ogg +0 -0
  423. package/assets/sfx/impactos/metal_blunt_close_04.ogg +0 -0
  424. package/assets/sfx/impactos/metal_blunt_close_05.ogg +0 -0
  425. package/assets/sfx/impactos/metal_blunt_heavy_close_01.ogg +0 -0
  426. package/assets/sfx/impactos/metal_blunt_heavy_close_02.ogg +0 -0
  427. package/assets/sfx/impactos/metal_blunt_heavy_close_03.ogg +0 -0
  428. package/assets/sfx/impactos/metal_blunt_heavy_close_04.ogg +0 -0
  429. package/assets/sfx/impactos/metal_blunt_heavy_close_05.ogg +0 -0
  430. package/assets/sfx/impactos/metal_blunt_light_close_01.ogg +0 -0
  431. package/assets/sfx/impactos/metal_blunt_light_close_02.ogg +0 -0
  432. package/assets/sfx/impactos/metal_blunt_light_close_03.ogg +0 -0
  433. package/assets/sfx/impactos/metal_blunt_light_close_04.ogg +0 -0
  434. package/assets/sfx/impactos/metal_blunt_light_close_05.ogg +0 -0
  435. package/assets/sfx/impactos/metal_blunt_medium_close_01.ogg +0 -0
  436. package/assets/sfx/impactos/metal_blunt_medium_close_02.ogg +0 -0
  437. package/assets/sfx/impactos/metal_blunt_medium_close_03.ogg +0 -0
  438. package/assets/sfx/impactos/metal_blunt_medium_close_04.ogg +0 -0
  439. package/assets/sfx/impactos/metal_blunt_medium_close_05.ogg +0 -0
  440. package/assets/sfx/impactos/metal_bullet_close_01.ogg +0 -0
  441. package/assets/sfx/impactos/metal_bullet_close_02.ogg +0 -0
  442. package/assets/sfx/impactos/metal_bullet_close_03.ogg +0 -0
  443. package/assets/sfx/impactos/metal_bullet_close_04.ogg +0 -0
  444. package/assets/sfx/impactos/metal_bullet_close_05.ogg +0 -0
  445. package/assets/sfx/impactos/metal_bullet_close_06.ogg +0 -0
  446. package/assets/sfx/impactos/metal_bullet_close_21.ogg +0 -0
  447. package/assets/sfx/impactos/metal_bullet_close_22.ogg +0 -0
  448. package/assets/sfx/impactos/metal_bullet_close_23.ogg +0 -0
  449. package/assets/sfx/impactos/metal_bullet_close_24.ogg +0 -0
  450. package/assets/sfx/impactos/metal_bullet_close_25.ogg +0 -0
  451. package/assets/sfx/impactos/metal_bullet_close_26.ogg +0 -0
  452. package/assets/sfx/impactos/metal_bullet_close_27.ogg +0 -0
  453. package/assets/sfx/impactos/metal_bullet_close_28.ogg +0 -0
  454. package/assets/sfx/impactos/metal_bullet_close_29.ogg +0 -0
  455. package/assets/sfx/impactos/metal_bullet_close_30.ogg +0 -0
  456. package/assets/sfx/impactos/metal_bullet_close_31.ogg +0 -0
  457. package/assets/sfx/impactos/metal_bullet_close_32.ogg +0 -0
  458. package/assets/sfx/impactos/metal_bullet_close_33.ogg +0 -0
  459. package/assets/sfx/impactos/metal_bullet_close_34.ogg +0 -0
  460. package/assets/sfx/impactos/metal_fall_close_01.ogg +0 -0
  461. package/assets/sfx/impactos/metal_fall_close_02.ogg +0 -0
  462. package/assets/sfx/impactos/metal_fall_close_03.ogg +0 -0
  463. package/assets/sfx/impactos/metal_fall_close_04.ogg +0 -0
  464. package/assets/sfx/impactos/metal_fall_close_05.ogg +0 -0
  465. package/assets/sfx/impactos/metal_fall_close_06.ogg +0 -0
  466. package/assets/sfx/impactos/metal_fall_close_07.ogg +0 -0
  467. package/assets/sfx/impactos/metal_fall_close_08.ogg +0 -0
  468. package/assets/sfx/impactos/metal_fall_close_09.ogg +0 -0
  469. package/assets/sfx/impactos/metal_fall_close_10.ogg +0 -0
  470. package/assets/sfx/impactos/metal_thin_close_01.ogg +0 -0
  471. package/assets/sfx/impactos/metal_thin_close_02.ogg +0 -0
  472. package/assets/sfx/impactos/metal_thin_close_03.ogg +0 -0
  473. package/assets/sfx/impactos/metal_thin_close_04.ogg +0 -0
  474. package/assets/sfx/impactos/metal_thin_close_05.ogg +0 -0
  475. package/assets/sfx/impactos/metal_thin_close_06.ogg +0 -0
  476. package/assets/sfx/impactos/metal_thin_close_07.ogg +0 -0
  477. package/assets/sfx/impactos/metal_thin_close_08.ogg +0 -0
  478. package/assets/sfx/impactos/metal_thin_close_09.ogg +0 -0
  479. package/assets/sfx/impactos/metal_thin_close_10.ogg +0 -0
  480. package/assets/sfx/impactos/metal_thin_close_11.ogg +0 -0
  481. package/assets/sfx/impactos/metal_thin_close_12.ogg +0 -0
  482. package/assets/sfx/impactos/metal_thin_close_13.ogg +0 -0
  483. package/assets/sfx/impactos/metal_thin_close_14.ogg +0 -0
  484. package/assets/sfx/impactos/metal_thin_close_15.ogg +0 -0
  485. package/assets/sfx/impactos/metal_thin_close_16.ogg +0 -0
  486. package/assets/sfx/impactos/metal_thin_close_17.ogg +0 -0
  487. package/assets/sfx/impactos/metal_thin_close_18.ogg +0 -0
  488. package/assets/sfx/impactos/metal_thin_close_19.ogg +0 -0
  489. package/assets/sfx/impactos/metal_thin_close_20.ogg +0 -0
  490. package/assets/sfx/impactos/metal_thin_close_21.ogg +0 -0
  491. package/assets/sfx/impactos/metal_thin_close_22.ogg +0 -0
  492. package/assets/sfx/impactos/metal_thin_close_23.ogg +0 -0
  493. package/assets/sfx/impactos/metal_thin_close_24.ogg +0 -0
  494. package/assets/sfx/impactos/metal_thin_close_25.ogg +0 -0
  495. package/assets/sfx/impactos/metal_thin_close_26.ogg +0 -0
  496. package/assets/sfx/impactos/paper_tear_close_01.ogg +0 -0
  497. package/assets/sfx/impactos/paper_tear_close_02.ogg +0 -0
  498. package/assets/sfx/impactos/plastic_hit_close_01.ogg +0 -0
  499. package/assets/sfx/impactos/plastic_hit_close_02.ogg +0 -0
  500. package/assets/sfx/impactos/plastic_hit_close_03.ogg +0 -0
  501. package/assets/sfx/impactos/plastic_hit_close_04.ogg +0 -0
  502. package/assets/sfx/impactos/ricochet_metal_close_21.ogg +0 -0
  503. package/assets/sfx/impactos/ricochet_metal_close_22.ogg +0 -0
  504. package/assets/sfx/impactos/ricochet_metal_close_23.ogg +0 -0
  505. package/assets/sfx/impactos/ricochet_metal_close_24.ogg +0 -0
  506. package/assets/sfx/impactos/ricochet_metal_close_25.ogg +0 -0
  507. package/assets/sfx/impactos/ricochet_metal_close_26.ogg +0 -0
  508. package/assets/sfx/impactos/ricochet_metal_close_27.ogg +0 -0
  509. package/assets/sfx/impactos/ricochet_metal_close_28.ogg +0 -0
  510. package/assets/sfx/impactos/rubble_falling_close_01.ogg +0 -0
  511. package/assets/sfx/impactos/rubble_falling_close_02.ogg +0 -0
  512. package/assets/sfx/impactos/rubble_falling_close_03.ogg +0 -0
  513. package/assets/sfx/impactos/rubble_falling_close_04.ogg +0 -0
  514. package/assets/sfx/impactos/rubble_falling_close_05.ogg +0 -0
  515. package/assets/sfx/impactos/rubble_falling_close_06.ogg +0 -0
  516. package/assets/sfx/impactos/rubble_falling_close_07.ogg +0 -0
  517. package/assets/sfx/impactos/rubble_falling_close_08.ogg +0 -0
  518. package/assets/sfx/impactos/rubble_falling_close_09.ogg +0 -0
  519. package/assets/sfx/impactos/soft_bullet_close_01.ogg +0 -0
  520. package/assets/sfx/impactos/soft_bullet_close_02.ogg +0 -0
  521. package/assets/sfx/impactos/soft_bullet_close_03.ogg +0 -0
  522. package/assets/sfx/impactos/soft_bullet_close_04.ogg +0 -0
  523. package/assets/sfx/impactos/soft_bullet_close_05.ogg +0 -0
  524. package/assets/sfx/impactos/soft_bullet_close_06.ogg +0 -0
  525. package/assets/sfx/impactos/soft_bullet_close_07.ogg +0 -0
  526. package/assets/sfx/impactos/soft_bullet_close_08.ogg +0 -0
  527. package/assets/sfx/impactos/soft_bullet_close_09.ogg +0 -0
  528. package/assets/sfx/impactos/soft_bullet_close_10.ogg +0 -0
  529. package/assets/sfx/impactos/soil_bullet_close_21.ogg +0 -0
  530. package/assets/sfx/impactos/soil_bullet_close_22.ogg +0 -0
  531. package/assets/sfx/impactos/soil_bullet_close_23.ogg +0 -0
  532. package/assets/sfx/impactos/wood_blunt_heavy_close_01.ogg +0 -0
  533. package/assets/sfx/impactos/wood_blunt_heavy_close_02.ogg +0 -0
  534. package/assets/sfx/impactos/wood_blunt_heavy_close_03.ogg +0 -0
  535. package/assets/sfx/impactos/wood_blunt_heavy_close_04.ogg +0 -0
  536. package/assets/sfx/impactos/wood_blunt_heavy_close_05.ogg +0 -0
  537. package/assets/sfx/impactos/wood_blunt_light_close_01.ogg +0 -0
  538. package/assets/sfx/impactos/wood_blunt_light_close_02.ogg +0 -0
  539. package/assets/sfx/impactos/wood_blunt_light_close_03.ogg +0 -0
  540. package/assets/sfx/impactos/wood_blunt_light_close_04.ogg +0 -0
  541. package/assets/sfx/impactos/wood_blunt_light_close_05.ogg +0 -0
  542. package/assets/sfx/impactos/wood_blunt_medium_close_01.ogg +0 -0
  543. package/assets/sfx/impactos/wood_blunt_medium_close_02.ogg +0 -0
  544. package/assets/sfx/impactos/wood_blunt_medium_close_03.ogg +0 -0
  545. package/assets/sfx/impactos/wood_blunt_medium_close_04.ogg +0 -0
  546. package/assets/sfx/impactos/wood_blunt_medium_close_05.ogg +0 -0
  547. package/assets/sfx/impactos/wood_fall_close_01.ogg +0 -0
  548. package/assets/sfx/impactos/wood_fall_close_02.ogg +0 -0
  549. package/assets/sfx/impactos/wood_fall_close_03.ogg +0 -0
  550. package/assets/sfx/impactos/wood_fall_close_04.ogg +0 -0
  551. package/assets/sfx/impactos/wood_fall_close_05.ogg +0 -0
  552. package/assets/sfx/impactos/wood_fall_close_06.ogg +0 -0
  553. package/assets/sfx/impactos/wood_fall_close_07.ogg +0 -0
  554. package/assets/sfx/impactos/wood_fall_close_08.ogg +0 -0
  555. package/assets/sfx/impactos/wood_fall_close_09.ogg +0 -0
  556. package/assets/sfx/impactos/wood_hit_close_01.ogg +0 -0
  557. package/assets/sfx/impactos/wood_hit_close_02.ogg +0 -0
  558. package/assets/sfx/impactos/wood_hit_close_03.ogg +0 -0
  559. package/assets/sfx/impactos/wood_hit_close_04.ogg +0 -0
  560. package/assets/sfx/impactos/wood_hit_close_05.ogg +0 -0
  561. package/assets/sfx/impactos/wood_hit_close_06.ogg +0 -0
  562. package/assets/sfx/impactos/wood_hit_close_07.ogg +0 -0
  563. package/assets/sfx/impactos/wood_hit_close_08.ogg +0 -0
  564. package/assets/sfx/impactos/wood_hit_close_09.ogg +0 -0
  565. package/assets/sfx/impactos/wood_hit_close_10.ogg +0 -0
  566. package/assets/sfx/impactos/wood_hit_close_11.ogg +0 -0
  567. package/assets/sfx/impactos/wood_hit_close_12.ogg +0 -0
  568. package/assets/sfx/impactos/wood_hit_close_13.ogg +0 -0
  569. package/assets/sfx/impactos/wood_hit_close_14.ogg +0 -0
  570. package/assets/sfx/impactos/wood_hit_close_21.ogg +0 -0
  571. package/assets/sfx/impactos/wood_hit_close_22.ogg +0 -0
  572. package/assets/sfx/impactos/wood_hit_close_23.ogg +0 -0
  573. package/assets/sfx/impactos/wood_hit_close_24.ogg +0 -0
  574. package/assets/sfx/impactos/wood_hit_close_25.ogg +0 -0
  575. package/assets/sfx/impactos/wood_hit_close_26.ogg +0 -0
  576. package/assets/sfx/impactos/wood_hit_close_27.ogg +0 -0
  577. package/assets/sfx/itens-portas/backpack_open_shut_01.ogg +0 -0
  578. package/assets/sfx/itens-portas/backpack_open_shut_02.ogg +0 -0
  579. package/assets/sfx/itens-portas/backpack_open_shut_03.ogg +0 -0
  580. package/assets/sfx/itens-portas/backpack_open_shut_04.ogg +0 -0
  581. package/assets/sfx/itens-portas/backpack_open_shut_05.ogg +0 -0
  582. package/assets/sfx/itens-portas/backpack_open_shut_06.ogg +0 -0
  583. package/assets/sfx/itens-portas/book_open_shut_01.ogg +0 -0
  584. package/assets/sfx/itens-portas/book_open_shut_02.ogg +0 -0
  585. package/assets/sfx/itens-portas/book_open_shut_03.ogg +0 -0
  586. package/assets/sfx/itens-portas/book_open_shut_04.ogg +0 -0
  587. package/assets/sfx/itens-portas/book_open_shut_05.ogg +0 -0
  588. package/assets/sfx/itens-portas/book_open_shut_06.ogg +0 -0
  589. package/assets/sfx/itens-portas/book_open_shut_07.ogg +0 -0
  590. package/assets/sfx/itens-portas/book_open_shut_08.ogg +0 -0
  591. package/assets/sfx/itens-portas/book_open_shut_09.ogg +0 -0
  592. package/assets/sfx/itens-portas/book_open_shut_10.ogg +0 -0
  593. package/assets/sfx/itens-portas/book_open_shut_11.ogg +0 -0
  594. package/assets/sfx/itens-portas/door_creak_01.ogg +0 -0
  595. package/assets/sfx/itens-portas/door_creak_02.ogg +0 -0
  596. package/assets/sfx/itens-portas/door_creak_03.ogg +0 -0
  597. package/assets/sfx/itens-portas/door_creak_06.ogg +0 -0
  598. package/assets/sfx/itens-portas/door_creak_07.ogg +0 -0
  599. package/assets/sfx/itens-portas/door_glass_sliding_01.ogg +0 -0
  600. package/assets/sfx/itens-portas/door_glass_sliding_02.ogg +0 -0
  601. package/assets/sfx/itens-portas/door_glass_sliding_03.ogg +0 -0
  602. package/assets/sfx/itens-portas/door_glass_sliding_04.ogg +0 -0
  603. package/assets/sfx/itens-portas/door_knock_01.ogg +0 -0
  604. package/assets/sfx/itens-portas/door_lock_unlock_01.ogg +0 -0
  605. package/assets/sfx/itens-portas/door_lock_unlock_02.ogg +0 -0
  606. package/assets/sfx/itens-portas/door_lock_unlock_03.ogg +0 -0
  607. package/assets/sfx/itens-portas/door_lock_unlock_04.ogg +0 -0
  608. package/assets/sfx/itens-portas/door_lock_unlock_05.ogg +0 -0
  609. package/assets/sfx/itens-portas/door_lock_unlock_06.ogg +0 -0
  610. package/assets/sfx/itens-portas/door_lock_unlock_07.ogg +0 -0
  611. package/assets/sfx/itens-portas/door_lock_unlock_08.ogg +0 -0
  612. package/assets/sfx/itens-portas/door_lock_unlock_09.ogg +0 -0
  613. package/assets/sfx/itens-portas/door_lock_unlock_10.ogg +0 -0
  614. package/assets/sfx/itens-portas/door_lock_unlock_11.ogg +0 -0
  615. package/assets/sfx/itens-portas/door_locked_rattle_01.ogg +0 -0
  616. package/assets/sfx/itens-portas/door_locked_rattle_02.ogg +0 -0
  617. package/assets/sfx/itens-portas/door_locked_rattle_03.ogg +0 -0
  618. package/assets/sfx/itens-portas/door_metal_open_shut_01.ogg +0 -0
  619. package/assets/sfx/itens-portas/door_metal_open_shut_02.ogg +0 -0
  620. package/assets/sfx/itens-portas/door_metal_open_shut_03.ogg +0 -0
  621. package/assets/sfx/itens-portas/door_metal_open_shut_04.ogg +0 -0
  622. package/assets/sfx/itens-portas/door_metal_open_shut_05.ogg +0 -0
  623. package/assets/sfx/itens-portas/door_metal_open_shut_06.ogg +0 -0
  624. package/assets/sfx/itens-portas/door_metal_open_shut_07.ogg +0 -0
  625. package/assets/sfx/itens-portas/door_slam_wood_01.ogg +0 -0
  626. package/assets/sfx/itens-portas/door_slam_wood_02.ogg +0 -0
  627. package/assets/sfx/itens-portas/door_slam_wood_03.ogg +0 -0
  628. package/assets/sfx/itens-portas/door_slam_wood_04.ogg +0 -0
  629. package/assets/sfx/itens-portas/door_wood_open_01.ogg +0 -0
  630. package/assets/sfx/itens-portas/door_wood_open_02.ogg +0 -0
  631. package/assets/sfx/itens-portas/door_wood_open_03.ogg +0 -0
  632. package/assets/sfx/itens-portas/door_wood_open_04.ogg +0 -0
  633. package/assets/sfx/itens-portas/door_wood_shut_01.ogg +0 -0
  634. package/assets/sfx/itens-portas/door_wood_shut_02.ogg +0 -0
  635. package/assets/sfx/itens-portas/door_wood_shut_03.ogg +0 -0
  636. package/assets/sfx/itens-portas/door_wood_shut_04.ogg +0 -0
  637. package/assets/sfx/itens-portas/door_wood_shut_05.ogg +0 -0
  638. package/assets/sfx/itens-portas/door_wood_shut_06.ogg +0 -0
  639. package/assets/sfx/itens-portas/door_wood_shut_07.ogg +0 -0
  640. package/assets/sfx/itens-portas/door_wood_shut_08.ogg +0 -0
  641. package/assets/sfx/itens-portas/drawer_open_01.ogg +0 -0
  642. package/assets/sfx/itens-portas/drawer_open_02.ogg +0 -0
  643. package/assets/sfx/itens-portas/drawer_shut_01.ogg +0 -0
  644. package/assets/sfx/itens-portas/drawer_shut_02.ogg +0 -0
  645. package/assets/sfx/itens-portas/item_drop_bag_01.ogg +0 -0
  646. package/assets/sfx/itens-portas/item_drop_bag_02.ogg +0 -0
  647. package/assets/sfx/itens-portas/item_drop_glass_01.ogg +0 -0
  648. package/assets/sfx/itens-portas/item_drop_metal_01.ogg +0 -0
  649. package/assets/sfx/itens-portas/item_drop_metal_02.ogg +0 -0
  650. package/assets/sfx/itens-portas/item_drop_metal_03.ogg +0 -0
  651. package/assets/sfx/itens-portas/item_drop_metal_04.ogg +0 -0
  652. package/assets/sfx/itens-portas/item_drop_metal_05.ogg +0 -0
  653. package/assets/sfx/itens-portas/item_drop_paper_01.ogg +0 -0
  654. package/assets/sfx/itens-portas/item_pickup_coins_01.ogg +0 -0
  655. package/assets/sfx/itens-portas/item_pickup_coins_02.ogg +0 -0
  656. package/assets/sfx/itens-portas/item_pickup_generic_01.ogg +0 -0
  657. package/assets/sfx/itens-portas/item_pickup_generic_02.ogg +0 -0
  658. package/assets/sfx/itens-portas/item_pickup_generic_03.ogg +0 -0
  659. package/assets/sfx/itens-portas/item_pickup_generic_04.ogg +0 -0
  660. package/assets/sfx/itens-portas/item_pickup_leather_01.ogg +0 -0
  661. package/assets/sfx/itens-portas/item_pickup_leather_02.ogg +0 -0
  662. package/assets/sfx/itens-portas/item_pickup_leather_03.ogg +0 -0
  663. package/assets/sfx/itens-portas/item_pickup_leather_04.ogg +0 -0
  664. package/assets/sfx/itens-portas/item_pickup_leather_05.ogg +0 -0
  665. package/assets/sfx/itens-portas/item_setdown_01.ogg +0 -0
  666. package/assets/sfx/itens-portas/item_setdown_02.ogg +0 -0
  667. package/assets/sfx/itens-portas/keys_jingle_01.ogg +0 -0
  668. package/assets/sfx/itens-portas/keys_jingle_02.ogg +0 -0
  669. package/assets/sfx/itens-portas/keys_jingle_03.ogg +0 -0
  670. package/assets/sfx/itens-portas/keys_jingle_04.ogg +0 -0
  671. package/assets/sfx/itens-portas/keys_jingle_05.ogg +0 -0
  672. package/assets/sfx/itens-portas/keys_jingle_06.ogg +0 -0
  673. package/assets/sfx/itens-portas/keys_jingle_07.ogg +0 -0
  674. package/assets/sfx/itens-portas/lever_pull_01.ogg +0 -0
  675. package/assets/sfx/itens-portas/lever_pull_02.ogg +0 -0
  676. package/assets/sfx/itens-portas/lever_pull_03.ogg +0 -0
  677. package/assets/sfx/itens-portas/lever_pull_04.ogg +0 -0
  678. package/assets/sfx/itens-portas/lever_pull_05.ogg +0 -0
  679. package/assets/sfx/itens-portas/lever_pull_06.ogg +0 -0
  680. package/assets/sfx/itens-portas/metal_latch_01.ogg +0 -0
  681. package/assets/sfx/itens-portas/metal_latch_02.ogg +0 -0
  682. package/assets/sfx/itens-portas/plates_hit_01.ogg +0 -0
  683. package/assets/sfx/itens-portas/plates_hit_02.ogg +0 -0
  684. package/assets/sfx/itens-portas/plates_hit_03.ogg +0 -0
  685. package/assets/sfx/itens-portas/plates_hit_04.ogg +0 -0
  686. package/assets/sfx/itens-portas/plates_hit_05.ogg +0 -0
  687. package/assets/sfx/itens-portas/plates_hit_06.ogg +0 -0
  688. package/assets/sfx/itens-portas/plates_hit_07.ogg +0 -0
  689. package/assets/sfx/itens-portas/plates_hit_08.ogg +0 -0
  690. package/assets/sfx/itens-portas/plates_hit_09.ogg +0 -0
  691. package/assets/sfx/itens-portas/plates_hit_10.ogg +0 -0
  692. package/assets/sfx/itens-portas/plates_slide_01.ogg +0 -0
  693. package/assets/sfx/itens-portas/plates_slide_02.ogg +0 -0
  694. package/assets/sfx/itens-portas/plates_slide_03.ogg +0 -0
  695. package/assets/sfx/itens-portas/plates_slide_04.ogg +0 -0
  696. package/assets/sfx/itens-portas/saw_wood_01.ogg +0 -0
  697. package/assets/sfx/itens-portas/switch_click_01.ogg +0 -0
  698. package/assets/sfx/itens-portas/switch_click_02.ogg +0 -0
  699. package/assets/sfx/itens-portas/switch_click_03.ogg +0 -0
  700. package/assets/sfx/itens-portas/switch_click_04.ogg +0 -0
  701. package/assets/sfx/itens-portas/toilet_flush_01.ogg +0 -0
  702. package/assets/sfx/itens-portas/tools_handling_01.ogg +0 -0
  703. package/assets/sfx/itens-portas/tools_handling_02.ogg +0 -0
  704. package/assets/sfx/itens-portas/tools_handling_03.ogg +0 -0
  705. package/assets/sfx/itens-portas/tools_handling_04.ogg +0 -0
  706. package/assets/sfx/itens-portas/tools_handling_05.ogg +0 -0
  707. package/assets/sfx/itens-portas/tools_handling_06.ogg +0 -0
  708. package/assets/sfx/itens-portas/tools_handling_07.ogg +0 -0
  709. package/assets/sfx/itens-portas/tools_handling_08.ogg +0 -0
  710. package/assets/sfx/itens-portas/tools_handling_09.ogg +0 -0
  711. package/assets/sfx/itens-portas/tools_handling_10.ogg +0 -0
  712. package/assets/sfx/itens-portas/tools_handling_11.ogg +0 -0
  713. package/assets/sfx/itens-portas/tools_handling_12.ogg +0 -0
  714. package/assets/sfx/itens-portas/tools_handling_13.ogg +0 -0
  715. package/assets/sfx/itens-portas/tools_handling_14.ogg +0 -0
  716. package/assets/sfx/itens-portas/tools_handling_15.ogg +0 -0
  717. package/assets/sfx/itens-portas/tools_handling_16.ogg +0 -0
  718. package/assets/sfx/itens-portas/water_drip_01.ogg +0 -0
  719. package/assets/sfx/itens-portas/water_drip_02.ogg +0 -0
  720. package/assets/sfx/itens-portas/water_drip_03.ogg +0 -0
  721. package/assets/sfx/itens-portas/water_drip_04.ogg +0 -0
  722. package/assets/sfx/itens-portas/water_faucet_01.ogg +0 -0
  723. package/assets/sfx/itens-portas/water_faucet_02.ogg +0 -0
  724. package/assets/sfx/itens-portas/water_faucet_03.ogg +0 -0
  725. package/assets/sfx/itens-portas/water_faucet_04.ogg +0 -0
  726. package/assets/sfx/itens-portas/water_faucet_05.ogg +0 -0
  727. package/assets/sfx/itens-portas/water_faucet_06.ogg +0 -0
  728. package/assets/sfx/itens-portas/water_faucet_07.ogg +0 -0
  729. package/assets/sfx/itens-portas/water_faucet_08.ogg +0 -0
  730. package/assets/sfx/itens-portas/water_faucet_09.ogg +0 -0
  731. package/assets/sfx/itens-portas/water_faucet_10.ogg +0 -0
  732. package/assets/sfx/manifest.json +11959 -0
  733. package/assets/sfx/personagem/axe_chop_01.ogg +0 -0
  734. package/assets/sfx/personagem/axe_chop_02.ogg +0 -0
  735. package/assets/sfx/personagem/blunt_hit_metal_01.ogg +0 -0
  736. package/assets/sfx/personagem/blunt_hit_metal_02.ogg +0 -0
  737. package/assets/sfx/personagem/blunt_hit_metal_03.ogg +0 -0
  738. package/assets/sfx/personagem/blunt_hit_metal_04.ogg +0 -0
  739. package/assets/sfx/personagem/blunt_hit_metal_05.ogg +0 -0
  740. package/assets/sfx/personagem/body_fall_01.ogg +0 -0
  741. package/assets/sfx/personagem/body_fall_02.ogg +0 -0
  742. package/assets/sfx/personagem/body_fall_03.ogg +0 -0
  743. package/assets/sfx/personagem/body_fall_04.ogg +0 -0
  744. package/assets/sfx/personagem/body_fall_05.ogg +0 -0
  745. package/assets/sfx/personagem/cloth_rustle_01.ogg +0 -0
  746. package/assets/sfx/personagem/cloth_rustle_02.ogg +0 -0
  747. package/assets/sfx/personagem/cloth_rustle_03.ogg +0 -0
  748. package/assets/sfx/personagem/cloth_rustle_04.ogg +0 -0
  749. package/assets/sfx/personagem/cloth_rustle_05.ogg +0 -0
  750. package/assets/sfx/personagem/cloth_rustle_06.ogg +0 -0
  751. package/assets/sfx/personagem/cloth_rustle_07.ogg +0 -0
  752. package/assets/sfx/personagem/cloth_rustle_08.ogg +0 -0
  753. package/assets/sfx/personagem/cloth_rustle_09.ogg +0 -0
  754. package/assets/sfx/personagem/cloth_rustle_10.ogg +0 -0
  755. package/assets/sfx/personagem/cloth_rustle_11.ogg +0 -0
  756. package/assets/sfx/personagem/cloth_rustle_12.ogg +0 -0
  757. package/assets/sfx/personagem/cloth_rustle_13.ogg +0 -0
  758. package/assets/sfx/personagem/cloth_rustle_14.ogg +0 -0
  759. package/assets/sfx/personagem/drink_gulp_01.ogg +0 -0
  760. package/assets/sfx/personagem/drink_gulp_02.ogg +0 -0
  761. package/assets/sfx/personagem/drink_gulp_03.ogg +0 -0
  762. package/assets/sfx/personagem/footstep_carpet_alt_01.ogg +0 -0
  763. package/assets/sfx/personagem/footstep_carpet_alt_02.ogg +0 -0
  764. package/assets/sfx/personagem/footstep_carpet_alt_03.ogg +0 -0
  765. package/assets/sfx/personagem/footstep_carpet_alt_04.ogg +0 -0
  766. package/assets/sfx/personagem/footstep_carpet_alt_05.ogg +0 -0
  767. package/assets/sfx/personagem/footstep_concrete_alt_01.ogg +0 -0
  768. package/assets/sfx/personagem/footstep_concrete_alt_02.ogg +0 -0
  769. package/assets/sfx/personagem/footstep_concrete_alt_03.ogg +0 -0
  770. package/assets/sfx/personagem/footstep_concrete_alt_04.ogg +0 -0
  771. package/assets/sfx/personagem/footstep_concrete_alt_05.ogg +0 -0
  772. package/assets/sfx/personagem/footstep_concrete_run_01.ogg +0 -0
  773. package/assets/sfx/personagem/footstep_concrete_run_02.ogg +0 -0
  774. package/assets/sfx/personagem/footstep_concrete_run_03.ogg +0 -0
  775. package/assets/sfx/personagem/footstep_concrete_run_04.ogg +0 -0
  776. package/assets/sfx/personagem/footstep_concrete_run_05.ogg +0 -0
  777. package/assets/sfx/personagem/footstep_concrete_walk_01.ogg +0 -0
  778. package/assets/sfx/personagem/footstep_concrete_walk_02.ogg +0 -0
  779. package/assets/sfx/personagem/footstep_concrete_walk_03.ogg +0 -0
  780. package/assets/sfx/personagem/footstep_concrete_walk_04.ogg +0 -0
  781. package/assets/sfx/personagem/footstep_concrete_walk_05.ogg +0 -0
  782. package/assets/sfx/personagem/footstep_dirt_run_01.ogg +0 -0
  783. package/assets/sfx/personagem/footstep_dirt_run_02.ogg +0 -0
  784. package/assets/sfx/personagem/footstep_dirt_run_03.ogg +0 -0
  785. package/assets/sfx/personagem/footstep_dirt_run_04.ogg +0 -0
  786. package/assets/sfx/personagem/footstep_dirt_run_05.ogg +0 -0
  787. package/assets/sfx/personagem/footstep_dirt_walk_01.ogg +0 -0
  788. package/assets/sfx/personagem/footstep_dirt_walk_02.ogg +0 -0
  789. package/assets/sfx/personagem/footstep_dirt_walk_03.ogg +0 -0
  790. package/assets/sfx/personagem/footstep_dirt_walk_04.ogg +0 -0
  791. package/assets/sfx/personagem/footstep_dirt_walk_05.ogg +0 -0
  792. package/assets/sfx/personagem/footstep_generic_alt_01.ogg +0 -0
  793. package/assets/sfx/personagem/footstep_generic_alt_02.ogg +0 -0
  794. package/assets/sfx/personagem/footstep_generic_alt_03.ogg +0 -0
  795. package/assets/sfx/personagem/footstep_generic_alt_04.ogg +0 -0
  796. package/assets/sfx/personagem/footstep_generic_alt_05.ogg +0 -0
  797. package/assets/sfx/personagem/footstep_generic_alt_06.ogg +0 -0
  798. package/assets/sfx/personagem/footstep_generic_alt_07.ogg +0 -0
  799. package/assets/sfx/personagem/footstep_generic_alt_08.ogg +0 -0
  800. package/assets/sfx/personagem/footstep_generic_alt_09.ogg +0 -0
  801. package/assets/sfx/personagem/footstep_generic_alt_10.ogg +0 -0
  802. package/assets/sfx/personagem/footstep_grass_alt2_01.ogg +0 -0
  803. package/assets/sfx/personagem/footstep_grass_alt2_02.ogg +0 -0
  804. package/assets/sfx/personagem/footstep_grass_alt2_03.ogg +0 -0
  805. package/assets/sfx/personagem/footstep_grass_alt2_04.ogg +0 -0
  806. package/assets/sfx/personagem/footstep_grass_alt_01.ogg +0 -0
  807. package/assets/sfx/personagem/footstep_grass_alt_02.ogg +0 -0
  808. package/assets/sfx/personagem/footstep_grass_alt_03.ogg +0 -0
  809. package/assets/sfx/personagem/footstep_grass_alt_04.ogg +0 -0
  810. package/assets/sfx/personagem/footstep_grass_alt_05.ogg +0 -0
  811. package/assets/sfx/personagem/footstep_grass_run_01.ogg +0 -0
  812. package/assets/sfx/personagem/footstep_grass_run_02.ogg +0 -0
  813. package/assets/sfx/personagem/footstep_grass_run_03.ogg +0 -0
  814. package/assets/sfx/personagem/footstep_grass_run_04.ogg +0 -0
  815. package/assets/sfx/personagem/footstep_grass_run_05.ogg +0 -0
  816. package/assets/sfx/personagem/footstep_grass_walk_01.ogg +0 -0
  817. package/assets/sfx/personagem/footstep_grass_walk_02.ogg +0 -0
  818. package/assets/sfx/personagem/footstep_grass_walk_03.ogg +0 -0
  819. package/assets/sfx/personagem/footstep_grass_walk_04.ogg +0 -0
  820. package/assets/sfx/personagem/footstep_grass_walk_05.ogg +0 -0
  821. package/assets/sfx/personagem/footstep_hard_alt_01.ogg +0 -0
  822. package/assets/sfx/personagem/footstep_hard_alt_02.ogg +0 -0
  823. package/assets/sfx/personagem/footstep_hard_alt_03.ogg +0 -0
  824. package/assets/sfx/personagem/footstep_hard_alt_04.ogg +0 -0
  825. package/assets/sfx/personagem/footstep_hard_alt_05.ogg +0 -0
  826. package/assets/sfx/personagem/footstep_hard_alt_06.ogg +0 -0
  827. package/assets/sfx/personagem/footstep_hard_alt_07.ogg +0 -0
  828. package/assets/sfx/personagem/footstep_hard_alt_08.ogg +0 -0
  829. package/assets/sfx/personagem/footstep_hard_alt_09.ogg +0 -0
  830. package/assets/sfx/personagem/footstep_metal_run_01.ogg +0 -0
  831. package/assets/sfx/personagem/footstep_metal_run_02.ogg +0 -0
  832. package/assets/sfx/personagem/footstep_metal_run_03.ogg +0 -0
  833. package/assets/sfx/personagem/footstep_metal_run_04.ogg +0 -0
  834. package/assets/sfx/personagem/footstep_metal_run_05.ogg +0 -0
  835. package/assets/sfx/personagem/footstep_metal_walk_01.ogg +0 -0
  836. package/assets/sfx/personagem/footstep_metal_walk_02.ogg +0 -0
  837. package/assets/sfx/personagem/footstep_metal_walk_03.ogg +0 -0
  838. package/assets/sfx/personagem/footstep_metal_walk_04.ogg +0 -0
  839. package/assets/sfx/personagem/footstep_metal_walk_05.ogg +0 -0
  840. package/assets/sfx/personagem/footstep_snow_alt_01.ogg +0 -0
  841. package/assets/sfx/personagem/footstep_snow_alt_02.ogg +0 -0
  842. package/assets/sfx/personagem/footstep_snow_alt_03.ogg +0 -0
  843. package/assets/sfx/personagem/footstep_snow_alt_04.ogg +0 -0
  844. package/assets/sfx/personagem/footstep_snow_alt_05.ogg +0 -0
  845. package/assets/sfx/personagem/footstep_snow_run_01.ogg +0 -0
  846. package/assets/sfx/personagem/footstep_snow_run_02.ogg +0 -0
  847. package/assets/sfx/personagem/footstep_snow_run_03.ogg +0 -0
  848. package/assets/sfx/personagem/footstep_snow_run_04.ogg +0 -0
  849. package/assets/sfx/personagem/footstep_snow_run_05.ogg +0 -0
  850. package/assets/sfx/personagem/footstep_snow_walk_01.ogg +0 -0
  851. package/assets/sfx/personagem/footstep_snow_walk_02.ogg +0 -0
  852. package/assets/sfx/personagem/footstep_snow_walk_03.ogg +0 -0
  853. package/assets/sfx/personagem/footstep_snow_walk_04.ogg +0 -0
  854. package/assets/sfx/personagem/footstep_snow_walk_05.ogg +0 -0
  855. package/assets/sfx/personagem/footstep_wood_alt_01.ogg +0 -0
  856. package/assets/sfx/personagem/footstep_wood_alt_02.ogg +0 -0
  857. package/assets/sfx/personagem/footstep_wood_alt_03.ogg +0 -0
  858. package/assets/sfx/personagem/footstep_wood_alt_04.ogg +0 -0
  859. package/assets/sfx/personagem/footstep_wood_alt_05.ogg +0 -0
  860. package/assets/sfx/personagem/footstep_wood_run_01.ogg +0 -0
  861. package/assets/sfx/personagem/footstep_wood_run_02.ogg +0 -0
  862. package/assets/sfx/personagem/footstep_wood_run_03.ogg +0 -0
  863. package/assets/sfx/personagem/footstep_wood_run_04.ogg +0 -0
  864. package/assets/sfx/personagem/footstep_wood_run_05.ogg +0 -0
  865. package/assets/sfx/personagem/footstep_wood_walk_01.ogg +0 -0
  866. package/assets/sfx/personagem/footstep_wood_walk_02.ogg +0 -0
  867. package/assets/sfx/personagem/footstep_wood_walk_03.ogg +0 -0
  868. package/assets/sfx/personagem/footstep_wood_walk_04.ogg +0 -0
  869. package/assets/sfx/personagem/footstep_wood_walk_05.ogg +0 -0
  870. package/assets/sfx/personagem/frying_pan_hit_01.ogg +0 -0
  871. package/assets/sfx/personagem/frying_pan_hit_02.ogg +0 -0
  872. package/assets/sfx/personagem/frying_pan_hit_03.ogg +0 -0
  873. package/assets/sfx/personagem/grab_01.ogg +0 -0
  874. package/assets/sfx/personagem/kick_hit_01.ogg +0 -0
  875. package/assets/sfx/personagem/kick_hit_02.ogg +0 -0
  876. package/assets/sfx/personagem/kick_hit_03.ogg +0 -0
  877. package/assets/sfx/personagem/kick_hit_04.ogg +0 -0
  878. package/assets/sfx/personagem/kick_hit_05.ogg +0 -0
  879. package/assets/sfx/personagem/knife_draw_01.ogg +0 -0
  880. package/assets/sfx/personagem/knife_draw_02.ogg +0 -0
  881. package/assets/sfx/personagem/knife_draw_03.ogg +0 -0
  882. package/assets/sfx/personagem/knife_scrape_01.ogg +0 -0
  883. package/assets/sfx/personagem/knife_slash_01.ogg +0 -0
  884. package/assets/sfx/personagem/knife_slash_02.ogg +0 -0
  885. package/assets/sfx/personagem/land_concrete_01.ogg +0 -0
  886. package/assets/sfx/personagem/land_concrete_02.ogg +0 -0
  887. package/assets/sfx/personagem/land_dirt_01.ogg +0 -0
  888. package/assets/sfx/personagem/land_dirt_02.ogg +0 -0
  889. package/assets/sfx/personagem/land_grass_01.ogg +0 -0
  890. package/assets/sfx/personagem/land_grass_02.ogg +0 -0
  891. package/assets/sfx/personagem/land_metal_01.ogg +0 -0
  892. package/assets/sfx/personagem/land_metal_02.ogg +0 -0
  893. package/assets/sfx/personagem/land_snow_01.ogg +0 -0
  894. package/assets/sfx/personagem/land_snow_02.ogg +0 -0
  895. package/assets/sfx/personagem/land_wood_01.ogg +0 -0
  896. package/assets/sfx/personagem/land_wood_02.ogg +0 -0
  897. package/assets/sfx/personagem/player_breath_run_01.ogg +0 -0
  898. package/assets/sfx/personagem/player_breath_run_02.ogg +0 -0
  899. package/assets/sfx/personagem/player_breath_run_03.ogg +0 -0
  900. package/assets/sfx/personagem/player_breath_run_04.ogg +0 -0
  901. package/assets/sfx/personagem/player_breath_run_05.ogg +0 -0
  902. package/assets/sfx/personagem/player_death_female_01.ogg +0 -0
  903. package/assets/sfx/personagem/player_death_female_02.ogg +0 -0
  904. package/assets/sfx/personagem/player_death_female_03.ogg +0 -0
  905. package/assets/sfx/personagem/player_death_female_04.ogg +0 -0
  906. package/assets/sfx/personagem/player_death_female_05.ogg +0 -0
  907. package/assets/sfx/personagem/player_death_female_06.ogg +0 -0
  908. package/assets/sfx/personagem/player_death_female_07.ogg +0 -0
  909. package/assets/sfx/personagem/player_death_female_08.ogg +0 -0
  910. package/assets/sfx/personagem/player_death_male_01.ogg +0 -0
  911. package/assets/sfx/personagem/player_death_male_02.ogg +0 -0
  912. package/assets/sfx/personagem/player_death_male_03.ogg +0 -0
  913. package/assets/sfx/personagem/player_death_male_04.ogg +0 -0
  914. package/assets/sfx/personagem/player_death_male_05.ogg +0 -0
  915. package/assets/sfx/personagem/player_death_male_06.ogg +0 -0
  916. package/assets/sfx/personagem/player_death_male_07.ogg +0 -0
  917. package/assets/sfx/personagem/player_death_male_08.ogg +0 -0
  918. package/assets/sfx/personagem/player_effort_01.ogg +0 -0
  919. package/assets/sfx/personagem/player_effort_02.ogg +0 -0
  920. package/assets/sfx/personagem/player_effort_03.ogg +0 -0
  921. package/assets/sfx/personagem/player_effort_04.ogg +0 -0
  922. package/assets/sfx/personagem/player_hurt_female_01.ogg +0 -0
  923. package/assets/sfx/personagem/player_hurt_female_02.ogg +0 -0
  924. package/assets/sfx/personagem/player_hurt_female_03.ogg +0 -0
  925. package/assets/sfx/personagem/player_hurt_female_04.ogg +0 -0
  926. package/assets/sfx/personagem/player_hurt_female_05.ogg +0 -0
  927. package/assets/sfx/personagem/player_hurt_female_06.ogg +0 -0
  928. package/assets/sfx/personagem/player_hurt_male_01.ogg +0 -0
  929. package/assets/sfx/personagem/player_hurt_male_02.ogg +0 -0
  930. package/assets/sfx/personagem/player_hurt_male_03.ogg +0 -0
  931. package/assets/sfx/personagem/player_hurt_male_04.ogg +0 -0
  932. package/assets/sfx/personagem/player_hurt_male_05.ogg +0 -0
  933. package/assets/sfx/personagem/player_hurt_male_06.ogg +0 -0
  934. package/assets/sfx/personagem/punch_hit_alt_01.ogg +0 -0
  935. package/assets/sfx/personagem/punch_hit_alt_02.ogg +0 -0
  936. package/assets/sfx/personagem/punch_hit_alt_03.ogg +0 -0
  937. package/assets/sfx/personagem/punch_hit_alt_04.ogg +0 -0
  938. package/assets/sfx/personagem/punch_hit_alt_05.ogg +0 -0
  939. package/assets/sfx/personagem/punch_hit_alt_06.ogg +0 -0
  940. package/assets/sfx/personagem/punch_hit_alt_07.ogg +0 -0
  941. package/assets/sfx/personagem/punch_hit_alt_08.ogg +0 -0
  942. package/assets/sfx/personagem/punch_hit_alt_09.ogg +0 -0
  943. package/assets/sfx/personagem/punch_hit_alt_10.ogg +0 -0
  944. package/assets/sfx/personagem/punch_hit_body_01.ogg +0 -0
  945. package/assets/sfx/personagem/punch_hit_body_02.ogg +0 -0
  946. package/assets/sfx/personagem/punch_hit_body_03.ogg +0 -0
  947. package/assets/sfx/personagem/punch_hit_body_04.ogg +0 -0
  948. package/assets/sfx/personagem/punch_hit_body_05.ogg +0 -0
  949. package/assets/sfx/personagem/punch_hit_body_06.ogg +0 -0
  950. package/assets/sfx/personagem/punch_hit_face_01.ogg +0 -0
  951. package/assets/sfx/personagem/punch_hit_face_02.ogg +0 -0
  952. package/assets/sfx/personagem/punch_hit_face_03.ogg +0 -0
  953. package/assets/sfx/personagem/punch_hit_face_04.ogg +0 -0
  954. package/assets/sfx/personagem/punch_hit_face_05.ogg +0 -0
  955. package/assets/sfx/personagem/punch_swing_01.ogg +0 -0
  956. package/assets/sfx/personagem/punch_swing_02.ogg +0 -0
  957. package/assets/sfx/personagem/punch_swing_03.ogg +0 -0
  958. package/assets/sfx/personagem/punch_swing_04.ogg +0 -0
  959. package/assets/sfx/personagem/punch_swing_05.ogg +0 -0
  960. package/assets/sfx/personagem/punch_swing_06.ogg +0 -0
  961. package/assets/sfx/personagem/punch_swing_07.ogg +0 -0
  962. package/assets/sfx/personagem/punch_swing_08.ogg +0 -0
  963. package/assets/sfx/personagem/scream_01.ogg +0 -0
  964. package/assets/sfx/personagem/scream_02.ogg +0 -0
  965. package/assets/sfx/personagem/scream_03.ogg +0 -0
  966. package/assets/sfx/personagem/scream_04.ogg +0 -0
  967. package/assets/sfx/personagem/slap_01.ogg +0 -0
  968. package/assets/sfx/personagem/swing_whoosh_alt_01.ogg +0 -0
  969. package/assets/sfx/personagem/swing_whoosh_alt_02.ogg +0 -0
  970. package/assets/sfx/personagem/swing_whoosh_alt_03.ogg +0 -0
  971. package/assets/sfx/personagem/swing_whoosh_alt_04.ogg +0 -0
  972. package/assets/sfx/personagem/swing_whoosh_alt_05.ogg +0 -0
  973. package/assets/sfx/personagem/swing_whoosh_alt_06.ogg +0 -0
  974. package/assets/sfx/personagem/swing_whoosh_alt_07.ogg +0 -0
  975. package/assets/sfx/personagem/swing_whoosh_alt_08.ogg +0 -0
  976. package/assets/sfx/personagem/swing_whoosh_alt_09.ogg +0 -0
  977. package/assets/sfx/personagem/swing_whoosh_alt_10.ogg +0 -0
  978. package/assets/sfx/personagem/swing_whoosh_alt_11.ogg +0 -0
  979. package/assets/sfx/personagem/swing_whoosh_alt_12.ogg +0 -0
  980. package/assets/sfx/personagem/swing_whoosh_alt_13.ogg +0 -0
  981. package/assets/sfx/personagem/swing_whoosh_alt_14.ogg +0 -0
  982. package/assets/sfx/personagem/swing_whoosh_alt_15.ogg +0 -0
  983. package/assets/sfx/personagem/swing_whoosh_alt_16.ogg +0 -0
  984. package/assets/sfx/personagem/swing_whoosh_alt_17.ogg +0 -0
  985. package/assets/sfx/personagem/swing_whoosh_alt_18.ogg +0 -0
  986. package/assets/sfx/personagem/swing_whoosh_alt_19.ogg +0 -0
  987. package/assets/sfx/personagem/swing_whoosh_alt_20.ogg +0 -0
  988. package/assets/sfx/personagem/swing_whoosh_alt_21.ogg +0 -0
  989. package/assets/sfx/personagem/swing_whoosh_alt_22.ogg +0 -0
  990. package/assets/sfx/personagem/swing_whoosh_alt_23.ogg +0 -0
  991. package/assets/sfx/personagem/swing_whoosh_alt_24.ogg +0 -0
  992. package/assets/sfx/personagem/swing_whoosh_alt_25.ogg +0 -0
  993. package/assets/sfx/personagem/swing_whoosh_alt_26.ogg +0 -0
  994. package/assets/sfx/personagem/swing_whoosh_alt_27.ogg +0 -0
  995. package/assets/sfx/personagem/swing_whoosh_alt_28.ogg +0 -0
  996. package/assets/sfx/personagem/swing_whoosh_alt_29.ogg +0 -0
  997. package/assets/sfx/personagem/swing_whoosh_alt_30.ogg +0 -0
  998. package/assets/sfx/personagem/swing_whoosh_alt_31.ogg +0 -0
  999. package/assets/sfx/personagem/swing_whoosh_alt_32.ogg +0 -0
  1000. package/assets/sfx/personagem/swing_whoosh_alt_33.ogg +0 -0
  1001. package/assets/sfx/personagem/swing_whoosh_alt_34.ogg +0 -0
  1002. package/assets/sfx/personagem/swing_whoosh_alt_35.ogg +0 -0
  1003. package/assets/sfx/personagem/swing_whoosh_alt_36.ogg +0 -0
  1004. package/assets/sfx/personagem/swing_whoosh_alt_37.ogg +0 -0
  1005. package/assets/sfx/personagem/swing_whoosh_alt_38.ogg +0 -0
  1006. package/assets/sfx/personagem/swing_whoosh_alt_39.ogg +0 -0
  1007. package/assets/sfx/personagem/swing_whoosh_alt_40.ogg +0 -0
  1008. package/assets/sfx/personagem/swing_whoosh_alt_41.ogg +0 -0
  1009. package/assets/sfx/personagem/swing_whoosh_alt_42.ogg +0 -0
  1010. package/assets/sfx/personagem/swing_whoosh_alt_43.ogg +0 -0
  1011. package/assets/sfx/personagem/zombie_creature_01.ogg +0 -0
  1012. package/assets/sfx/personagem/zombie_creature_02.ogg +0 -0
  1013. package/assets/sfx/personagem/zombie_creature_03.ogg +0 -0
  1014. package/assets/sfx/personagem/zombie_death_01.ogg +0 -0
  1015. package/assets/sfx/personagem/zombie_death_02.ogg +0 -0
  1016. package/assets/sfx/personagem/zombie_death_03.ogg +0 -0
  1017. package/assets/sfx/personagem/zombie_death_04.ogg +0 -0
  1018. package/assets/sfx/personagem/zombie_death_05.ogg +0 -0
  1019. package/assets/sfx/personagem/zombie_death_06.ogg +0 -0
  1020. package/assets/sfx/personagem/zombie_death_07.ogg +0 -0
  1021. package/assets/sfx/personagem/zombie_death_08.ogg +0 -0
  1022. package/assets/sfx/personagem/zombie_groan_01.ogg +0 -0
  1023. package/assets/sfx/personagem/zombie_groan_02.ogg +0 -0
  1024. package/assets/sfx/personagem/zombie_groan_03.ogg +0 -0
  1025. package/assets/sfx/personagem/zombie_groan_04.ogg +0 -0
  1026. package/assets/sfx/personagem/zombie_groan_05.ogg +0 -0
  1027. package/assets/sfx/personagem/zombie_groan_06.ogg +0 -0
  1028. package/assets/sfx/personagem/zombie_groan_07.ogg +0 -0
  1029. package/assets/sfx/personagem/zombie_groan_08.ogg +0 -0
  1030. package/assets/sfx/personagem/zombie_groan_09.ogg +0 -0
  1031. package/assets/sfx/personagem/zombie_groan_10.ogg +0 -0
  1032. package/assets/sfx/personagem/zombie_groan_11.ogg +0 -0
  1033. package/assets/sfx/veiculos/car_door_open_01.ogg +0 -0
  1034. package/assets/sfx/veiculos/car_door_shut_01.ogg +0 -0
  1035. package/assets/sfx/veiculos/car_gear_shift_01.ogg +0 -0
  1036. package/assets/sfx/veiculos/car_trunk_shut_01.ogg +0 -0
  1037. package/assets/sfx/veiculos/car_window_01.ogg +0 -0
  1038. package/assets/sfx/veiculos/car_window_02.ogg +0 -0
  1039. package/assets/sfx/veiculos/engine_loop_car_high_01.ogg +0 -0
  1040. package/assets/sfx/veiculos/engine_loop_car_idle_01.ogg +0 -0
  1041. package/assets/sfx/veiculos/engine_start_run_stop_01.ogg +0 -0
  1042. package/assets/sfx/veiculos/engine_start_run_stop_02.ogg +0 -0
  1043. package/dist/chunk-7TLFY7VO.js +4170 -0
  1044. package/dist/chunk-7TLFY7VO.js.map +1 -0
  1045. package/dist/index.d.ts +228 -603
  1046. package/dist/index.global.js +2958 -463
  1047. package/dist/index.global.js.map +1 -1
  1048. package/dist/index.js +1088 -2044
  1049. package/dist/index.js.map +1 -1
  1050. package/dist/locale-BugSe8dA.d.ts +1071 -0
  1051. package/dist/testing.d.ts +82 -0
  1052. package/dist/testing.js +19 -0
  1053. package/dist/testing.js.map +1 -0
  1054. package/package.json +13 -6
package/dist/index.js CHANGED
@@ -1,527 +1,243 @@
1
- // src/rng.ts
2
- var FNV_OFFSET = 2166136261;
3
- var FNV_PRIME = 16777619;
4
- var MIX = 2654435761;
5
- function createRng(seed) {
6
- let state = seed >>> 0;
7
- return () => {
8
- state = state + 1831565813 >>> 0;
9
- let mixed = Math.imul(state ^ state >>> 15, state | 1);
10
- mixed ^= mixed + Math.imul(mixed ^ mixed >>> 7, mixed | 61);
11
- return ((mixed ^ mixed >>> 14) >>> 0) / 4294967296;
12
- };
13
- }
14
- function streamSeed(seed, name) {
15
- const label = String(name);
16
- let hash = FNV_OFFSET;
17
- for (let index = 0; index < label.length; index++) hash = Math.imul(hash ^ label.charCodeAt(index), FNV_PRIME) >>> 0;
18
- return Math.imul(seed >>> 0 ^ hash, MIX) >>> 0;
19
- }
20
- function streamFor(seed, name) {
21
- return createRng(streamSeed(seed, name));
22
- }
23
- function drawBetween(random, min, max) {
24
- return min + random() * (max - min);
25
- }
26
-
27
- // src/recipe.ts
28
- var BUS_IDS = ["weapons", "voices", "world", "ambience", "weather", "ui"];
29
- var BUILD_ORDERS = ["layered", "burst", "scream", "groan", "boom", "static", "chord", "calls", "siren", "weapon"];
30
-
31
- // src/falloff.ts
32
- var DISTANCE_CURVES = {
33
- /** The game's `sfx`: `vol / (1 + d² × 0.004)`, cutoff `/ (1 + d × 0.01)`, silent below 0.01 (jogo L62091–62092, L62101). */
34
- game_sfx: { model: "inverse_square", k: 4e-3, cutoffK: 0.01, minGain: 0.01 },
35
- /** The game's `grito`: `1 / (1 + d² × 0.006)`, silent below 0.02 (jogo L62129–62130). */
36
- game_scream: { model: "inverse_square", k: 6e-3, minGain: 0.02 },
37
- /** The game's `voz`: `1 / (1 + d² × 0.01)`, silent below 0.02 (jogo L62146–62147). */
38
- game_voice: { model: "inverse_square", k: 0.01, minGain: 0.02 },
39
- /** The game's `boom`: `1.4 / (1 + d² × 0.002)`, never silent (jogo L68280). */
40
- game_boom: { model: "inverse_square", k: 2e-3, scale: 1.4 },
41
- /** The art scene's `outAt`: `vol / (1 + d² × 0.008)` (cena L1320). */
42
- art_scene: { model: "inverse_square", k: 8e-3 },
43
- /** The game's animal calls: `max(0, 1 − d / 70) × 0.25`, silent at or below 0.005 (jogo L66627–66628). */
44
- animals: { model: "linear", range: 70, scale: 0.25, minGain: 5e-3 }
45
- };
46
- function falloffGain(falloff, volume, distance) {
47
- if (!falloff || falloff.model === "none") return volume;
48
- if (falloff.model === "linear") {
49
- const level2 = Math.max(0, 1 - distance / falloff.range) * volume;
50
- return falloff.scale === void 0 ? level2 : level2 * falloff.scale;
51
- }
52
- const level = volume / (1 + distance * distance * falloff.k);
53
- return falloff.scale === void 0 ? level : falloff.scale * level;
54
- }
55
- function isSilent(falloff, gain) {
56
- if (!falloff || falloff.model === "none" || falloff.minGain === void 0) return false;
57
- return falloff.model === "linear" ? gain <= falloff.minGain : gain < falloff.minGain;
58
- }
59
- function cutoffDivisor(falloff, distance) {
60
- if (!falloff || falloff.model !== "inverse_square" || falloff.cutoffK === void 0) return 1;
61
- return 1 + distance * falloff.cutoffK;
62
- }
63
-
64
- // src/listener.ts
65
- var DEFAULT_LISTENER = { position: [0, 0, 0], yaw: 0 };
66
- var PAN_LIMIT = 0.85;
67
- var PAN_MIN_DISTANCE = 2;
68
- function listenerDistance(listener, position, mode = "xz") {
69
- const dx = position[0] - listener.position[0];
70
- const dz = position[2] - listener.position[2];
71
- if (mode === "xz") return Math.hypot(dx, dz);
72
- return Math.hypot(dx, position[1] - listener.position[1], dz);
73
- }
74
- function panFor(listener, position) {
75
- const rightX = Math.cos(listener.yaw);
76
- const rightZ = -Math.sin(listener.yaw);
77
- const dx = position[0] - listener.position[0];
78
- const dz = position[2] - listener.position[2];
79
- const distance = Math.hypot(dx, dz) || 1;
80
- const pan = (dx * rightX + dz * rightZ) / Math.max(distance, PAN_MIN_DISTANCE);
81
- return pan < -PAN_LIMIT ? -PAN_LIMIT : pan > PAN_LIMIT ? PAN_LIMIT : pan;
82
- }
83
-
84
- // src/data/voice-groups.json
85
- var voice_groups_default = {
86
- undead_voice: {
87
- maxConcurrent: 5,
88
- cooldown: 0.25,
89
- maxDistance: 40,
90
- sources: [
91
- "cena:L1342 `AU.groans > 4` refuses, so five play at once",
92
- "jogo:L66986 one groan every 0.25 s (`groanBudget`), only nearer than 40 m",
93
- "jogo:L70472 the budget counts down by the frame time"
94
- ]
95
- }
96
- };
97
-
98
- // src/voices.ts
99
- var VOICE_GROUPS = voice_groups_default;
100
- var BUS_PRIORITY = { ui: 5, weapons: 4, voices: 3, world: 2, weather: 1, ambience: 1 };
101
- var DEFAULT_MAX_VOICES = 32;
102
- function busPriority(bus) {
103
- return BUS_PRIORITY[bus];
104
- }
105
- function createVoiceManager(options = {}) {
106
- const groups = new Map(Object.entries(options.groups ?? VOICE_GROUPS));
107
- const maxVoices = options.maxVoices ?? DEFAULT_MAX_VOICES;
108
- const budgets = /* @__PURE__ */ new Map();
109
- let voices = [];
110
- let nextId = 1;
111
- let peak = 0;
112
- let dropped = 0;
113
- const refuse = (reason) => {
114
- dropped += 1;
115
- return { accepted: false, reason };
116
- };
117
- const groupCheck = (request, evicted) => {
118
- const group = request.group === void 0 ? void 0 : groups.get(request.group);
119
- if (!group) return void 0;
120
- if (group.maxDistance !== void 0 && !((request.distance ?? 0) < group.maxDistance)) return "distance";
121
- if (group.cooldown !== void 0 && (budgets.get(request.group) ?? 0) > 0) return "cooldown";
122
- const members = voices.filter((voice) => voice.group === request.group);
123
- if (group.maxConcurrent === void 0 || members.length < group.maxConcurrent) return void 0;
124
- if (!group.steal) return "group_full";
125
- evicted.push(members[0].id);
126
- return void 0;
127
- };
128
- return {
129
- request(request) {
130
- const evicted = [];
131
- const refusal = groupCheck(request, evicted);
132
- if (refusal) return refuse(refusal);
133
- const score = request.priority * request.gain;
134
- const remaining = voices.filter((voice) => !evicted.includes(voice.id));
135
- if (remaining.length >= maxVoices) {
136
- const lowest = remaining.reduce((low, voice) => voice.score < low.score ? voice : low);
137
- if (score <= lowest.score) return refuse("global_full");
138
- evicted.push(lowest.id);
139
- dropped += 1;
140
- }
141
- const group = request.group === void 0 ? void 0 : groups.get(request.group);
142
- if (group?.cooldown !== void 0) budgets.set(request.group, group.cooldown);
143
- const id = nextId++;
144
- voices = [...voices.filter((voice) => !evicted.includes(voice.id)), { id, ...request.group === void 0 ? {} : { group: request.group }, score, remaining: request.length }];
145
- peak = Math.max(peak, voices.length);
146
- return { accepted: true, id, evicted };
147
- },
148
- release(id) {
149
- voices = voices.filter((voice) => voice.id !== id);
150
- },
151
- setLength(id, seconds) {
152
- const voice = voices.find((entry) => entry.id === id);
153
- if (voice) voice.remaining = seconds;
154
- },
155
- advance(dt) {
156
- for (const [group, budget] of budgets) budgets.set(group, budget - dt);
157
- const ended = [];
158
- for (const voice of voices) {
159
- voice.remaining -= dt;
160
- if (voice.remaining <= 0) ended.push(voice.id);
161
- }
162
- if (ended.length > 0) voices = voices.filter((voice) => voice.remaining > 0);
163
- return ended;
164
- },
165
- setGroup(id, group) {
166
- if (group) groups.set(id, group);
167
- else groups.delete(id);
168
- },
169
- stats: () => ({ active: voices.length, peak, dropped, maxVoices })
170
- };
171
- }
1
+ import {
2
+ BENCH_BANK,
3
+ BUILD_ORDERS,
4
+ BUS_IDS,
5
+ BUS_PRIORITY,
6
+ CALIBRATION_ID,
7
+ CALIBRATION_LOOP_ID,
8
+ CALIBRATION_LOOP_SOUND,
9
+ CALIBRATION_SOUND,
10
+ CRITERIA,
11
+ CRITERIA_TARGETS,
12
+ CROSSFADE_STEPS,
13
+ DEFAULT_CROSSOVER,
14
+ DEFAULT_LISTENER,
15
+ DEFAULT_LOOP_CROSSFADE,
16
+ DEFAULT_MAX_VOICES,
17
+ DEFAULT_MIX,
18
+ DEFAULT_SAMPLE_CUTOFF_K,
19
+ DEFAULT_SAMPLE_FALLOFF,
20
+ DEFAULT_SAMPLE_PITCH,
21
+ DEFAULT_TAIL_GAIN,
22
+ DISTANCE_CURVES,
23
+ GAME_SFX_BANK,
24
+ GAME_SFX_CLASSES,
25
+ GAME_SFX_FALLBACK,
26
+ LAYER_FLOOR,
27
+ LIBRARY_BANK,
28
+ LIBRARY_LOOPS,
29
+ LIBRARY_SOUNDS,
30
+ LOOP_SMOOTHING,
31
+ LOOP_START_ABOVE,
32
+ MIX_PROFILES,
33
+ OPEN_CUTOFF,
34
+ PAN_LIMIT,
35
+ PAN_MIN_DISTANCE,
36
+ SAMPLE_ENVIRONMENTS,
37
+ SFX_BLOWS,
38
+ SFX_CATALOG,
39
+ SFX_CATEGORIES,
40
+ SFX_IMPACTS,
41
+ SFX_MATERIALS,
42
+ VOICE_GROUPS,
43
+ audioBenchTextOf,
44
+ balanceOf,
45
+ bufferOf,
46
+ buildChain,
47
+ busGain,
48
+ busPriority,
49
+ calibrationLoader,
50
+ centroidHz,
51
+ countHits,
52
+ createAudioEngine,
53
+ createAudioTestModule,
54
+ createLoopState,
55
+ createRng,
56
+ createSampleStore,
57
+ createSetPicker,
58
+ createSoundRegistry,
59
+ createVoiceManager,
60
+ crossGains,
61
+ cutoffDivisor,
62
+ dbOf,
63
+ drawBetween,
64
+ encodeWav,
65
+ endDropDb,
66
+ equalPowerIn,
67
+ falloffGain,
68
+ farMixAt,
69
+ fetchLoader,
70
+ fillImpulse,
71
+ fillNoise,
72
+ globalContext,
73
+ impactSoundId,
74
+ inlineLoader,
75
+ isCalibrationUrl,
76
+ isSilent,
77
+ limiterCurve,
78
+ listenerDistance,
79
+ loopCrossfade,
80
+ measureCriteria,
81
+ noiseClassRecipe,
82
+ onsetIndex,
83
+ panFor,
84
+ peakIndex,
85
+ peakOf,
86
+ pickTake,
87
+ planSample,
88
+ planSound,
89
+ realize,
90
+ realizeSample,
91
+ recordOutput,
92
+ resolveMix,
93
+ retunePlan,
94
+ ringSeconds,
95
+ rmsDb,
96
+ sampleCutoff,
97
+ sampleLength,
98
+ sampleUrls,
99
+ sfxState,
100
+ streamFor,
101
+ streamSeed,
102
+ tierFor,
103
+ unlockContext
104
+ } from "./chunk-7TLFY7VO.js";
172
105
 
173
- // src/plan.ts
174
- var DEFAULT_TAIL = 0.05;
175
- var DEFAULT_NOISE_SECONDS = 1.5;
176
- var OCCLUSION_GAIN = 0.5;
177
- var OCCLUSION_CUTOFF = 0.6;
178
- function isParamRef(range) {
179
- return typeof range === "object" && !Array.isArray(range);
180
- }
181
- function draw(range, scope) {
182
- if (typeof range === "number") return range;
183
- if (isParamRef(range)) {
184
- const value = scope.params[range.param];
185
- if (value === void 0) throw new Error(`game-audio: the recipe reads the param "${range.param}", which was not given`);
186
- return value * (range.scale ?? 1) + (range.add ?? 0);
106
+ // src/manifest.ts
107
+ var SDK_LICENSES = ["CC0", "CC-BY"];
108
+ var SFX_LAYERS = ["close", "far", "tail_in", "tail_out"];
109
+ var SFX_TIERS = { light: 0, medium: 0.34, heavy: 0.67 };
110
+ function parseSfxName(name) {
111
+ const match = /^(.*?)(?:_(close|far|tail_in|tail_out))?(?:_(\d+))?$/.exec(name);
112
+ const id = match?.[1] || name;
113
+ const layer = match?.[2] ?? "close";
114
+ const take = match?.[3] ? Number(match[3]) : 1;
115
+ return { id, layer, take };
116
+ }
117
+ function splitTier(id) {
118
+ const match = /^(.*)_(light|medium|heavy)$/.exec(id);
119
+ return match ? { base: match[1], tier: match[2] } : { base: id };
120
+ }
121
+ var refsOf = (entries, baseUrl) => (entries ?? []).map((entry) => ({ url: `${baseUrl}${entry.file}` }));
122
+ function sampleBankFromManifest(manifest, options) {
123
+ const baseUrl = options.baseUrl ?? "";
124
+ const samples = [];
125
+ const tiersOf = /* @__PURE__ */ new Map();
126
+ for (const sound of manifest.sounds) {
127
+ const { base, tier } = splitTier(sound.id);
128
+ if (tier) tiersOf.set(base, [...tiersOf.get(base) ?? [], sound]);
187
129
  }
188
- const [min, max] = range;
189
- return min + scope.random() * (max - min);
190
- }
191
- function drawTime(time, scope) {
192
- if (time === "duration" || typeof time === "string" && time.endsWith("d")) return time;
193
- return draw(time, scope);
194
- }
195
- function timeOf(time, duration) {
196
- if (typeof time === "number") return time;
197
- if (time === "duration") return duration;
198
- return Number(time.slice(0, -1)) * duration;
199
- }
200
- function drawAutomation(automation, scope) {
201
- const pending = {};
202
- for (const key of Object.keys(automation)) {
203
- if (key === "set" && "set" in automation) pending.value = draw(automation.set, scope);
204
- else if (key === "from" && "from" in automation) pending.from = draw(automation.from, scope);
205
- else if (key === "to" && automation.to !== void 0) pending.to = automation.to === "from" ? pending.from ?? pending.value ?? 0 : draw(automation.to, scope);
206
- else if (key === "curve") pending.curve = automation.curve;
207
- else if (key === "over" && automation.over !== void 0) pending.over = drawTime(automation.over, scope);
130
+ const bases = /* @__PURE__ */ new Map();
131
+ for (const sound of manifest.sounds) {
132
+ if (!splitTier(sound.id).tier) bases.set(sound.id, sound);
208
133
  }
209
- return pending;
210
- }
211
- function finishAutomation(pending, duration) {
212
- if (pending.from !== void 0 && pending.to === void 0) return { from: pending.from };
213
- if (pending.from !== void 0) return { from: pending.from, to: pending.to, curve: pending.curve ?? "linear", at: timeOf(pending.over ?? "duration", duration) };
214
- if (pending.to === void 0 || pending.over === void 0) return { value: pending.value };
215
- return { value: pending.value, to: pending.to, curve: pending.curve ?? "linear", at: timeOf(pending.over, duration) };
216
- }
217
- var startFrequency = (automation) => automation.from ?? automation.value ?? 0;
218
- function drawFilter(spec, scope) {
219
- const pending = { spec, frequency: {} };
220
- for (const key of Object.keys(spec)) {
221
- if (key === "frequency") pending.frequency = drawAutomation(spec.frequency, scope);
222
- else if (key === "q" && spec.q !== void 0) pending.q = draw(spec.q, scope);
223
- else if (key === "gain" && spec.gain !== void 0) pending.gain = draw(spec.gain, scope);
224
- else if (key === "level" && spec.level !== void 0) pending.level = draw(spec.level, scope);
134
+ for (const [base, tiers] of tiersOf) {
135
+ if (!bases.has(base)) bases.set(base, { id: base, category: tiers[0]?.category ?? "", layers: { close: tiers[0]?.layers.close ?? [] } });
225
136
  }
226
- return pending;
227
- }
228
- function drawModulator(modulator, scope) {
229
- const pending = { modulator, rate: 0 };
230
- for (const key of Object.keys(modulator)) {
231
- if (key === "rate") pending.rate = draw(modulator.rate, scope);
232
- else if (key === "depth" && !(typeof modulator.depth === "object" && "scaleOf" in modulator.depth)) pending.depth = draw(modulator.depth, scope);
233
- }
234
- return pending;
235
- }
236
- function drawVoice(source, scope) {
237
- const pending = { frequency: {}, vibratoRate: 0, formants: [], breath: { frequency: 0, q: source.breath.q, gain: 0 } };
238
- for (const key of Object.keys(source)) {
239
- if (key === "frequency") pending.frequency = drawAutomation(source.frequency, scope);
240
- else if (key === "vibrato") pending.vibratoRate = draw(source.vibrato.rate, scope);
241
- else if (key === "formants") pending.formants = source.formants.map((formant) => ({ frequency: draw(formant.frequency, scope), q: formant.q }));
242
- else if (key === "breath") pending.breath = { frequency: draw(source.breath.frequency, scope), q: source.breath.q, gain: draw(source.breath.gain, scope) };
243
- }
244
- return pending;
245
- }
246
- function drawLayer(layer, scope) {
247
- const pending = { at: 0, gain: 1, filters: [], modulators: [] };
248
- for (const key of Object.keys(layer)) {
249
- if (key === "at" && layer.at !== void 0) pending.at = draw(layer.at, scope);
250
- else if (key === "duration" && layer.duration !== void 0) pending.duration = draw(layer.duration, scope);
251
- else if (key === "gain" && layer.gain !== void 0) pending.gain = draw(layer.gain, scope);
252
- else if (key === "source" && layer.source.kind === "osc") pending.automation = drawAutomation(layer.source.frequency, scope);
253
- else if (key === "source" && layer.source.kind === "formant_voice") pending.voice = drawVoice(layer.source, scope);
254
- else if (key === "filters" && layer.filters) pending.filters = layer.filters.bank.map((spec) => drawFilter(spec, scope));
255
- else if (key === "modulators" && layer.modulators) pending.modulators = layer.modulators.map((modulator) => drawModulator(modulator, scope));
137
+ for (const sound of bases.values()) {
138
+ const numbers = options.sounds?.[sound.id] ?? options.defaults?.(sound);
139
+ const close = refsOf(sound.layers.close, baseUrl);
140
+ if (!numbers || close.length === 0) continue;
141
+ const tiers = (tiersOf.get(sound.id) ?? []).map((tier) => {
142
+ const name = splitTier(tier.id).tier;
143
+ const tierFar = refsOf(tier.layers.far, baseUrl);
144
+ return { name, from: SFX_TIERS[name] ?? 0, close: refsOf(tier.layers.close, baseUrl), ...tierFar.length > 0 ? { far: tierFar } : {} };
145
+ }).sort((a, b) => a.from - b.from);
146
+ const far = refsOf(sound.layers.far, baseUrl);
147
+ const indoor = refsOf(sound.layers.tail_in, baseUrl);
148
+ const outdoor = refsOf(sound.layers.tail_out, baseUrl);
149
+ const files = [sound, ...tiersOf.get(sound.id) ?? []].flatMap((entry) => Object.values(entry.layers).flatMap((entries) => entries ?? []));
150
+ samples.push({
151
+ id: sound.id,
152
+ bus: numbers.bus,
153
+ close,
154
+ ...far.length > 0 ? { far } : {},
155
+ ...tiers.length > 0 ? { tiers } : {},
156
+ ...numbers.crossover ? { crossover: numbers.crossover } : {},
157
+ ...indoor.length > 0 || outdoor.length > 0 ? { tail: { ...indoor.length > 0 ? { indoor } : {}, ...outdoor.length > 0 ? { outdoor } : {}, ...numbers.tailGain === void 0 ? {} : { gain: numbers.tailGain } } } : {},
158
+ ...numbers.pitch === void 0 ? {} : { pitch: numbers.pitch },
159
+ ...numbers.gain === void 0 ? {} : { gain: numbers.gain },
160
+ ...numbers.falloff ? { falloff: numbers.falloff } : {},
161
+ ...numbers.cutoffK === void 0 ? {} : { cutoffK: numbers.cutoffK },
162
+ ...numbers.group ? { group: numbers.group } : {},
163
+ ...numbers.priority === void 0 ? {} : { priority: numbers.priority },
164
+ ...numbers.fallback ? { fallback: numbers.fallback } : {},
165
+ sources: files.map((file) => `${file.file}: ${file.source} ${file.author} ${file.license}`)
166
+ });
256
167
  }
257
- return pending;
258
- }
259
- function drawOffset(source, duration, scope, noiseSeconds) {
260
- if (source.kind === "formant_voice") return scope.random();
261
- if (source.kind !== "noise" || source.offset === void 0) return 0;
262
- if (typeof source.offset === "number") return source.offset;
263
- if (source.offset === "fit") return scope.random() * Math.max(0, noiseSeconds - duration);
264
- return scope.random() * (source.offsetScale ?? 1);
265
- }
266
- function finishSource(layer, pending, duration, offset) {
267
- const source = layer.source;
268
- if (source.kind === "noise") return { kind: "noise", offset, loop: source.loop === true };
269
- if (source.kind === "osc") return { kind: "osc", wave: source.wave, frequency: finishAutomation(pending.automation ?? {}, duration) };
270
- const voice = pending.voice;
271
- return {
272
- kind: "formant_voice",
273
- wave: source.wave,
274
- frequency: finishAutomation(voice.frequency, duration),
275
- vibrato: { rate: voice.vibratoRate, depth: startFrequency(voice.frequency) * source.vibrato.depth },
276
- formants: voice.formants,
277
- breath: { ...voice.breath, offset },
278
- mix: source.mix
279
- };
280
- }
281
- function finishModulator(pending, sourceFrequency) {
282
- const { modulator } = pending;
283
- const depth = typeof modulator.depth === "object" && "scaleOf" in modulator.depth ? sourceFrequency * modulator.depth.factor : pending.depth ?? 0;
284
- return { target: modulator.target, ...modulator.wave ? { wave: modulator.wave } : {}, rate: pending.rate, depth, ...modulator.base === void 0 ? {} : { base: modulator.base } };
285
- }
286
- function finishEnvelope(envelope2, duration, level) {
287
- return envelope2.map(([time, value, curve, fixed2]) => ({ time: timeOf(time, duration), value: fixed2 === "fixed" ? value : value * level, curve }));
288
- }
289
- function planLayer(layer, scope, defaults, levelInEnvelope, soundLevel) {
290
- const pending = drawLayer(layer, scope);
291
- const duration = pending.duration ?? defaults.duration;
292
- if (duration === void 0) throw new Error("game-audio: a layer needs a duration (its own or the recipe\u2019s)");
293
- const offset = drawOffset(layer.source, duration, scope, defaults.noiseSeconds);
294
- const level = pending.gain * soundLevel;
295
- const sourceFrequency = layer.source.kind === "noise" ? 0 : startFrequency(pending.automation ?? pending.voice?.frequency ?? {});
296
- const planned = {
297
- at: pending.at,
298
- duration,
299
- tail: layer.tail ?? defaults.tail ?? DEFAULT_TAIL,
300
- level,
301
- ...layer.wet === void 0 ? {} : { wet: layer.wet },
302
- source: finishSource(layer, pending, duration, offset),
303
- ...layer.filters ? {
304
- filters: {
305
- mode: layer.filters.mode,
306
- bank: pending.filters.map(({ spec, frequency, q, gain, level: filterLevel }) => ({
307
- type: spec.type,
308
- frequency: finishAutomation(frequency, duration),
309
- ...q === void 0 ? {} : { q },
310
- ...gain === void 0 ? {} : { gain },
311
- ...filterLevel === void 0 ? {} : { level: filterLevel }
312
- }))
313
- }
314
- } : {},
315
- modulators: pending.modulators.map((modulator) => finishModulator(modulator, sourceFrequency)),
316
- envelope: finishEnvelope(layer.envelope, duration, levelInEnvelope ? level : 1)
317
- };
318
- if (!layer.repeat) return [planned];
319
- return Array.from({ length: layer.repeat.count }, (_, index) => ({ ...planned, at: planned.at + index * (layer.repeat?.spacing ?? 0) }));
320
- }
321
- function scaleAutomation(automation, divisor) {
322
- const scale = (value) => value === void 0 ? void 0 : value / divisor;
323
- const scaled = { ...automation };
324
- for (const key of ["value", "from", "to"]) if (automation[key] !== void 0) scaled[key] = scale(automation[key]);
325
- return scaled;
326
- }
327
- function muffle(layer, divisor) {
328
- if (divisor === 1 || !layer.filters) return layer;
329
- const bank = layer.filters.bank.map((filter) => filter.type === "lowpass" ? { ...filter, frequency: scaleAutomation(filter.frequency, divisor) } : filter);
330
- return { ...layer, filters: { ...layer.filters, bank } };
331
- }
332
- var layerEnd = (layer) => layer.at + layer.duration + layer.tail;
333
- function planSound(recipe, input = {}) {
334
- const listener = input.listener ?? DEFAULT_LISTENER;
335
- const distance = input.distance ?? (input.position ? listenerDistance(listener, input.position, input.distanceMode) : 0);
336
- const occlusion = Math.min(1, Math.max(0, input.occlusion ?? 0));
337
- const order = recipe.order ?? "layered";
338
- const falloffLevel = falloffGain(recipe.falloff, input.volume ?? 1, distance);
339
- const level = occlusion > 0 ? falloffLevel * (1 - OCCLUSION_GAIN * occlusion) : falloffLevel;
340
- const silent = isSilent(recipe.falloff, falloffLevel);
341
- const base = {
342
- id: recipe.id,
343
- bus: recipe.bus,
344
- order,
345
- ...recipe.group === void 0 ? {} : { group: recipe.group },
346
- priority: recipe.priority ?? busPriority(recipe.bus),
347
- level,
348
- distance,
349
- ...recipe.pan ? { pan: input.position ? panFor(listener, input.position) : 0 } : {}
350
- };
351
- if (silent) return recipe.keepSilent ? { ...base, silent: true, length: 0, layers: [] } : null;
352
- const scope = { random: input.random ?? createRng(1), params: { ...input.params } };
353
- for (const [name, range] of Object.entries(recipe.vars ?? {})) if (scope.params[name] === void 0) scope.params[name] = draw(range, scope);
354
- const defaults = {
355
- ...recipe.duration === void 0 ? {} : { duration: draw(recipe.duration, scope) },
356
- ...recipe.tail === void 0 ? {} : { tail: recipe.tail },
357
- noiseSeconds: input.noiseSeconds ?? DEFAULT_NOISE_SECONDS
358
- };
359
- const divisor = cutoffDivisor(recipe.falloff, distance) / (1 - OCCLUSION_CUTOFF * occlusion);
360
- const layers = recipe.layers.flatMap((layer) => planLayer(layer, scope, defaults, order !== "layered", level)).map((layer) => muffle(layer, divisor));
361
- return { ...base, silent: false, length: Math.max(0, ...layers.map(layerEnd)), layers };
168
+ return { id: options.id, samples };
362
169
  }
363
170
 
364
- // src/loops.ts
365
- var LOOP_START_ABOVE = 2e-3;
366
- var LOOP_SMOOTHING = { volume: 0.15, frequency: 0.08 };
367
- function createLoopState(recipe, open = false) {
368
- const startAbove = recipe.startAbove ?? LOOP_START_ABOVE;
369
- let created = open;
370
- let volume = recipe.volume ?? 0;
371
- return {
372
- set(state) {
373
- volume = state.volume ?? volume;
374
- const create = !created;
375
- if (create && !(volume >= startAbove)) return null;
376
- created = true;
377
- const frequency = recipe.source.kind === "osc" && state.frequency ? state.frequency : void 0;
378
- return { create, volume, ...frequency === void 0 ? {} : { frequency } };
379
- },
380
- get created() {
381
- return created;
382
- },
383
- reset() {
384
- created = false;
385
- }
386
- };
387
- }
388
-
389
- // src/data/mix-profiles.json
390
- var mix_profiles_default = [
391
- {
392
- id: "game",
393
- master: 0.5,
394
- noise: { seconds: 1.5, create: "lazy" },
395
- sources: ["jogo:L62077-62081 master 0.5 to the output", "jogo:L62082-62088 noise 1.5 s made by the first sound that needs it"]
396
- },
397
- {
398
- id: "art_scene",
399
- master: 0.85,
400
- compressor: { threshold: -12, ratio: 5 },
401
- reverb: { seconds: 2.2, decay: 3.4, wet: 0.4 },
402
- noise: { seconds: 2, create: "eager" },
403
- sources: [
404
- "cena:L1308 compressor -12 dB, ratio 5",
405
- "cena:L1309 master 0.85",
406
- "cena:L1310 convolver, impulse 2.2 s of (1 - i/len)^3.4",
407
- "cena:L1311 wet 0.4",
408
- "cena:L1312 noise 2 s made with the chain"
409
- ]
171
+ // src/kit-samples.ts
172
+ var KIT_CATEGORY_BUS = {
173
+ armas: "weapons",
174
+ impactos: "world",
175
+ "explosoes-fogo": "world",
176
+ personagem: "world",
177
+ veiculos: "world",
178
+ "itens-portas": "world",
179
+ ambiente: "ambience"
180
+ };
181
+ var VOICE_IDS = /^(player_(hurt|death|effort|breath)|scream|zombie_)/;
182
+ var KIT_SAMPLE_ALIASES = {
183
+ // a house door: the latch giving, the hinge, the leaf meeting the frame, a locked one shaken; a drawer on its runners
184
+ latch: "metal_latch",
185
+ creak_wood: "door_creak",
186
+ shut_wood: "door_wood_shut",
187
+ rattle: "door_locked_rattle",
188
+ // a drawer stays on its recipe: the recorded runs (1 to 1.9 s) outlast a drawer's pull
189
+ // an item taken in the hand (game-destruction-three grab_* keys)
190
+ grab_hard: "item_pickup_generic",
191
+ grab_soft: "item_pickup_leather"
192
+ };
193
+ function kitSampleDefaults(sound) {
194
+ const bus = VOICE_IDS.test(sound.id) ? "voices" : KIT_CATEGORY_BUS[sound.category];
195
+ if (!bus) return void 0;
196
+ return { bus, pitch: sound.category === "ambiente" || /_loop/.test(sound.id) ? 0 : 0.04 };
197
+ }
198
+ function withAliases(manifest, aliases) {
199
+ const byId = new Map(manifest.sounds.map((sound) => [sound.id, sound]));
200
+ const extra = [];
201
+ for (const [alias, target] of Object.entries(aliases)) {
202
+ const sound = byId.get(target);
203
+ if (sound && !byId.has(alias)) extra.push({ ...sound, id: alias });
410
204
  }
411
- ];
412
-
413
- // src/mix.ts
414
- var MIX_PROFILES = Object.fromEntries(
415
- mix_profiles_default.map((profile) => [profile.id, profile])
416
- );
417
- var DEFAULT_MIX = "art_scene";
418
- function resolveMix(mix, profiles = MIX_PROFILES) {
419
- if (typeof mix !== "string") return mix;
420
- const profile = profiles[mix];
421
- if (!profile) throw new Error(`game-audio: unknown mix profile "${mix}" (known: ${Object.keys(profiles).join(", ")})`);
422
- return profile;
423
- }
424
- function busGain(setting) {
425
- if (!setting) return 1;
426
- return setting.muted ? 0 : setting.gain ?? 1;
205
+ return { ...manifest, sounds: [...manifest.sounds, ...extra] };
427
206
  }
428
-
429
- // src/bank.ts
430
- function isPlainObject(value) {
431
- return typeof value === "object" && value !== null && !Array.isArray(value);
207
+ function kitSampleBank(manifest, options = {}) {
208
+ return sampleBankFromManifest(withAliases(manifest, options.aliases ?? KIT_SAMPLE_ALIASES), {
209
+ id: options.id ?? "kit_samples",
210
+ baseUrl: options.baseUrl ?? "",
211
+ defaults: kitSampleDefaults
212
+ });
432
213
  }
433
- function mergeRecords(base, patch) {
434
- const merged = { ...base };
435
- for (const [key, value] of Object.entries(patch)) {
436
- if (value === void 0) continue;
437
- const current = merged[key];
438
- merged[key] = isPlainObject(current) && isPlainObject(value) ? mergeRecords(current, value) : value;
214
+ var isFileUrl = (url) => {
215
+ const page = globalThis.location?.href;
216
+ try {
217
+ return new URL(url, page).protocol === "file:";
218
+ } catch {
219
+ return false;
439
220
  }
440
- return merged;
441
- }
442
- function createSoundRegistry(banks = []) {
443
- const sounds = /* @__PURE__ */ new Map();
444
- const loops = /* @__PURE__ */ new Map();
445
- const owners = /* @__PURE__ */ new Map();
446
- const registry = {
447
- register(bank) {
448
- for (const sound of bank.sounds ?? []) {
449
- sounds.set(sound.id, sound);
450
- owners.set(sound.id, bank.id);
451
- }
452
- for (const loop of bank.loops ?? []) {
453
- loops.set(loop.id, loop);
454
- owners.set(loop.id, bank.id);
455
- }
456
- },
457
- patch(id, patch) {
458
- const sound = sounds.get(id);
459
- if (sound) sounds.set(id, mergeRecords(sound, patch));
460
- const loop = loops.get(id);
461
- if (loop) loops.set(id, mergeRecords(loop, patch));
462
- },
463
- remove(id) {
464
- sounds.delete(id);
465
- loops.delete(id);
466
- owners.delete(id);
467
- },
468
- sound: (id) => sounds.get(id),
469
- loop: (id) => loops.get(id),
470
- soundIds: () => [...sounds.keys()],
471
- loopIds: () => [...loops.keys()],
472
- bankOf: (id) => owners.get(id)
473
- };
474
- for (const bank of banks) registry.register(bank);
475
- return registry;
476
- }
477
-
478
- // src/data/game-sfx.json
479
- var game_sfx_default = {
480
- sources: ["jogo:L62089-62107"],
481
- note: "The game's sfx table P: [lowpass cutoff Hz, peak gain, seconds]. Played as a noise burst with the game's distance curve (falloff game_sfx) and a 0.05 s tail. Team names in `team`.",
482
- classes: [
483
- { id: "pistol", team: "pistola", bus: "weapons", cutoff: 1800, gain: 0.9, seconds: 0.18 },
484
- { id: "shotgun", team: "escopeta", bus: "weapons", cutoff: 900, gain: 1.2, seconds: 0.35 },
485
- { id: "rifle", team: "fuzil", bus: "weapons", cutoff: 1400, gain: 1.1, seconds: 0.28 },
486
- { id: "long_rifle", team: "rifle", bus: "weapons", cutoff: 1100, gain: 1.3, seconds: 0.45 },
487
- { id: "impact", team: "impacto", bus: "world", cutoff: 2500, gain: 0.25, seconds: 0.05 },
488
- { id: "flesh", team: "carne", bus: "world", cutoff: 600, gain: 0.35, seconds: 0.08 },
489
- { id: "step", team: "passo", bus: "world", cutoff: 400, gain: 0.08, seconds: 0.05 },
490
- { id: "glass", team: "vidro", bus: "world", cutoff: 5e3, gain: 0.5, seconds: 0.3 },
491
- { id: "wood", team: "madeira", bus: "world", cutoff: 700, gain: 0.5, seconds: 0.2 },
492
- { id: "reload", team: "recarga", bus: "weapons", cutoff: 3e3, gain: 0.15, seconds: 0.06 },
493
- { id: "empty", team: "vazio", bus: "weapons", cutoff: 4e3, gain: 0.12, seconds: 0.03 },
494
- { id: "explosion", team: "explosao", bus: "world", cutoff: 200, gain: 1.6, seconds: 1.4 }
495
- ],
496
- fallback: { id: "unknown", team: "(any other name)", bus: "world", cutoff: 1e3, gain: 0.5, seconds: 0.1 }
497
221
  };
498
-
499
- // src/recipes/noise-class.ts
500
- var GAME_SFX = game_sfx_default;
501
- var GAME_SFX_CLASSES = GAME_SFX.classes;
502
- var GAME_SFX_FALLBACK = GAME_SFX.fallback;
503
- function noiseClassRecipe(row, id = `sfx_${row.id}`) {
504
- return {
505
- id,
506
- bus: row.bus,
507
- order: "burst",
508
- duration: row.seconds,
509
- tail: 0.05,
510
- layers: [
511
- {
512
- source: { kind: "noise", offset: "random" },
513
- filters: { mode: "serial", bank: [{ type: "lowpass", frequency: { set: row.cutoff } }] },
514
- envelope: [
515
- [0, row.gain, "set"],
516
- ["1d", 1e-3, "exp", "fixed"]
517
- ]
518
- }
519
- ],
520
- falloff: DISTANCE_CURVES.game_sfx,
521
- sources: [...GAME_SFX.sources.map((source) => `${source} ${row.team}`)]
522
- };
222
+ var fetchJson = async (url) => {
223
+ if (isFileUrl(url)) throw new Error(`${url}: file:// is not fetched`);
224
+ const response = await fetch(url);
225
+ if (!response.ok) throw new Error(`${url}: ${response.status}`);
226
+ return await response.json();
227
+ };
228
+ async function loadKitSamples(engine, options = {}) {
229
+ const baseUrl = options.baseUrl ?? "";
230
+ let manifest;
231
+ try {
232
+ manifest = await (options.fetchManifest ?? fetchJson)(`${baseUrl}manifest.json`);
233
+ } catch {
234
+ return null;
235
+ }
236
+ const bank = kitSampleBank(manifest, options);
237
+ engine.register(bank);
238
+ if (options.preload && engine.loadSamples) void engine.loadSamples(options.preload).catch(() => void 0);
239
+ return bank;
523
240
  }
524
- var GAME_SFX_BANK = { id: "game_sfx", sounds: [...GAME_SFX_CLASSES, GAME_SFX_FALLBACK].map((row) => noiseClassRecipe(row)) };
525
241
 
526
242
  // src/recipes/scene.ts
527
243
  var ATTACK = 2e-3;
@@ -600,1085 +316,780 @@ function sceneRecipe(id, layers, line, options = {}) {
600
316
  };
601
317
  }
602
318
 
603
- // src/library/crowd_rumble.json
604
- var crowd_rumble_default = {
605
- id: "crowd_rumble",
606
- bus: "ambience",
607
- order: "game_loop",
608
- source: { kind: "noise", loop: true },
609
- filters: { mode: "serial", bank: [{ type: "lowpass", frequency: { set: 160 } }] },
610
- smoothing: { volume: 0.15, frequency: 0.08 },
611
- startAbove: 2e-3,
612
- sources: ["jogo:L62116 horda: noise through a 160 Hz lowpass", "jogo:L70424 level min(0.16, near \xD7 0.0016)", "temporary home until the crowd package (Q12)"]
319
+ // src/recipes/foley.ts
320
+ var FOLEY_FALLOFF = {
321
+ model: "inverse_square",
322
+ k: 0.02,
323
+ cutoffK: 0.04,
324
+ minGain: 4e-3
613
325
  };
614
-
615
- // src/library/engine_saw.json
616
- var engine_saw_default = {
617
- id: "engine_saw",
326
+ var vary = (f, pct = 0.04) => [Math.round(f * (1 - pct)), Math.round(f * (1 + pct))];
327
+ var foley = (id, layers, note) => ({
328
+ id,
618
329
  bus: "world",
619
- order: "game_loop",
620
- source: { kind: "osc", wave: "sawtooth", loop: true },
621
- filters: { mode: "serial", bank: [{ type: "lowpass", frequency: { set: 400 } }] },
622
- smoothing: { volume: 0.15, frequency: 0.08 },
623
- startAbove: 2e-3,
624
- sources: [
625
- "jogo:L62115 motor: sawtooth through a 400 Hz lowpass",
626
- "jogo:L70421 level 0.035 + speed \xD7 0.003, frequency 38 + speed \xD7 7 (the host drives `set`)",
627
- "temporary home until the vehicles package (Q12)"
628
- ]
330
+ pan: true,
331
+ layers,
332
+ falloff: FOLEY_FALLOFF,
333
+ sources: [`sdk: ${note}`]
334
+ });
335
+ var click = (f, vol, delay = 0) => [
336
+ sceneNoise({
337
+ type: "bandpass",
338
+ f: vary(f, 0.08),
339
+ q: 4,
340
+ d: [0.018, 0.03],
341
+ vol: [vol * 0.85, vol * 1.1],
342
+ delay
343
+ }),
344
+ sceneTone({
345
+ f: vary(f * 0.8, 0.06),
346
+ f2: Math.round(f * 0.62),
347
+ d: [0.015, 0.025],
348
+ vol: vol * 0.18,
349
+ delay
350
+ })
351
+ ];
352
+ var meet = (body, panel, vol, latch) => [
353
+ sceneTone({
354
+ f: vary(body),
355
+ f2: Math.round(body * 0.5),
356
+ d: [0.12, 0.16],
357
+ vol: [vol * 0.9, vol * 1.1]
358
+ }),
359
+ sceneNoise({
360
+ type: "bandpass",
361
+ f: vary(panel, 0.06),
362
+ q: 1.2,
363
+ d: [0.08, 0.12],
364
+ vol: [vol * 0.9, vol * 1.1],
365
+ wet: 0.25
366
+ }),
367
+ ...click(latch, vol * 0.45, [0.012, 0.028])
368
+ ];
369
+ var LEAF_FOLEY = [
370
+ // a wooden house door or wardrobe door: latch, a short creak, the leaf on the frame (the hard slam adds the frame rattling)
371
+ foley("door_wood_open", click(2400, 0.4), "the latch of a wooden door giving"),
372
+ foley(
373
+ "door_creak",
374
+ [
375
+ sceneTone({ f: [190, 240], f2: 310, d: [0.4, 0.55], vol: [0.04, 0.06] }),
376
+ sceneNoise({
377
+ type: "bandpass",
378
+ f: [480, 560],
379
+ q: 6,
380
+ a: 0.05,
381
+ d: [0.35, 0.5],
382
+ vol: [0.1, 0.14]
383
+ })
384
+ ],
385
+ "a wooden hinge turning"
386
+ ),
387
+ foley("door_wood_close", meet(120, 600, 0.55, 2400), "a wooden leaf meeting its frame"),
388
+ foley(
389
+ "door_wood_slam",
390
+ [
391
+ ...meet(110, 560, 0.85, 2300),
392
+ ...sceneMany(
393
+ 3,
394
+ () => sceneNoise({
395
+ type: "bandpass",
396
+ f: [900, 1500],
397
+ q: 3,
398
+ d: 0.03,
399
+ vol: [0.08, 0.14],
400
+ delay: [0.05, 0.18]
401
+ })
402
+ )
403
+ ],
404
+ "a wooden door slammed: the frame and the hinges rattle after the hit"
405
+ ),
406
+ // a metal door or gate: a hollow panel that rings a little
407
+ foley("door_metal_open_close", [...meet(160, 900, 0.55, 2e3), sceneTone({ f: vary(1250), f2: 1150, d: [0.1, 0.16], vol: 0.06, wet: 0.3 })], "a metal door or gate meeting its frame"),
408
+ foley(
409
+ "door_creak_metal",
410
+ [
411
+ sceneTone({ f: [620, 760], f2: 900, d: [0.3, 0.4], vol: [0.03, 0.045] }),
412
+ sceneNoise({
413
+ type: "bandpass",
414
+ f: [1300, 1500],
415
+ q: 8,
416
+ a: 0.04,
417
+ d: [0.25, 0.35],
418
+ vol: [0.07, 0.09]
419
+ })
420
+ ],
421
+ "a metal hinge turning"
422
+ ),
423
+ // the handle of a locked door shaken: the latch knocking in its keeper, five to seven times in half a second
424
+ foley(
425
+ "door_locked_rattle",
426
+ [
427
+ ...sceneMany(
428
+ 6,
429
+ () => sceneNoise({
430
+ type: "bandpass",
431
+ f: [1600, 2600],
432
+ q: 3,
433
+ d: [0.025, 0.04],
434
+ vol: [0.22, 0.34],
435
+ delay: [0, 0.45]
436
+ })
437
+ ),
438
+ ...sceneMany(
439
+ 3,
440
+ () => sceneTone({
441
+ f: [170, 210],
442
+ f2: 120,
443
+ d: 0.05,
444
+ vol: [0.12, 0.18],
445
+ delay: [0.02, 0.4]
446
+ })
447
+ )
448
+ ],
449
+ "the handle of a locked door shaken: latch knocks and the leaf thumping in its frame"
450
+ ),
451
+ // a fridge: the rubber seal lets go with a soft suck, the bottles in the door clink; closing it is a soft thump and the seal pulling shut
452
+ foley(
453
+ "fridge_open",
454
+ [
455
+ sceneNoise({
456
+ type: "lowpass",
457
+ f: [320, 380],
458
+ a: 0.03,
459
+ d: [0.14, 0.2],
460
+ vol: [0.32, 0.4]
461
+ }),
462
+ sceneNoise({
463
+ type: "bandpass",
464
+ f: [800, 950],
465
+ f2: 1400,
466
+ q: 2,
467
+ a: 0.02,
468
+ d: 0.12,
469
+ vol: [0.08, 0.12]
470
+ }),
471
+ ...sceneMany(
472
+ 2,
473
+ () => sceneTone({
474
+ f: [2600, 4200],
475
+ d: [0.04, 0.08],
476
+ vol: [0.015, 0.03],
477
+ delay: [0.08, 0.22]
478
+ })
479
+ )
480
+ ],
481
+ "a fridge door: the seal letting go and the bottles in the door"
482
+ ),
483
+ foley(
484
+ "fridge_close",
485
+ [
486
+ sceneTone({ f: vary(85), f2: 45, d: [0.1, 0.13], vol: [0.38, 0.46] }),
487
+ sceneNoise({
488
+ type: "lowpass",
489
+ f: [520, 620],
490
+ d: [0.08, 0.12],
491
+ vol: [0.3, 0.36]
492
+ }),
493
+ sceneNoise({
494
+ type: "lowpass",
495
+ f: [260, 320],
496
+ a: 0.02,
497
+ d: 0.1,
498
+ vol: [0.12, 0.18],
499
+ delay: [0.04, 0.07]
500
+ }),
501
+ ...sceneMany(
502
+ 2,
503
+ () => sceneTone({
504
+ f: [2600, 4200],
505
+ d: [0.04, 0.07],
506
+ vol: [0.015, 0.03],
507
+ delay: [0.03, 0.12]
508
+ })
509
+ )
510
+ ],
511
+ "a fridge door shut: a soft thump, the seal pulling and the bottles"
512
+ ),
513
+ // a microwave: the spring catch of the door, plastic on plastic
514
+ foley(
515
+ "microwave_open",
516
+ [
517
+ ...click(1800, 0.34),
518
+ sceneTone({
519
+ f: [3e3, 3400],
520
+ f2: 2800,
521
+ d: 0.05,
522
+ vol: 0.025,
523
+ delay: [0.01, 0.02]
524
+ })
525
+ ],
526
+ "the spring catch of a microwave door"
527
+ ),
528
+ foley(
529
+ "microwave_close",
530
+ [
531
+ sceneNoise({
532
+ type: "bandpass",
533
+ f: [1200, 1450],
534
+ q: 2.5,
535
+ d: [0.04, 0.06],
536
+ vol: [0.36, 0.44]
537
+ }),
538
+ sceneTone({ f: vary(180), f2: 120, d: 0.05, vol: [0.16, 0.22] }),
539
+ ...click(2200, 0.2, [8e-3, 0.016])
540
+ ],
541
+ "a microwave door clacking shut"
542
+ ),
543
+ foley("microwave_beep", [sceneTone({ wave: "square", f: 2e3, d: 0.12, vol: 0.05 })], "the beep of a microwave"),
544
+ // drawers and sliding leaves: the runners, then the stop
545
+ foley(
546
+ "drawer_open",
547
+ [
548
+ sceneNoise({
549
+ type: "bandpass",
550
+ f: [620, 780],
551
+ q: 2,
552
+ a: 0.04,
553
+ d: [0.28, 0.36],
554
+ vol: [0.18, 0.24]
555
+ }),
556
+ sceneNoise({ type: "bandpass", f: [2e3, 2400], q: 5, d: 0.28, vol: 0.04 }),
557
+ ...click(1400, 0.16, [0.28, 0.34])
558
+ ],
559
+ "a drawer on its runners and its stop"
560
+ ),
561
+ foley(
562
+ "drawer_close",
563
+ [
564
+ sceneNoise({
565
+ type: "bandpass",
566
+ f: [620, 780],
567
+ q: 2,
568
+ a: 0.03,
569
+ d: [0.2, 0.28],
570
+ vol: [0.18, 0.24]
571
+ }),
572
+ sceneTone({
573
+ f: vary(150),
574
+ f2: 90,
575
+ d: 0.08,
576
+ vol: [0.22, 0.3],
577
+ delay: [0.2, 0.26]
578
+ })
579
+ ],
580
+ "a drawer pushed home"
581
+ )
582
+ ];
583
+ var ITEM_FOLEY = [
584
+ // the hand closing on the item: a touch of skin and cloth, then the item's own small sound
585
+ foley(
586
+ "item_pickup_metal",
587
+ [
588
+ sceneNoise({ type: "bandpass", f: [700, 900], q: 1, d: 0.06, vol: 0.18 }),
589
+ sceneTone({
590
+ f: [1900, 2600],
591
+ f2: 1700,
592
+ d: [0.05, 0.08],
593
+ vol: [0.06, 0.09],
594
+ delay: [0.01, 0.03]
595
+ })
596
+ ],
597
+ "picking up a metal thing"
598
+ ),
599
+ foley(
600
+ "item_pickup_plastic",
601
+ [
602
+ sceneNoise({ type: "bandpass", f: [700, 900], q: 1, d: 0.06, vol: 0.18 }),
603
+ sceneNoise({
604
+ type: "bandpass",
605
+ f: [1500, 1900],
606
+ q: 3,
607
+ d: 0.03,
608
+ vol: [0.15, 0.21],
609
+ delay: [0.01, 0.03]
610
+ })
611
+ ],
612
+ "picking up a plastic thing"
613
+ ),
614
+ foley(
615
+ "item_pickup_glass",
616
+ [
617
+ sceneNoise({ type: "bandpass", f: [700, 900], q: 1, d: 0.06, vol: 0.15 }),
618
+ sceneTone({
619
+ f: [3200, 4200],
620
+ d: [0.05, 0.08],
621
+ vol: [0.038, 0.06],
622
+ delay: [0.01, 0.03]
623
+ })
624
+ ],
625
+ "picking up a glass thing"
626
+ ),
627
+ foley(
628
+ "item_pickup_paper",
629
+ [
630
+ sceneNoise({
631
+ type: "highpass",
632
+ f: [2600, 3400],
633
+ a: 0.01,
634
+ d: [0.1, 0.14],
635
+ vol: [0.12, 0.18]
636
+ }),
637
+ sceneNoise({ type: "bandpass", f: [800, 1e3], q: 1, d: 0.05, vol: 0.12 })
638
+ ],
639
+ "picking up paper or cardboard"
640
+ ),
641
+ foley(
642
+ "item_pickup_fabric",
643
+ [
644
+ sceneNoise({
645
+ type: "bandpass",
646
+ f: [900, 1300],
647
+ q: 0.8,
648
+ a: 0.02,
649
+ d: [0.12, 0.16],
650
+ vol: [0.15, 0.21]
651
+ })
652
+ ],
653
+ "picking up cloth"
654
+ ),
655
+ foley(
656
+ "item_pickup_wood",
657
+ [
658
+ sceneNoise({ type: "bandpass", f: [700, 900], q: 1, d: 0.06, vol: 0.18 }),
659
+ sceneNoise({
660
+ type: "bandpass",
661
+ f: [900, 1100],
662
+ q: 2,
663
+ d: 0.04,
664
+ vol: [0.15, 0.21],
665
+ delay: [0.01, 0.03]
666
+ })
667
+ ],
668
+ "picking up a wooden thing"
669
+ ),
670
+ foley(
671
+ "item_pickup_food",
672
+ [
673
+ sceneNoise({ type: "bandpass", f: [700, 900], q: 1, d: 0.06, vol: 0.18 }),
674
+ sceneNoise({
675
+ type: "lowpass",
676
+ f: [500, 650],
677
+ d: 0.05,
678
+ vol: 0.12,
679
+ delay: [0.01, 0.03]
680
+ })
681
+ ],
682
+ "picking up food"
683
+ ),
684
+ foley(
685
+ "item_throw",
686
+ [
687
+ sceneNoise({
688
+ type: "bandpass",
689
+ f: [450, 650],
690
+ f2: 1400,
691
+ q: 1.5,
692
+ a: 0.05,
693
+ d: 0.18,
694
+ vol: [0.1, 0.14]
695
+ })
696
+ ],
697
+ "the arm throwing something: air"
698
+ ),
699
+ // a can: the tab cracks, the gas hisses out; drinking is gulps; crushing it crumples the sheet
700
+ foley(
701
+ "can_open",
702
+ [
703
+ ...click(3200, 0.36),
704
+ sceneNoise({
705
+ type: "highpass",
706
+ f: [3600, 4400],
707
+ a: 5e-3,
708
+ d: [0.22, 0.3],
709
+ vol: [0.16, 0.22],
710
+ delay: [0.012, 0.02]
711
+ }),
712
+ ...sceneMany(5, () => sceneTone({ f: [4e3, 7e3], d: 0.02, vol: 0.01, delay: [0.05, 0.4] }))
713
+ ],
714
+ "the tab of a can and the gas hissing out"
715
+ ),
716
+ foley(
717
+ "can_crush",
718
+ [
719
+ sceneNoise({
720
+ type: "bandpass",
721
+ f: [1600, 2200],
722
+ q: 1.2,
723
+ d: [0.18, 0.25],
724
+ vol: [0.3, 0.38]
725
+ }),
726
+ ...sceneMany(
727
+ 6,
728
+ () => sceneTone({
729
+ f: [1200, 3400],
730
+ f2: 900,
731
+ d: 0.03,
732
+ vol: [0.03, 0.06],
733
+ delay: [0, 0.2]
734
+ })
735
+ )
736
+ ],
737
+ "a can crushed in the hand"
738
+ ),
739
+ foley(
740
+ "can_puncture_spray",
741
+ [
742
+ sceneNoise({
743
+ type: "highpass",
744
+ f: [2400, 3e3],
745
+ a: 5e-3,
746
+ d: [0.5, 0.7],
747
+ vol: [0.2, 0.26]
748
+ }),
749
+ sceneNoise({ type: "bandpass", f: [600, 800], q: 2, d: 0.4, vol: 0.06 })
750
+ ],
751
+ "a can holed: the jet hissing out"
752
+ ),
753
+ foley(
754
+ "bottle_open",
755
+ [
756
+ ...sceneMany(
757
+ 5,
758
+ () => sceneNoise({
759
+ type: "bandpass",
760
+ f: [2200, 3e3],
761
+ q: 4,
762
+ d: 8e-3,
763
+ vol: [0.1, 0.16],
764
+ delay: [0, 0.18]
765
+ })
766
+ ),
767
+ sceneNoise({
768
+ type: "highpass",
769
+ f: 3800,
770
+ a: 5e-3,
771
+ d: 0.12,
772
+ vol: [0.06, 0.1],
773
+ delay: [0.18, 0.22]
774
+ })
775
+ ],
776
+ "the screw cap of a bottle turning off"
777
+ ),
778
+ foley(
779
+ "drink_gulp",
780
+ [
781
+ sceneNoise({
782
+ type: "lowpass",
783
+ f: [280, 360],
784
+ a: 0.02,
785
+ d: [0.1, 0.14],
786
+ vol: [0.24, 0.3]
787
+ }),
788
+ sceneTone({ f: [140, 170], f2: 85, d: [0.08, 0.11], vol: [0.12, 0.16] })
789
+ ],
790
+ "a gulp"
791
+ ),
792
+ foley(
793
+ "eat_crunch",
794
+ [
795
+ ...sceneMany(
796
+ 4,
797
+ () => sceneNoise({
798
+ type: "bandpass",
799
+ f: [1800, 3200],
800
+ q: 1.5,
801
+ d: [0.02, 0.04],
802
+ vol: [0.12, 0.2],
803
+ delay: [0, 0.12]
804
+ })
805
+ )
806
+ ],
807
+ "a bite of something crunchy"
808
+ ),
809
+ foley(
810
+ "eat_chew",
811
+ [
812
+ sceneNoise({
813
+ type: "lowpass",
814
+ f: [450, 600],
815
+ a: 0.03,
816
+ d: [0.1, 0.14],
817
+ vol: [0.12, 0.16]
818
+ }),
819
+ sceneNoise({
820
+ type: "bandpass",
821
+ f: [1100, 1400],
822
+ q: 2,
823
+ d: 0.04,
824
+ vol: 0.04,
825
+ delay: [0.03, 0.06]
826
+ })
827
+ ],
828
+ "chewing"
829
+ ),
830
+ foley(
831
+ "bandage_wrap",
832
+ [
833
+ sceneNoise({
834
+ type: "bandpass",
835
+ f: [1400, 1800],
836
+ f2: 2400,
837
+ q: 1,
838
+ a: 0.04,
839
+ d: [0.3, 0.4],
840
+ vol: [0.12, 0.16]
841
+ })
842
+ ],
843
+ "a bandage unrolled round a limb"
844
+ ),
845
+ foley(
846
+ "pills_shake",
847
+ [
848
+ ...sceneMany(
849
+ 8,
850
+ () => sceneTone({
851
+ f: [2400, 3600],
852
+ d: 0.015,
853
+ vol: [0.03, 0.05],
854
+ delay: [0, 0.25]
855
+ })
856
+ ),
857
+ sceneNoise({ type: "bandpass", f: [1500, 1900], q: 2, d: 0.25, vol: 0.05 })
858
+ ],
859
+ "pills shaken in their bottle"
860
+ ),
861
+ foley(
862
+ "medkit_use",
863
+ [
864
+ ...click(1700, 0.24),
865
+ sceneNoise({
866
+ type: "bandpass",
867
+ f: [1e3, 1400],
868
+ q: 1,
869
+ a: 0.03,
870
+ d: [0.25, 0.32],
871
+ vol: [0.08, 0.12],
872
+ delay: [0.05, 0.08]
873
+ })
874
+ ],
875
+ "a first aid kit opened and rummaged"
876
+ ),
877
+ foley("flashlight_click", click(2600, 0.3), "the switch of a flashlight")
878
+ ];
879
+ var FOLEY_BANK = {
880
+ id: "foley",
881
+ sounds: [...LEAF_FOLEY, ...ITEM_FOLEY]
629
882
  };
630
-
631
- // src/library/horn.json
632
- var horn_default = {
633
- id: "horn",
634
- bus: "world",
635
- order: "chord",
636
- duration: 0.6,
637
- tail: 0.02,
638
- layers: [
639
- { source: { kind: "osc", wave: "square", frequency: { set: 415 } }, envelope: [[0, 0.08, "set"], [0.6, 1e-4, "set", "fixed"]] },
640
- { source: { kind: "osc", wave: "square", frequency: { set: 523 } }, envelope: [[0, 0.08, "set"], [0.6, 1e-4, "set", "fixed"]] }
641
- ],
642
- falloff: { model: "none" },
643
- sources: ["jogo:L70272-70276 buzina: squares at 415 and 523 Hz, 0.08 for 0.6 s", "temporary home until the vehicles package (Q12)"]
883
+ var PICKUP_CLASSES = ["metal", "plastic", "glass", "paper", "fabric", "wood", "food"];
884
+ var LEAF_FOLEY_SETS = {
885
+ wood_door: {
886
+ open: "door_wood_open",
887
+ turn: "door_creak",
888
+ close: "door_wood_close",
889
+ slam: "door_wood_slam",
890
+ locked: "door_locked_rattle"
891
+ },
892
+ metal_door: {
893
+ open: "door_wood_open",
894
+ turn: "door_creak_metal",
895
+ close: "door_metal_open_close",
896
+ locked: "door_locked_rattle"
897
+ },
898
+ fridge: {
899
+ open: "fridge_open",
900
+ close: "fridge_close",
901
+ locked: "door_locked_rattle"
902
+ },
903
+ microwave: {
904
+ open: "microwave_open",
905
+ close: "microwave_close",
906
+ locked: "door_locked_rattle"
907
+ },
908
+ drawer: {
909
+ open: "drawer_open",
910
+ close: "drawer_close",
911
+ locked: "door_locked_rattle"
912
+ }
644
913
  };
645
914
 
646
- // src/library/radio_static.json
647
- var radio_static_default = {
648
- id: "radio_static",
649
- bus: "world",
650
- order: "static",
651
- duration: 0.6,
652
- layers: [
653
- {
654
- source: { kind: "noise", offset: "random" },
655
- filters: { mode: "serial", bank: [{ type: "bandpass", frequency: { set: 1800 }, q: 0.8 }] },
656
- envelope: [[0, 0.06, "set"], ["1d", 1e-3, "exp", "fixed"]]
657
- }
658
- ],
659
- falloff: { model: "none" },
660
- sources: ["jogo:L69998-70004 chiado: noise through a 1800 Hz bandpass (Q 0.8), 0.06 falling over 0.6 s", "temporary home until the props or radio package (Q12)"]
915
+ // src/recipes/body-foley.ts
916
+ import {
917
+ BODY_SOUND_IDS,
918
+ FOOTSTEP_SOUND_IDS,
919
+ GAIT_IDS,
920
+ LAND_SOUND_IDS,
921
+ LANDING_IDS,
922
+ SURFACE_IDS,
923
+ SWING_LEAD_SECONDS,
924
+ footstepSoundId
925
+ } from "@adatechnology/game-contracts";
926
+ var BODY_FOLEY_TAKES = 4;
927
+ var TAKES = [
928
+ { f: 1, t: 1, v: 1 },
929
+ { f: 1.08, t: 0.9, v: 0.92 },
930
+ { f: 0.93, t: 1.12, v: 1.05 },
931
+ { f: 1.03, t: 1.05, v: 0.88 }
932
+ ];
933
+ var FOOTSTEP_FALLOFF = { model: "inverse_square", k: 0.03, cutoffK: 0.03, minGain: 4e-3 };
934
+ var BODY_FALLOFF = { model: "inverse_square", k: 0.012, cutoffK: 0.015, minGain: 4e-3 };
935
+ var SURFACES = {
936
+ concrete: { heel: { f: 95, d: 0.05, vol: 0.55 }, roll: { type: "bandpass", f: 2300, q: 1.1, d: 0.05, vol: 0.38 }, grains: { count: 2, f: 4200, q: 2, spread: 0.04, vol: 0.08 } },
937
+ asphalt: { heel: { f: 90, d: 0.05, vol: 0.5 }, roll: { type: "bandpass", f: 1700, q: 0.9, d: 0.06, vol: 0.36 }, grains: { count: 4, f: 3600, q: 2.5, spread: 0.06, vol: 0.1 } },
938
+ wood: { heel: { f: 130, d: 0.08, vol: 0.55 }, roll: { type: "lowpass", f: 1300, q: 0.8, d: 0.06, vol: 0.3 }, ring: [{ f: 210, d: 0.1, vol: 0.18 }, { f: 470, d: 0.06, vol: 0.06 }] },
939
+ tile: { heel: { f: 110, d: 0.04, vol: 0.45 }, roll: { type: "bandpass", f: 3600, q: 2, d: 0.03, vol: 0.42 }, ring: [{ f: 1900, d: 0.03, vol: 0.05 }] },
940
+ dirt: { heel: { f: 75, d: 0.06, vol: 0.45 }, roll: { type: "lowpass", f: 750, q: 0.7, d: 0.09, vol: 0.4 }, grains: { count: 3, f: 1800, q: 1.5, spread: 0.07, vol: 0.06 } },
941
+ grass: { heel: { f: 70, d: 0.05, vol: 0.32 }, roll: { type: "highpass", f: 2600, q: 0.7, d: 0.13, vol: 0.28 }, grains: { count: 4, f: 5200, q: 1.2, spread: 0.1, vol: 0.07 } },
942
+ gravel: { heel: { f: 80, d: 0.05, vol: 0.4 }, roll: { type: "lowpass", f: 950, q: 0.8, d: 0.1, vol: 0.3 }, grains: { count: 8, f: 2600, q: 3, spread: 0.13, vol: 0.2 } },
943
+ sand: { heel: { f: 65, d: 0.06, vol: 0.3 }, roll: { type: "bandpass", f: 1500, q: 0.6, d: 0.16, vol: 0.3 }, grains: { count: 5, f: 4800, q: 1.5, spread: 0.12, vol: 0.05 } },
944
+ metal: { heel: { f: 120, d: 0.05, vol: 0.5 }, roll: { type: "bandpass", f: 2800, q: 1.5, d: 0.03, vol: 0.25 }, ring: [{ f: 420, d: 0.25, vol: 0.16 }, { f: 1130, d: 0.18, vol: 0.09 }, { f: 2470, d: 0.1, vol: 0.04 }] },
945
+ water: { heel: { f: 70, d: 0.04, vol: 0.25 }, roll: { type: "bandpass", f: 3e3, q: 1.2, d: 0.1, vol: 0.18 }, splash: { f: 1100, f2: 380, d: 0.22, vol: 0.55 }, grains: { count: 4, f: 2400, q: 6, spread: 0.18, vol: 0.12 } },
946
+ glass: { heel: { f: 90, d: 0.04, vol: 0.4 }, roll: { type: "highpass", f: 4500, q: 0.8, d: 0.06, vol: 0.2 }, grains: { count: 9, f: 6200, q: 5, spread: 0.12, vol: 0.22 }, ring: [{ f: 3900, d: 0.04, vol: 0.04 }, { f: 5300, d: 0.03, vol: 0.03 }] },
947
+ carpet: { heel: { f: 70, d: 0.05, vol: 0.32 }, roll: { type: "lowpass", f: 420, q: 0.7, d: 0.07, vol: 0.3 } }
661
948
  };
662
-
663
- // src/library/rotor_blades.json
664
- var rotor_blades_default = {
665
- id: "rotor_blades",
666
- bus: "world",
667
- order: "game_loop",
668
- source: { kind: "noise", loop: true },
669
- filters: { mode: "serial", bank: [{ type: "lowpass", frequency: { set: 300 } }] },
670
- modulators: [{ target: "gain", rate: 11, depth: 0.5, base: 0.5 }],
671
- smoothing: { volume: 0.15, frequency: 0.08 },
672
- startAbove: 2e-3,
673
- sources: [
674
- "jogo:L62116-62120 rotor: noise through a 300 Hz lowpass, blade beat as an 11 Hz LFO of 0.5 on a 0.5 gain stage",
675
- "jogo:L70426 level min(0.5, 30 / (distance + 10))",
676
- "temporary home until the vehicles package (Q12)"
677
- ]
949
+ var GAITS = {
950
+ walk: { vol: 1, bright: 1, toe: 0.075, short: 1 },
951
+ run: { vol: 1.35, bright: 1.25, toe: 0.035, short: 0.75 }
678
952
  };
679
-
680
- // src/library/siren.json
681
- var siren_default = {
682
- id: "siren",
683
- bus: "world",
684
- order: "siren",
685
- duration: 9,
686
- tail: 0.2,
687
- layers: [
688
- {
689
- wet: 1.5,
690
- source: { kind: "osc", wave: "sine", frequency: { set: 850 } },
691
- modulators: [{ target: "frequency", rate: 0.18, depth: 280 }],
692
- filters: { mode: "serial", bank: [{ type: "lowpass", frequency: { set: 1400 } }] },
693
- envelope: [[0, 1e-4, "set", "fixed"], [2, 0.035, "exp"], [6, 0.035, "set"], [9, 1e-4, "exp", "fixed"]]
694
- }
953
+ var grainLayers = (g, take, start, scale) => Array.from(
954
+ { length: g.count },
955
+ (_, i) => sceneNoise({ type: "bandpass", f: [g.f * take.f * 0.85, g.f * take.f * 1.15], q: g.q, d: [8e-3, 0.02], vol: g.vol * scale * take.v, delay: start + (i + 0.5) / g.count * g.spread * take.t })
956
+ );
957
+ var ringLayers = (rings, take, scale, at = 0) => rings.map((r) => sceneTone({ f: r.f * take.f, d: r.d * take.t, vol: r.vol * scale * take.v, delay: at }));
958
+ function footLayers(surface, take, gait, weight = 1) {
959
+ const s = SURFACES[surface];
960
+ const toe = gait.toe * take.t;
961
+ return [
962
+ sceneTone({ f: s.heel.f * take.f * weight ** -0.3, f2: s.heel.f * take.f * 0.6, d: s.heel.d * gait.short * take.t * weight ** 0.5, vol: s.heel.vol * gait.vol * take.v * weight ** 0.5 }),
963
+ sceneNoise({ type: "lowpass", f: 500 * gait.bright, d: 0.02 * take.t, vol: 0.18 * gait.vol * take.v * weight ** 0.5 }),
964
+ sceneNoise({ type: s.roll.type, f: [s.roll.f * take.f * gait.bright * 0.92, s.roll.f * take.f * gait.bright * 1.08], q: s.roll.q, d: s.roll.d * gait.short * take.t * weight ** 0.3, vol: s.roll.vol * gait.vol * take.v, delay: toe }),
965
+ ...s.grains ? grainLayers(s.grains, take, toe * 0.5, gait.vol * weight ** 0.5) : [],
966
+ ...s.ring ? ringLayers(s.ring, take, gait.vol * weight ** 0.5) : [],
967
+ ...s.splash ? [sceneNoise({ type: "bandpass", f: s.splash.f * take.f, f2: s.splash.f2 * take.f, q: 1.4, d: s.splash.d * take.t * weight ** 0.4, vol: s.splash.vol * gait.vol * take.v * weight ** 0.5 })] : []
968
+ ];
969
+ }
970
+ var quieter = (level, layers) => layers.map((layer) => {
971
+ const gain = layer.gain ?? 1;
972
+ if (typeof gain === "number") return { ...layer, gain: gain * level };
973
+ if (Array.isArray(gain)) return { ...layer, gain: [gain[0] * level, gain[1] * level] };
974
+ return layer;
975
+ });
976
+ var recipe = (id, layers, falloff, bus = "world") => ({ id, bus, pan: true, layers, falloff, sources: ["sdk"] });
977
+ var takeId = (id, index) => `${id}_${String(index + 1).padStart(2, "0")}`;
978
+ function takes(id, layersOf, falloff, rate = [0.96, 1.04], bus) {
979
+ const sounds = TAKES.map((take, index) => recipe(takeId(id, index), layersOf(take, index), falloff, bus));
980
+ return { sounds, set: { id, variants: sounds.map((sound) => sound.id), rate } };
981
+ }
982
+ var footstep = (surface, gait) => takes(footstepSoundId(surface, gait), (take) => footLayers(surface, take, GAITS[gait]), FOOTSTEP_FALLOFF);
983
+ var LANDINGS = { light: { weight: 1.4, cloth: 0.12 }, heavy: { weight: 2.4, cloth: 0.22 } };
984
+ var LANDING_LEVEL = 0.65;
985
+ var landing = (surface, landing2) => takes(
986
+ `land_${surface}_${landing2}`,
987
+ (take) => quieter(LANDING_LEVEL, [
988
+ // both feet, a hair apart, then the knees taking the weight (a low body thump) and the clothes settling
989
+ ...footLayers(surface, take, GAITS.run, LANDINGS[landing2].weight),
990
+ ...footLayers(surface, { ...take, v: take.v * 0.6 }, GAITS.run, LANDINGS[landing2].weight * 0.6).map((layer) => ({ ...layer, at: (typeof layer.at === "number" ? layer.at : 0) + 0.018 * take.t })),
991
+ sceneTone({ f: 60 * take.f, f2: 38, d: 0.14 * LANDINGS[landing2].weight * take.t, vol: 0.22 * LANDINGS[landing2].weight ** 0.7 * take.v, delay: 0.02 }),
992
+ sceneNoise({ type: "bandpass", f: [1800, 2600], q: 0.8, d: 0.18, vol: LANDINGS[landing2].cloth * take.v, delay: 0.04 })
993
+ ]),
994
+ FOOTSTEP_FALLOFF
995
+ );
996
+ var whoosh = (blow, from, to, d, vol, q = 1.6) => (take) => [
997
+ // the air: a band sweeping up as the limb speeds up; it peaks `SWING_LEAD_SECONDS` in, the moment before the contact, then dies away
998
+ sceneNoise({ type: "bandpass", f: from * take.f, f2: to * take.f, q, a: SWING_LEAD_SECONDS[blow], d: d * take.t, vol: vol * take.v }),
999
+ sceneNoise({ type: "lowpass", f: 600 * take.f, a: SWING_LEAD_SECONDS[blow], d: d * take.t * 0.8, vol: vol * 0.35 * take.v })
1000
+ ];
1001
+ var fleshHit = (o) => (take) => [
1002
+ sceneNoise({ type: "bandpass", f: o.slapF * take.f, q: 1.2, d: 0.03 * take.t, vol: o.slap * take.v }),
1003
+ sceneNoise({ type: "highpass", f: 3500 * take.f, d: 0.012, vol: o.slap * 0.4 * take.v }),
1004
+ sceneTone({ f: o.thudF * take.f, f2: o.thudF * 0.5, d: o.thudD * take.t, vol: o.thud * take.v }),
1005
+ sceneNoise({ type: "lowpass", f: 600 * take.f, d: o.thudD * 1.2 * take.t, vol: o.thud * 0.5 * take.v }),
1006
+ ...o.crack ? [sceneNoise({ type: "highpass", f: 2500, d: 0.015, vol: o.crack * take.v, delay: 6e-3 }), sceneTone({ wave: "square", f: 900 * take.f, f2: 300, d: 0.02, vol: o.crack * 0.15 * take.v, delay: 6e-3 })] : [],
1007
+ ...o.wet ? [sceneNoise({ type: "bandpass", f: 1400 * take.f, f2: 500, q: 2.5, d: 0.12 * take.t, vol: o.wet * take.v, delay: 0.01 })] : []
1008
+ ];
1009
+ var knock = (o) => (take) => [
1010
+ sceneNoise({ type: "bandpass", f: o.clickF * take.f, q: 1.5, d: 0.018, vol: o.click * take.v }),
1011
+ ...o.tones.map(([f, d, vol]) => sceneTone({ f: f * take.f, d: d * take.t, vol: vol * take.v }))
1012
+ ];
1013
+ var voice = (o) => (take) => [
1014
+ sceneVoice({ f0: o.f0 * take.f, f1: o.f1 * take.f, d: o.d * take.t, fA: o.fA * take.f, fB: o.fB * take.f, noise: o.noise, vol: o.vol * take.v })
1015
+ ];
1016
+ var BODY = {
1017
+ jump: (take) => [
1018
+ sceneNoise({ type: "bandpass", f: 900 * take.f, f2: 1700 * take.f, q: 1, a: 0.03, d: 0.12, vol: 0.18 * take.v }),
1019
+ sceneNoise({ type: "bandpass", f: 2200 * take.f, q: 0.8, d: 0.04, vol: 0.12 * take.v }),
1020
+ sceneTone({ f: 85 * take.f, f2: 60, d: 0.04, vol: 0.2 * take.v })
1021
+ ],
1022
+ cloth_rustle: (take) => [
1023
+ { ...sceneNoise({ type: "bandpass", f: 2400 * take.f, q: 0.8, a: 0.06, d: 0.22 * take.t, vol: 0.12 * take.v }), modulators: [{ target: "gain", wave: "triangle", rate: [9, 14], depth: 0.5 }] }
1024
+ ],
1025
+ body_fall: (take) => [
1026
+ sceneTone({ f: 58 * take.f, f2: 35, d: 0.28 * take.t, vol: 0.9 * take.v }),
1027
+ sceneNoise({ type: "lowpass", f: 480 * take.f, d: 0.3 * take.t, vol: 0.55 * take.v }),
1028
+ sceneNoise({ type: "bandpass", f: 1300 * take.f, q: 1, d: 0.05, vol: 0.3 * take.v }),
1029
+ // the limbs a moment later, and the clothes
1030
+ sceneTone({ f: 75 * take.f, f2: 45, d: 0.12, vol: 0.4 * take.v, delay: 0.13 * take.t }),
1031
+ sceneNoise({ type: "bandpass", f: 2200, q: 0.8, d: 0.2, vol: 0.12 * take.v, delay: 0.05 })
1032
+ ],
1033
+ fall_damage: (take) => [
1034
+ ...BODY.body_fall(take),
1035
+ sceneNoise({ type: "highpass", f: 2800, d: 0.02, vol: 0.35 * take.v, delay: 0.01 }),
1036
+ ...voice({ f0: 170, f1: 110, d: 0.32, fA: 650, fB: 1150, noise: 0.25, vol: 0.32 })(take).map((layer) => ({ ...layer, at: 0.08 }))
1037
+ ],
1038
+ player_hurt: voice({ f0: 150, f1: 105, d: 0.26, fA: 620, fB: 1100, noise: 0.3, vol: 0.35 }),
1039
+ player_breath_run: (take) => [
1040
+ sceneNoise({ type: "bandpass", f: 1200 * take.f, q: 1, a: 0.08, d: 0.22 * take.t, vol: 0.25 * take.v }),
1041
+ sceneNoise({ type: "bandpass", f: 900 * take.f, q: 1, a: 0.06, d: 0.26 * take.t, vol: 0.3 * take.v, delay: 0.3 * take.t })
1042
+ ],
1043
+ player_death: voice({ f0: 135, f1: 68, d: 1, fA: 560, fB: 980, noise: 0.35, vol: 0.4 }),
1044
+ bite: (take) => [
1045
+ sceneNoise({ type: "highpass", f: 2600, d: 0.015, vol: 0.4 * take.v }),
1046
+ sceneNoise({ type: "bandpass", f: 1600 * take.f, f2: 450, q: 2.2, d: 0.16 * take.t, vol: 0.55 * take.v, delay: 0.01 }),
1047
+ sceneNoise({ type: "bandpass", f: 3200 * take.f, f2: 1800, q: 1.2, d: 0.22 * take.t, vol: 0.25 * take.v, delay: 0.09 }),
1048
+ sceneTone({ f: 120 * take.f, f2: 70, d: 0.06, vol: 0.3 * take.v })
695
1049
  ],
696
- falloff: { model: "none" },
697
- sources: ["cena:L1369 siren: 850 Hz sine swept \xB1280 Hz at 0.18 Hz, 1400 Hz lowpass, 0.035 for 9 s, reverb send 1.5", "temporary home until the vehicles package (Q12)"]
1050
+ grab: (take) => [
1051
+ sceneNoise({ type: "bandpass", f: 1900 * take.f, q: 0.9, a: 4e-3, d: 0.13 * take.t, vol: 0.32 * take.v }),
1052
+ sceneTone({ f: 95 * take.f, f2: 60, d: 0.07, vol: 0.3 * take.v }),
1053
+ sceneNoise({ type: "lowpass", f: 700, d: 0.08, vol: 0.2 * take.v })
1054
+ ],
1055
+ punch_swing: whoosh("punch", 450, 1500, 0.16, 0.9),
1056
+ punch_hit_body: fleshHit({ slap: 0.55, slapF: 1500, thud: 0.6, thudF: 115, thudD: 0.09 }),
1057
+ punch_hit_face: fleshHit({ slap: 0.75, slapF: 2300, thud: 0.45, thudF: 150, thudD: 0.07, crack: 0.25 }),
1058
+ punch_hit_object: knock({ clickF: 1800, click: 0.3, tones: [[210, 0.04, 0.25]] }),
1059
+ kick_swing: whoosh("kick", 280, 950, 0.22, 1, 1.3),
1060
+ kick_hit: fleshHit({ slap: 0.45, slapF: 1100, thud: 0.85, thudF: 82, thudD: 0.14 }),
1061
+ kick_hit_object: knock({ clickF: 1e3, click: 0.3, tones: [[92, 0.08, 0.5]] }),
1062
+ shove_two_hands: (take) => [
1063
+ sceneNoise({ type: "bandpass", f: 950 * take.f, q: 0.9, a: 0.01, d: 0.13 * take.t, vol: 0.38 * take.v }),
1064
+ sceneTone({ f: 100 * take.f, f2: 60, d: 0.1 * take.t, vol: 0.45 * take.v }),
1065
+ sceneNoise({ type: "bandpass", f: 2300, q: 0.8, d: 0.16, vol: 0.12 * take.v, delay: 0.03 })
1066
+ ],
1067
+ knife_swing: whoosh("blade", 1900, 4600, 0.12, 1.1, 2.2),
1068
+ knife_stab: fleshHit({ slap: 0.2, slapF: 1200, thud: 0.4, thudF: 160, thudD: 0.06, wet: 0.5 }),
1069
+ knife_slash: (take) => [
1070
+ sceneNoise({ type: "highpass", f: 3200 * take.f, f2: 1800, d: 0.13 * take.t, vol: 0.35 * take.v }),
1071
+ sceneNoise({ type: "bandpass", f: 1300 * take.f, f2: 600, q: 2.5, d: 0.12 * take.t, vol: 0.35 * take.v, delay: 0.02 })
1072
+ ],
1073
+ knife_hit_object: knock({ clickF: 3200, click: 0.25, tones: [[2800, 0.08, 0.07], [4150, 0.06, 0.05]] }),
1074
+ blunt_swing: whoosh("blunt", 220, 760, 0.28, 1.1, 1.5),
1075
+ blunt_hit: fleshHit({ slap: 0.35, slapF: 900, thud: 1, thudF: 70, thudD: 0.18, crack: 0.3 }),
1076
+ blunt_hit_object: knock({ clickF: 1400, click: 0.35, tones: [[300, 0.12, 0.25], [760, 0.08, 0.12]] }),
1077
+ axe_swing: whoosh("chop", 190, 620, 0.3, 1.2, 1.4),
1078
+ axe_chop: fleshHit({ slap: 0.3, slapF: 1400, thud: 0.75, thudF: 140, thudD: 0.1, crack: 0.35, wet: 0.45 }),
1079
+ axe_hit_object: knock({ clickF: 2200, click: 0.4, tones: [[1500, 0.15, 0.1], [2300, 0.1, 0.06], [140, 0.1, 0.35]] })
698
1080
  };
699
-
700
- // src/library/index.ts
701
- var LIBRARY_SOUNDS = [horn_default, radio_static_default, siren_default];
702
- var LIBRARY_LOOPS = [engine_saw_default, rotor_blades_default, crowd_rumble_default];
703
- var LIBRARY_BANK = { id: "library", sounds: LIBRARY_SOUNDS, loops: LIBRARY_LOOPS };
704
-
705
- // src/webaudio/noise.ts
706
- function fillNoise(random, length) {
707
- const samples = new Float32Array(length);
708
- for (let index = 0; index < length; index++) samples[index] = random() * 2 - 1;
709
- return samples;
710
- }
711
- function fillImpulse(random, options) {
712
- const size = Math.floor(options.length);
713
- return Array.from({ length: options.channels }, () => {
714
- const samples = new Float32Array(size);
715
- for (let index = 0; index < options.length; index++) {
716
- const value = (random() * 2 - 1) * Math.exp(options.decay * Math.log(1 - index / options.length));
717
- if (index < size) samples[index] = value;
718
- }
719
- return samples;
720
- });
721
- }
722
- function bufferOf(context, channels, requestedLength) {
723
- const buffer = context.createBuffer(channels.length, requestedLength, context.sampleRate);
724
- channels.forEach((samples, channel) => buffer.getChannelData(channel).set(samples));
725
- return buffer;
726
- }
727
-
728
- // src/webaudio/chain.ts
729
- function buildChain(context, profile, random) {
730
- let compressor;
731
- if (profile.compressor) {
732
- compressor = context.createDynamicsCompressor();
733
- compressor.threshold.value = profile.compressor.threshold;
734
- compressor.ratio.value = profile.compressor.ratio;
735
- if (profile.compressor.knee !== void 0) compressor.knee.value = profile.compressor.knee;
736
- if (profile.compressor.attack !== void 0) compressor.attack.value = profile.compressor.attack;
737
- if (profile.compressor.release !== void 0) compressor.release.value = profile.compressor.release;
738
- compressor.connect(context.destination);
739
- }
740
- const master = context.createGain();
741
- master.gain.value = profile.master;
742
- master.connect(compressor ?? context.destination);
743
- if (!profile.reverb) {
744
- return {
745
- master,
746
- disconnect: () => {
747
- master.disconnect();
748
- compressor?.disconnect();
749
- }
750
- };
751
- }
752
- const convolver = context.createConvolver();
753
- const length = context.sampleRate * profile.reverb.seconds;
754
- convolver.buffer = bufferOf(context, fillImpulse(random, { channels: 2, length, decay: profile.reverb.decay }), length);
755
- const wet = context.createGain();
756
- wet.gain.value = profile.reverb.wet;
757
- wet.connect(convolver);
758
- convolver.connect(master);
759
- return {
760
- master,
761
- wet,
762
- disconnect: () => {
763
- wet.disconnect();
764
- convolver.disconnect();
765
- master.disconnect();
766
- compressor?.disconnect();
767
- }
768
- };
769
- }
770
-
771
- // src/webaudio/context.ts
772
- function globalContext() {
773
- const scope = globalThis;
774
- const Constructor = scope.AudioContext ?? scope.webkitAudioContext;
775
- return Constructor ? new Constructor() : null;
776
- }
777
- function unlockContext(context) {
778
- if (context.state === "suspended") void context.resume();
779
- }
780
-
781
- // src/webaudio/nodes.ts
782
- function assign(param, automation, time) {
783
- if (automation.value !== void 0) param.value = automation.value;
784
- if (automation.from !== void 0) param.setValueAtTime(automation.from, time);
785
- }
786
- function ramp(param, curve, value, at) {
787
- if (curve === "set") param.setValueAtTime(value, at);
788
- else if (curve === "exp") param.exponentialRampToValueAtTime(value, at);
789
- else param.linearRampToValueAtTime(value, at);
790
- }
791
- function rampTo(param, automation, time) {
792
- if (automation.to !== void 0 && automation.at !== void 0) ramp(param, automation.curve ?? "linear", automation.to, time + automation.at);
793
- }
794
- function applyEnvelope(param, points, time) {
795
- for (const point of points) ramp(param, point.curve, point.value, time + point.time);
796
- }
797
- function noiseSource(target, loop) {
798
- const source = target.context.createBufferSource();
799
- source.buffer = target.noise();
800
- if (loop) source.loop = true;
801
- return source;
802
- }
803
- function filterNode(context, filter, time) {
804
- const node = context.createBiquadFilter();
805
- node.type = filter.type;
806
- assign(node.frequency, filter.frequency, time);
807
- if (filter.q !== void 0) node.Q.value = filter.q;
808
- if (filter.gain !== void 0) node.gain.value = filter.gain;
809
- return node;
810
- }
811
- function gainNode(context, value) {
812
- const node = context.createGain();
813
- node.gain.value = value;
814
- return node;
815
- }
816
- function voiceOf(sources) {
817
- return {
818
- sources,
819
- stop() {
820
- for (const source of sources) {
821
- try {
822
- source.stop();
823
- } catch {
824
- }
825
- }
826
- }
827
- };
828
- }
829
-
830
- // src/webaudio/realize-loop.ts
831
- var fixed = (range) => typeof range === "number" ? range : 0;
832
- var fixedFrequency = (automation) => fixed("set" in automation ? automation.set : automation.from);
833
- function sourceOf(recipe, target) {
834
- if (recipe.source.kind === "noise") return { source: noiseSource(target, true) };
835
- const oscillator = target.context.createOscillator();
836
- oscillator.type = recipe.source.wave;
837
- if (recipe.source.frequency) oscillator.frequency.value = fixedFrequency(recipe.source.frequency);
838
- return { source: oscillator, frequency: oscillator.frequency };
839
- }
840
- function stopAll(sources) {
841
- return () => {
842
- for (const source of sources) {
843
- try {
844
- source.stop();
845
- } catch {
846
- }
847
- }
848
- };
849
- }
850
- function realizeGameLoop(recipe, target) {
851
- const { context } = target;
852
- const gain = context.createGain();
853
- const filters = (recipe.filters?.bank ?? []).map(() => context.createBiquadFilter());
854
- gain.gain.value = 0;
855
- const last = filters.reduce((previous, filter) => previous ? previous.connect(filter) : filter, void 0);
856
- last?.connect(gain);
857
- gain.connect(target.output);
858
- const { source, frequency } = sourceOf(recipe, target);
859
- recipe.filters?.bank.forEach((spec, index) => {
860
- const filter = filters[index];
861
- filter.type = spec.type;
862
- filter.frequency.value = fixedFrequency(spec.frequency);
863
- if (spec.q !== void 0) filter.Q.value = fixed(spec.q);
864
- });
865
- const sources = [source];
866
- for (const modulator of recipe.modulators ?? []) {
867
- const lfo = context.createOscillator();
868
- const depth = context.createGain();
869
- const stage = context.createGain();
870
- if (modulator.wave) lfo.type = modulator.wave;
871
- lfo.frequency.value = fixed(modulator.rate);
872
- depth.gain.value = fixed(modulator.depth);
873
- stage.gain.value = modulator.base ?? 0;
874
- lfo.connect(depth);
875
- depth.connect(stage.gain);
876
- last?.disconnect();
877
- last?.connect(stage);
878
- stage.connect(gain);
879
- lfo.start();
880
- sources.push(lfo);
881
- }
882
- source.connect(filters[0] ?? gain);
883
- source.start();
884
- return { gain, source, ...frequency ? { frequency } : {}, stop: stopAll(sources) };
885
- }
886
- function realizeChainLoop(recipe, target, volume) {
887
- const { context } = target;
888
- const { source, frequency } = sourceOf(recipe, target);
889
- const filters = (recipe.filters?.bank ?? []).map(
890
- (spec) => filterNode(context, { type: spec.type, frequency: { value: fixedFrequency(spec.frequency) }, ...spec.q === void 0 ? {} : { q: fixed(spec.q) } }, target.time)
891
- );
892
- const gain = gainNode(context, volume);
893
- const lfos = (recipe.modulators ?? []).map((modulator) => {
894
- const lfo = context.createOscillator();
895
- if (modulator.wave) lfo.type = modulator.wave;
896
- lfo.frequency.value = fixed(modulator.rate);
897
- const depth = gainNode(context, fixed(modulator.depth));
898
- lfo.connect(depth);
899
- depth.connect(gain.gain);
900
- return lfo;
901
- });
902
- let tail = source;
903
- for (const filter of filters) tail = tail.connect(filter);
904
- tail.connect(gain);
905
- gain.connect(target.output);
906
- source.start();
907
- for (const lfo of lfos) lfo.start();
908
- return { gain, source, ...frequency ? { frequency } : {}, stop: stopAll([source, ...lfos]) };
909
- }
910
-
911
- // src/webaudio/engine-loop.ts
912
- var INERT = { set() {
913
- }, stop() {
914
- } };
915
- function createLoopHandle(recipe, host, volume) {
916
- if (!recipe) return INERT;
917
- const loopRecipe = recipe;
918
- const isChain = loopRecipe.order === "chain_loop";
919
- const opening = volume ?? loopRecipe.volume ?? 0;
920
- const smoothing = loopRecipe.smoothing ?? LOOP_SMOOTHING;
921
- let state = createLoopState(loopRecipe);
922
- let nodes;
923
- const entry = {
924
- get created() {
925
- return nodes !== void 0;
926
- },
927
- rewire() {
928
- nodes?.gain.disconnect();
929
- nodes?.gain.connect(host.output(loopRecipe.bus));
930
- },
931
- stop() {
932
- nodes?.stop();
933
- nodes?.gain.disconnect();
934
- nodes = void 0;
935
- state = createLoopState(loopRecipe);
936
- host.unregister(entry);
937
- }
938
- };
939
- const create = (context, startVolume) => {
940
- if (loopRecipe.source.kind === "noise") host.prepareNoise();
941
- const target = { context, output: host.output(loopRecipe.bus), noise: host.noise, time: context.currentTime };
942
- const made = isChain ? realizeChainLoop(loopRecipe, target, startVolume) : realizeGameLoop(loopRecipe, target);
943
- host.register(entry);
944
- return made;
945
- };
946
- const open = () => {
947
- const context = host.ready();
948
- if (!context) return;
949
- nodes = create(context, opening);
950
- state = createLoopState({ ...loopRecipe, volume: opening }, true);
951
- };
952
- if (isChain) open();
953
- return {
954
- set(next) {
955
- if (isChain && !nodes) open();
956
- const context = host.ready();
957
- if (!context) return;
958
- const action = state.set(next);
959
- if (!action) return;
960
- nodes ?? (nodes = create(context, 0));
961
- nodes.gain.gain.setTargetAtTime(action.volume, context.currentTime, smoothing.volume);
962
- if (action.frequency !== void 0 && nodes.frequency) nodes.frequency.setTargetAtTime(action.frequency, context.currentTime, smoothing.frequency);
963
- },
964
- stop: entry.stop
965
- };
966
- }
967
-
968
- // src/webaudio/engine-noise.ts
969
- function createNoiseStore(random) {
970
- const store = {
971
- random,
972
- reset() {
973
- store.samples = void 0;
974
- store.buffer = void 0;
975
- }
976
- };
977
- return store;
978
- }
979
- function prepareNoise(store, context, seconds) {
980
- store.samples ?? (store.samples = fillNoise(store.random, Math.floor(context.sampleRate * seconds)));
981
- return store.samples;
982
- }
983
- function noiseBuffer(store, context, seconds) {
984
- const samples = prepareNoise(store, context, seconds);
985
- store.buffer ?? (store.buffer = bufferOf(context, [samples], context.sampleRate * seconds));
986
- return store.buffer;
987
- }
988
-
989
- // src/webaudio/engine-queue.ts
990
- var nowMs = () => typeof performance === "undefined" ? Date.now() : performance.now();
991
- function scheduleTask(task) {
992
- if (typeof MessageChannel === "undefined") {
993
- setTimeout(task, 0);
994
- return;
995
- }
996
- const channel = new MessageChannel();
997
- channel.port1.onmessage = () => {
998
- channel.port1.close();
999
- task();
1000
- };
1001
- channel.port2.postMessage(0);
1002
- }
1003
- function createStartQueue(options = {}) {
1004
- const budgetMs = options.budgetMs ?? 2;
1005
- const maxLatencyMs = options.maxLatencyMs ?? 250;
1006
- let jobs = [];
1007
- let scheduled = false;
1008
- const drain = () => {
1009
- scheduled = false;
1010
- const began = nowMs();
1011
- while (jobs.length > 0) {
1012
- const job = jobs.shift();
1013
- if (nowMs() - job.queuedAt > maxLatencyMs) job.drop();
1014
- else job.run();
1015
- if (nowMs() - began >= budgetMs) break;
1016
- }
1017
- if (jobs.length > 0) schedule();
1018
- };
1019
- const schedule = () => {
1020
- if (scheduled) return;
1021
- scheduled = true;
1022
- scheduleTask(drain);
1023
- };
1024
- return {
1025
- push(job) {
1026
- jobs.push({ ...job, queuedAt: nowMs() });
1027
- schedule();
1028
- },
1029
- clear() {
1030
- for (const job of jobs) job.drop();
1031
- jobs = [];
1032
- },
1033
- get size() {
1034
- return jobs.length;
1035
- }
1036
- };
1037
- }
1038
-
1039
- // src/webaudio/realize-game.ts
1040
- var end = (layer, start) => start + layer.duration + layer.tail;
1041
- var firstFilter = (layer) => layer.filters?.bank[0];
1042
- var offsetOf = (layer) => layer.source.kind === "noise" ? layer.source.offset : 0;
1043
- function setFilter(node, filter, time) {
1044
- if (!filter) return;
1045
- node.type = filter.type;
1046
- assign(node.frequency, filter.frequency, time);
1047
- if (filter.q !== void 0) node.Q.value = filter.q;
1048
- }
1049
- function realizeBurst(plan, target) {
1050
- const { context } = target;
1051
- const layer = plan.layers[0];
1052
- const time = target.time + layer.at;
1053
- const gain = context.createGain();
1054
- gain.connect(target.output);
1055
- const source = noiseSource(target, layer.source.kind === "noise" && layer.source.loop);
1056
- const filter = context.createBiquadFilter();
1057
- source.connect(filter);
1058
- filter.connect(gain);
1059
- setFilter(filter, firstFilter(layer), time);
1060
- applyEnvelope(gain.gain, layer.envelope, time);
1061
- source.start(time, offsetOf(layer));
1062
- source.stop(end(layer, time));
1063
- return voiceOf([source]);
1064
- }
1065
- function realizeScream(plan, target) {
1066
- const { context } = target;
1067
- const layer = plan.layers[0];
1068
- const time = target.time + layer.at;
1069
- const source = noiseSource(target, layer.source.kind === "noise" && layer.source.loop);
1070
- const gain = context.createGain();
1071
- gain.connect(target.output);
1072
- for (const band of layer.filters?.bank ?? []) {
1073
- const filter = context.createBiquadFilter();
1074
- filter.type = band.type;
1075
- if (band.q !== void 0) filter.Q.value = band.q;
1076
- assign(filter.frequency, band.frequency, time);
1077
- rampTo(filter.frequency, band.frequency, time);
1078
- const level = context.createGain();
1079
- level.gain.value = band.level ?? 1;
1080
- source.connect(filter);
1081
- filter.connect(level);
1082
- level.connect(gain);
1083
- }
1084
- const sources = [source];
1085
- const lfos = layer.modulators.map((modulator) => {
1086
- const lfo = context.createOscillator();
1087
- const depth = context.createGain();
1088
- if (modulator.wave) lfo.type = modulator.wave;
1089
- lfo.frequency.value = modulator.rate;
1090
- depth.gain.value = modulator.depth;
1091
- lfo.connect(depth);
1092
- depth.connect(gain.gain);
1093
- return lfo;
1094
- });
1095
- applyEnvelope(gain.gain, layer.envelope, time);
1096
- source.start(time, offsetOf(layer));
1097
- source.stop(end(layer, time));
1098
- for (const lfo of lfos) {
1099
- lfo.start(time);
1100
- lfo.stop(end(layer, time));
1101
- sources.push(lfo);
1102
- }
1103
- return voiceOf(sources);
1104
- }
1105
- function realizeGroan(plan, target) {
1106
- const { context } = target;
1107
- const layer = plan.layers[0];
1108
- const time = target.time + layer.at;
1109
- const oscillator = context.createOscillator();
1110
- const gain = context.createGain();
1111
- const filter = context.createBiquadFilter();
1112
- const band = firstFilter(layer);
1113
- if (layer.source.kind === "osc") oscillator.type = layer.source.wave;
1114
- if (band) {
1115
- filter.type = band.type;
1116
- if (band.q !== void 0) filter.Q.value = band.q;
1117
- }
1118
- if (layer.source.kind === "osc") {
1119
- assign(oscillator.frequency, layer.source.frequency, time);
1120
- rampTo(oscillator.frequency, layer.source.frequency, time);
1121
- }
1122
- if (band) assign(filter.frequency, band.frequency, time);
1123
- applyEnvelope(gain.gain, layer.envelope, time);
1124
- oscillator.connect(filter);
1125
- filter.connect(gain);
1126
- gain.connect(target.output);
1127
- oscillator.start(time);
1128
- oscillator.stop(end(layer, time));
1129
- return voiceOf([oscillator]);
1130
- }
1131
- function realizeBoom(plan, target) {
1132
- const { context } = target;
1133
- const layer = plan.layers[0];
1134
- const time = target.time + layer.at;
1135
- const oscillator = context.createOscillator();
1136
- const gain = context.createGain();
1137
- if (layer.source.kind === "osc") {
1138
- oscillator.type = layer.source.wave;
1139
- assign(oscillator.frequency, layer.source.frequency, time);
1140
- rampTo(oscillator.frequency, layer.source.frequency, time);
1141
- }
1142
- applyEnvelope(gain.gain, layer.envelope, time);
1143
- oscillator.connect(gain);
1144
- gain.connect(target.output);
1145
- oscillator.start(time);
1146
- oscillator.stop(end(layer, time));
1147
- return voiceOf([oscillator]);
1148
- }
1149
- function realizeStatic(plan, target) {
1150
- const { context } = target;
1151
- const layer = plan.layers[0];
1152
- const time = target.time + layer.at;
1153
- const gain = context.createGain();
1154
- const source = context.createBufferSource();
1155
- const filter = context.createBiquadFilter();
1156
- source.buffer = target.noise();
1157
- setFilter(filter, firstFilter(layer), time);
1158
- applyEnvelope(gain.gain, layer.envelope, time);
1159
- source.connect(filter);
1160
- filter.connect(gain);
1161
- gain.connect(target.output);
1162
- source.start(time, offsetOf(layer));
1163
- source.stop(end(layer, time));
1164
- return voiceOf([source]);
1165
- }
1166
- function realizeChord(plan, target) {
1167
- const { context } = target;
1168
- const layers = plan.layers;
1169
- const oscillators = layers.map(() => context.createOscillator());
1170
- const gain = context.createGain();
1171
- for (let index = layers.length - 1; index >= 0; index--) {
1172
- const source = layers[index].source;
1173
- if (source.kind === "osc") oscillators[index].type = source.wave;
1174
- }
1175
- layers.forEach((layer, index) => {
1176
- if (layer.source.kind === "osc") assign(oscillators[index].frequency, layer.source.frequency, target.time + layer.at);
1177
- });
1178
- applyEnvelope(gain.gain, layers[0].envelope, target.time + layers[0].at);
1179
- for (const oscillator of oscillators) oscillator.connect(gain);
1180
- gain.connect(target.output);
1181
- layers.forEach((layer, index) => oscillators[index].start(target.time + layer.at));
1182
- layers.forEach((layer, index) => oscillators[index].stop(end(layer, target.time + layer.at)));
1183
- return voiceOf(oscillators);
1184
- }
1185
- function realizeCalls(plan, target) {
1186
- const { context } = target;
1187
- const gain = context.createGain();
1188
- const filter = context.createBiquadFilter();
1189
- if (plan.silent) return voiceOf([]);
1190
- const band = firstFilter(plan.layers[0]);
1191
- if (band) filter.type = band.type;
1192
- filter.connect(gain);
1193
- gain.connect(target.output);
1194
- const oscillators = plan.layers.map((layer) => {
1195
- const time = target.time + layer.at;
1196
- const oscillator = context.createOscillator();
1197
- if (layer.source.kind === "osc") {
1198
- oscillator.type = layer.source.wave;
1199
- assign(oscillator.frequency, layer.source.frequency, time);
1200
- rampTo(oscillator.frequency, layer.source.frequency, time);
1201
- }
1202
- if (band) {
1203
- assign(filter.frequency, band.frequency, time);
1204
- if (band.q !== void 0) filter.Q.value = band.q;
1205
- }
1206
- const envelope2 = context.createGain();
1207
- applyEnvelope(envelope2.gain, layer.envelope, time);
1208
- oscillator.connect(envelope2);
1209
- envelope2.connect(filter);
1210
- oscillator.start(time);
1211
- oscillator.stop(end(layer, time));
1212
- return oscillator;
1213
- });
1214
- return voiceOf(oscillators);
1215
- }
1216
-
1217
- // src/webaudio/realize-layered.ts
1218
- var end2 = (layer, start) => start + layer.duration + layer.tail;
1219
- function outputStage(plan, layer, target) {
1220
- const { context } = target;
1221
- const level = gainNode(context, layer.level);
1222
- let node = level;
1223
- if (plan.pan !== void 0 && typeof context.createStereoPanner === "function") {
1224
- const panner = context.createStereoPanner();
1225
- panner.pan.value = plan.pan;
1226
- level.connect(panner);
1227
- node = panner;
1228
- }
1229
- node.connect(target.output);
1230
- if (layer.wet && target.wet) {
1231
- const send = gainNode(context, layer.wet);
1232
- node.connect(send);
1233
- send.connect(target.wet);
1234
- }
1235
- return level;
1236
- }
1237
- function realizeNoiseLayer(plan, layer, target) {
1238
- const { context } = target;
1239
- const time = target.time + layer.at;
1240
- const source = noiseSource(target, layer.source.kind === "noise" && layer.source.loop);
1241
- const filters = (layer.filters?.bank ?? []).map((filter) => {
1242
- const node = filterNode(context, filter, time);
1243
- rampTo(node.frequency, filter.frequency, time);
1244
- return node;
1245
- });
1246
- const envelope2 = context.createGain();
1247
- applyEnvelope(envelope2.gain, layer.envelope, time);
1248
- let tail = source;
1249
- for (const filter of filters) tail = tail.connect(filter);
1250
- tail.connect(envelope2);
1251
- envelope2.connect(outputStage(plan, layer, target));
1252
- source.start(time, layer.source.kind === "noise" ? layer.source.offset : 0);
1253
- source.stop(end2(layer, time));
1254
- return [source];
1255
- }
1256
- function realizeToneLayer(plan, layer, target) {
1257
- const { context } = target;
1258
- const time = target.time + layer.at;
1259
- const oscillator = context.createOscillator();
1260
- if (layer.source.kind === "osc") {
1261
- oscillator.type = layer.source.wave;
1262
- assign(oscillator.frequency, layer.source.frequency, time);
1263
- rampTo(oscillator.frequency, layer.source.frequency, time);
1264
- }
1265
- const envelope2 = context.createGain();
1266
- applyEnvelope(envelope2.gain, layer.envelope, time);
1267
- oscillator.connect(envelope2);
1268
- envelope2.connect(outputStage(plan, layer, target));
1269
- oscillator.start(time);
1270
- oscillator.stop(end2(layer, time));
1271
- return [oscillator];
1272
- }
1273
- function realizeVoiceLayer(plan, layer, target) {
1274
- const source = layer.source;
1275
- if (source.kind !== "formant_voice") return [];
1276
- const { context } = target;
1277
- const time = target.time + layer.at;
1278
- const oscillator = context.createOscillator();
1279
- oscillator.type = source.wave;
1280
- assign(oscillator.frequency, source.frequency, time);
1281
- rampTo(oscillator.frequency, source.frequency, time);
1282
- const vibrato = context.createOscillator();
1283
- vibrato.frequency.value = source.vibrato.rate;
1284
- const vibratoDepth = gainNode(context, source.vibrato.depth);
1285
- vibrato.connect(vibratoDepth);
1286
- vibratoDepth.connect(oscillator.frequency);
1287
- const formants = source.formants.map((formant) => filterNode(context, { type: "bandpass", frequency: { value: formant.frequency }, q: formant.q }, time));
1288
- const breath = noiseSource(target, true);
1289
- const breathBand = filterNode(context, { type: "bandpass", frequency: { value: source.breath.frequency }, q: source.breath.q }, time);
1290
- const breathLevel = gainNode(context, source.breath.gain);
1291
- const mix = gainNode(context, source.mix);
1292
- for (const formant of formants) oscillator.connect(formant);
1293
- breath.connect(breathBand);
1294
- breathBand.connect(breathLevel);
1295
- for (const formant of formants) formant.connect(mix);
1296
- breathLevel.connect(mix);
1297
- const envelope2 = context.createGain();
1298
- applyEnvelope(envelope2.gain, layer.envelope, time);
1299
- mix.connect(envelope2);
1300
- envelope2.connect(outputStage(plan, layer, target));
1301
- const stop = end2(layer, time);
1302
- oscillator.start(time);
1303
- vibrato.start(time);
1304
- breath.start(time, source.breath.offset);
1305
- oscillator.stop(stop);
1306
- vibrato.stop(stop);
1307
- breath.stop(stop);
1308
- return [oscillator, vibrato, breath];
1309
- }
1310
- function realizeLayered(plan, target) {
1311
- const sources = plan.layers.flatMap((layer) => {
1312
- if (layer.source.kind === "noise") return realizeNoiseLayer(plan, layer, target);
1313
- if (layer.source.kind === "osc") return realizeToneLayer(plan, layer, target);
1314
- return realizeVoiceLayer(plan, layer, target);
1315
- });
1316
- return voiceOf(sources);
1317
- }
1318
- function realizeSiren(plan, target) {
1319
- const { context } = target;
1320
- const layer = plan.layers[0];
1321
- const time = target.time + layer.at;
1322
- const oscillator = context.createOscillator();
1323
- if (layer.source.kind === "osc") {
1324
- oscillator.type = layer.source.wave;
1325
- assign(oscillator.frequency, layer.source.frequency, time);
1326
- rampTo(oscillator.frequency, layer.source.frequency, time);
1327
- }
1328
- const depths = layer.modulators.map((modulator) => {
1329
- const lfo = context.createOscillator();
1330
- if (modulator.wave) lfo.type = modulator.wave;
1331
- lfo.frequency.value = modulator.rate;
1332
- const depth = gainNode(context, modulator.depth);
1333
- lfo.connect(depth);
1334
- if (modulator.target === "frequency") depth.connect(oscillator.frequency);
1335
- return { lfo, depth, target: modulator.target };
1336
- });
1337
- const lfos = depths.map(({ lfo }) => lfo);
1338
- const envelope2 = context.createGain();
1339
- applyEnvelope(envelope2.gain, layer.envelope, time);
1340
- for (const { depth, target: modulated } of depths) if (modulated === "gain") depth.connect(envelope2.gain);
1341
- const filters = (layer.filters?.bank ?? []).map((filter) => filterNode(context, filter, time));
1342
- let tail = oscillator;
1343
- for (const filter of filters) tail = tail.connect(filter);
1344
- tail.connect(envelope2);
1345
- envelope2.connect(target.output);
1346
- if (layer.wet && target.wet) {
1347
- const send = gainNode(context, layer.wet);
1348
- envelope2.connect(send);
1349
- send.connect(target.wet);
1350
- }
1351
- const stop = end2(layer, time);
1352
- oscillator.start(time);
1353
- for (const lfo of lfos) lfo.start(time);
1354
- oscillator.stop(stop);
1355
- for (const lfo of lfos) lfo.stop(stop);
1356
- return voiceOf([oscillator, ...lfos]);
1357
- }
1358
-
1359
- // src/webaudio/realize-weapon.ts
1360
- function noiseLayer(layer, target, time) {
1361
- const { context } = target;
1362
- const source = noiseSource(target, layer.source.kind === "noise" && layer.source.loop);
1363
- const filters = (layer.filters?.bank ?? []).map((filter) => filterNode(context, filter, time));
1364
- const envelope2 = context.createGain();
1365
- applyEnvelope(envelope2.gain, layer.envelope, time);
1366
- let tail = source;
1367
- for (const filter of filters) tail = tail.connect(filter);
1368
- tail.connect(envelope2).connect(target.output);
1369
- source.start(time, layer.source.kind === "noise" ? layer.source.offset : 0);
1370
- source.stop(time + layer.duration + layer.tail);
1371
- return source;
1372
- }
1373
- function toneLayer(layer, target, time) {
1374
- const { context } = target;
1375
- const oscillator = context.createOscillator();
1376
- if (layer.source.kind === "osc") {
1377
- oscillator.type = layer.source.wave;
1378
- assign(oscillator.frequency, layer.source.frequency, time);
1379
- rampTo(oscillator.frequency, layer.source.frequency, time);
1380
- }
1381
- const envelope2 = context.createGain();
1382
- applyEnvelope(envelope2.gain, layer.envelope, time);
1383
- oscillator.connect(envelope2).connect(target.output);
1384
- oscillator.start(time);
1385
- oscillator.stop(time + layer.duration + layer.tail);
1386
- return oscillator;
1387
- }
1388
- function realizeWeapon(plan, target) {
1389
- const sources = plan.layers.map((layer) => {
1390
- const time = target.time + layer.at;
1391
- return layer.source.kind === "noise" ? noiseLayer(layer, target, time) : toneLayer(layer, target, time);
1392
- });
1393
- return voiceOf(sources);
1394
- }
1395
-
1396
- // src/webaudio/realize.ts
1397
- var BUILDERS = {
1398
- layered: realizeLayered,
1399
- burst: realizeBurst,
1400
- scream: realizeScream,
1401
- groan: realizeGroan,
1402
- boom: realizeBoom,
1403
- static: realizeStatic,
1404
- chord: realizeChord,
1405
- calls: realizeCalls,
1406
- siren: realizeSiren,
1407
- weapon: realizeWeapon
1081
+ var BODY_BUS = { player_hurt: "voices", player_death: "voices", player_breath_run: "voices", fall_damage: "voices" };
1082
+ var built = [
1083
+ ...SURFACE_IDS.flatMap((surface) => GAIT_IDS.map((gait) => footstep(surface, gait))),
1084
+ ...SURFACE_IDS.flatMap((surface) => LANDING_IDS.map((l) => landing(surface, l))),
1085
+ ...BODY_SOUND_IDS.map((id) => takes(id, BODY[id], BODY_FALLOFF, id.endsWith("_swing") ? [0.94, 1.06] : [0.96, 1.04], BODY_BUS[id]))
1086
+ ];
1087
+ var BODY_FOLEY_BANK = {
1088
+ id: "body_foley",
1089
+ sounds: built.flatMap((entry) => entry.sounds),
1090
+ sets: built.map((entry) => entry.set)
1408
1091
  };
1409
- function realize(plan, target) {
1410
- return BUILDERS[plan.order](plan, target);
1411
- }
1412
-
1413
- // src/webaudio/engine.ts
1414
- var usesNoise = (recipe) => recipe.layers.some((layer) => layer.source.kind !== "osc");
1415
- var planUsesNoise = (plan) => plan.layers.some((layer) => layer.source.kind !== "osc");
1416
- function createAudioEngine(options = {}) {
1417
- const seed = options.seed ?? 1;
1418
- const registry = createSoundRegistry(options.banks);
1419
- const voices = createVoiceManager({ ...options.groups ? { groups: options.groups } : {}, ...options.maxVoices === void 0 ? {} : { maxVoices: options.maxVoices } });
1420
- const engineRandom = createRng(seed);
1421
- const shared = createNoiseStore(engineRandom);
1422
- const busSettings = /* @__PURE__ */ new Map();
1423
- const busNodes = /* @__PURE__ */ new Map();
1424
- const meters = /* @__PURE__ */ new Map();
1425
- const active = /* @__PURE__ */ new Map();
1426
- const loops = /* @__PURE__ */ new Set();
1427
- const named = /* @__PURE__ */ new Map();
1428
- let mix = resolveMix(options.mix ?? DEFAULT_MIX, options.profiles);
1429
- let context = null;
1430
- let chain = null;
1431
- let listener = DEFAULT_LISTENER;
1432
- let lastTime = 0;
1433
- const outputFor = (bus) => busNodes.get(bus) ?? chain?.master;
1434
- const watched = /* @__PURE__ */ new Set();
1435
- const meterOf = (bus) => {
1436
- const existing = meters.get(bus);
1437
- if (existing) return existing;
1438
- const node = busNodes.get(bus);
1439
- if (!context || !node || typeof context.createAnalyser !== "function") return void 0;
1440
- const analyser = context.createAnalyser();
1441
- analyser.fftSize = 1024;
1442
- node.connect(analyser);
1443
- const made = { analyser, data: new Float32Array(analyser.fftSize) };
1444
- meters.set(bus, made);
1445
- return made;
1446
- };
1447
- const ensureBus = (bus) => {
1448
- if (!context || !chain || busNodes.has(bus)) return;
1449
- const node = context.createGain();
1450
- node.connect(chain.master);
1451
- busNodes.set(bus, node);
1452
- if (watched.has(bus)) meterOf(bus);
1453
- };
1454
- const ready = () => {
1455
- if (context) return context;
1456
- const created = (options.createContext ?? globalContext)();
1457
- if (!created) return null;
1458
- context = created;
1459
- chain = buildChain(created, mix, engineRandom);
1460
- if (mix.noise.create === "eager") noiseBuffer(shared, created, mix.noise.seconds);
1461
- for (const [bus, setting] of Object.entries(mix.buses ?? {})) {
1462
- busSettings.set(bus, { ...setting, ...busSettings.get(bus) });
1463
- }
1464
- for (const [bus, setting] of busSettings) {
1465
- ensureBus(bus);
1466
- busNodes.get(bus).gain.value = busGain(setting);
1467
- }
1468
- lastTime = created.currentTime;
1469
- return created;
1470
- };
1471
- const advance = () => {
1472
- if (!context) return;
1473
- const elapsed = context.currentTime - lastTime;
1474
- lastTime = context.currentTime;
1475
- if (elapsed > 0) for (const id of voices.advance(elapsed)) active.delete(id);
1476
- };
1477
- const inputFor = (recipe, playOptions, random) => ({
1478
- random,
1479
- listener,
1480
- noiseSeconds: mix.noise.seconds,
1481
- ...options.distance ? { distanceMode: options.distance } : {},
1482
- ...playOptions.volume === void 0 ? {} : { volume: playOptions.volume },
1483
- ...playOptions.distance === void 0 ? {} : { distance: playOptions.distance },
1484
- ...playOptions.position ? { position: playOptions.position } : {},
1485
- ...playOptions.params ? { params: playOptions.params } : {},
1486
- ...options.occlusion && playOptions.position && recipe.falloff?.model !== "none" ? { occlusion: options.occlusion(playOptions.position) } : {}
1487
- });
1488
- const startQueue = options.deferredStart ? createStartQueue(options.deferredStart) : null;
1489
- const build = (plan, store, delay) => {
1490
- const audio = context;
1491
- return realize(plan, {
1492
- context: audio,
1493
- output: outputFor(plan.bus),
1494
- ...chain?.wet ? { wet: chain.wet } : {},
1495
- noise: () => noiseBuffer(store, audio, mix.noise.seconds),
1496
- time: audio.currentTime + delay
1497
- });
1498
- };
1499
- const deferVoice = (plan, store, voiceId, delay) => {
1500
- let built = null;
1501
- let cancelled = false;
1502
- const pending = {
1503
- get sources() {
1504
- return built?.sources ?? [];
1505
- },
1506
- stop() {
1507
- cancelled = true;
1508
- built?.stop();
1509
- }
1510
- };
1511
- startQueue.push({
1512
- run() {
1513
- if (!cancelled && context) built = build(plan, store, delay);
1514
- },
1515
- drop() {
1516
- if (voiceId === void 0) return;
1517
- voices.release(voiceId);
1518
- active.delete(voiceId);
1519
- }
1520
- });
1521
- return pending;
1522
- };
1523
- const start = (plan, store, voiceId, delay = 0) => {
1524
- const realized = startQueue ? deferVoice(plan, store, voiceId, delay) : build(plan, store, delay);
1525
- if (voiceId === void 0) return null;
1526
- voices.setLength(voiceId, plan.length + delay);
1527
- active.set(voiceId, realized);
1528
- return {
1529
- id: voiceId,
1530
- plan,
1531
- stop() {
1532
- realized.stop();
1533
- voices.release(voiceId);
1534
- active.delete(voiceId);
1535
- }
1536
- };
1537
- };
1538
- const admit = (recipe, gain, distance) => {
1539
- const decision = voices.request({ ...recipe.group ? { group: recipe.group } : {}, priority: recipe.priority ?? busPriority(recipe.bus), gain, distance, length: 0 });
1540
- if (!decision.accepted) return null;
1541
- for (const id of decision.evicted) {
1542
- active.get(id)?.stop();
1543
- active.delete(id);
1544
- }
1545
- return decision.id;
1546
- };
1547
- const playWith = (id, playOptions, random, store) => {
1548
- const recipe = registry.sound(id);
1549
- if (!recipe || busSettings.get(recipe.bus)?.muted) return null;
1550
- const distance = playOptions.distance ?? (playOptions.position ? listenerDistance(listener, playOptions.position, options.distance) : 0);
1551
- const level = falloffGain(recipe.falloff, playOptions.volume ?? 1, distance);
1552
- const silent = isSilent(recipe.falloff, level);
1553
- if (silent && !recipe.keepSilent) return null;
1554
- const audio = ready();
1555
- if (!audio) return null;
1556
- unlockContext(audio);
1557
- advance();
1558
- const voiceId = silent ? void 0 : admit(recipe, level, distance);
1559
- if (voiceId === null) return null;
1560
- if (!silent && usesNoise(recipe)) prepareNoise(store, audio, mix.noise.seconds);
1561
- const plan = planSound(recipe, inputFor(recipe, playOptions, playOptions.seed === void 0 ? random : createRng(playOptions.seed)));
1562
- return plan ? start(plan, store, voiceId, playOptions.delay) : null;
1563
- };
1564
- const randomFor = (playOptions) => {
1565
- if (playOptions.channel === void 0) return engineRandom;
1566
- const existing = named.get(playOptions.channel);
1567
- if (existing) return existing;
1568
- const stream = streamFor(seed, playOptions.channel);
1569
- named.set(playOptions.channel, stream);
1570
- return stream;
1571
- };
1572
- const planWith = (id, playOptions, random) => {
1573
- const recipe = registry.sound(id);
1574
- return recipe ? planSound(recipe, inputFor(recipe, playOptions, random)) : null;
1575
- };
1576
- const loopHost = {
1577
- ready,
1578
- output: outputFor,
1579
- prepareNoise: () => context && prepareNoise(shared, context, mix.noise.seconds),
1580
- noise: () => noiseBuffer(shared, context, mix.noise.seconds),
1581
- register: (loop) => void loops.add(loop),
1582
- unregister: (loop) => void loops.delete(loop)
1583
- };
1584
- return {
1585
- registry,
1586
- register: (bank) => registry.register(bank),
1587
- plan: (id, playOptions = {}) => planWith(id, playOptions, createRng(playOptions.seed ?? seed)),
1588
- play: (id, playOptions = {}) => playWith(id, playOptions, randomFor(playOptions), shared),
1589
- playPlan(plan, playOptions = {}) {
1590
- const audio = ready();
1591
- if (!audio) return null;
1592
- advance();
1593
- const recipe = { id: plan.id, bus: plan.bus, layers: [], sources: [], priority: plan.priority, ...plan.group ? { group: plan.group } : {} };
1594
- const voiceId = plan.silent ? void 0 : admit(recipe, plan.level, plan.distance);
1595
- if (voiceId === null) return null;
1596
- if (planUsesNoise(plan)) prepareNoise(shared, audio, mix.noise.seconds);
1597
- return start(plan, shared, voiceId, playOptions.delay);
1598
- },
1599
- loop: (id, loopOptions = {}) => createLoopHandle(registry.loop(id), loopHost, loopOptions.volume),
1600
- channel(channelOptions) {
1601
- const random = channelOptions.random ?? (channelOptions.seed === void 0 ? engineRandom : createRng(channelOptions.seed));
1602
- const store = channelOptions.ownNoise ? createNoiseStore(random) : shared;
1603
- return {
1604
- random,
1605
- play: (id, playOptions = {}) => playWith(id, playOptions, random, store),
1606
- plan: (id, playOptions = {}) => planWith(id, playOptions, createRng(playOptions.seed ?? seed))
1607
- };
1608
- },
1609
- setListener(next) {
1610
- listener = next;
1611
- },
1612
- setBus(id, setting) {
1613
- busSettings.set(id, { ...busSettings.get(id), ...setting });
1614
- if (!context) return;
1615
- ensureBus(id);
1616
- busNodes.get(id).gain.value = busGain(busSettings.get(id));
1617
- },
1618
- setMix(next) {
1619
- const previous = mix;
1620
- mix = resolveMix(next, options.profiles);
1621
- if (!context || !chain) return;
1622
- const old = chain;
1623
- chain = buildChain(context, mix, engineRandom);
1624
- if (mix.noise.seconds !== previous.noise.seconds) shared.reset();
1625
- for (const node of busNodes.values()) {
1626
- node.disconnect();
1627
- node.connect(chain.master);
1628
- }
1629
- for (const loop of loops) loop.rewire();
1630
- old.disconnect();
1631
- },
1632
- setMaster(gain) {
1633
- mix = { ...mix, master: gain };
1634
- if (chain) chain.master.gain.value = gain;
1635
- },
1636
- unlock() {
1637
- const audio = ready();
1638
- if (audio) unlockContext(audio);
1639
- },
1640
- warmUp() {
1641
- const audio = ready();
1642
- if (!audio) return false;
1643
- noiseBuffer(shared, audio, mix.noise.seconds);
1644
- return true;
1645
- },
1646
- level(bus) {
1647
- watched.add(bus);
1648
- ensureBus(bus);
1649
- const meter = meterOf(bus);
1650
- if (!meter) return 0;
1651
- meter.analyser.getFloatTimeDomainData(meter.data);
1652
- let sum = 0;
1653
- for (const sample of meter.data) sum += sample * sample;
1654
- return Math.sqrt(sum / meter.data.length);
1655
- },
1656
- stats() {
1657
- advance();
1658
- const voiceStats = voices.stats();
1659
- return {
1660
- context: context ? context.state : "none",
1661
- voices: voiceStats.active,
1662
- peak: voiceStats.peak,
1663
- dropped: voiceStats.dropped,
1664
- maxVoices: voiceStats.maxVoices,
1665
- loops: [...loops].filter((loop) => loop.created).length
1666
- };
1667
- },
1668
- dispose() {
1669
- startQueue?.clear();
1670
- for (const id of active.keys()) voices.release(id);
1671
- for (const loop of [...loops]) loop.stop();
1672
- active.clear();
1673
- void context?.close();
1674
- context = null;
1675
- chain = null;
1676
- busNodes.clear();
1677
- meters.clear();
1678
- shared.reset();
1679
- }
1680
- };
1681
- }
1092
+ var BODY_FOLEY_SET_IDS = [...FOOTSTEP_SOUND_IDS, ...LAND_SOUND_IDS, ...BODY_SOUND_IDS];
1682
1093
 
1683
1094
  // src/webaudio/sink.ts
1684
1095
  function createAudioSink(engine) {
@@ -1690,7 +1101,9 @@ function createAudioSink(engine) {
1690
1101
  ...request.position ? { position: request.position } : {},
1691
1102
  ...request.volume === void 0 ? {} : { volume: request.volume },
1692
1103
  ...request.params ? { params: request.params } : {},
1693
- ...request.seed === void 0 ? {} : { seed: request.seed }
1104
+ ...request.seed === void 0 ? {} : { seed: request.seed },
1105
+ ...request.delay === void 0 ? {} : { delay: request.delay },
1106
+ ...request.urgent ? { urgent: true } : {}
1694
1107
  });
1695
1108
  if (!handle) return null;
1696
1109
  playing.set(handle.id, handle);
@@ -1700,9 +1113,22 @@ function createAudioSink(engine) {
1700
1113
  playing.get(handle.id)?.stop();
1701
1114
  playing.delete(handle.id);
1702
1115
  },
1703
- loop(sound) {
1116
+ loop(sound, options) {
1704
1117
  const loop = engine.loop(sound);
1705
- return { set: (state) => loop.set({ ...state.volume === void 0 ? {} : { volume: state.volume }, ...state.frequency === void 0 ? {} : { frequency: state.frequency } }), stop: () => loop.stop() };
1118
+ let position = options?.position;
1119
+ return {
1120
+ set: (state) => {
1121
+ position = state.position ?? position;
1122
+ const cutoff = state.params?.["cutoff"];
1123
+ loop.set({
1124
+ ...state.volume === void 0 ? {} : { volume: state.volume },
1125
+ ...state.frequency === void 0 ? {} : { frequency: state.frequency },
1126
+ ...position ? { position } : {},
1127
+ ...cutoff === void 0 ? {} : { cutoff }
1128
+ });
1129
+ },
1130
+ stop: () => loop.stop()
1131
+ };
1706
1132
  },
1707
1133
  setListener(listener) {
1708
1134
  engine.setListener(listener);
@@ -1712,519 +1138,137 @@ function createAudioSink(engine) {
1712
1138
  }
1713
1139
  };
1714
1140
  }
1715
-
1716
- // src/bench/locale.ts
1717
- var EN = {
1718
- group: "Sound",
1719
- name: "Sound area",
1720
- probe: "Sound probe",
1721
- controls: {
1722
- sound: "Sound",
1723
- distance: "Distance",
1724
- bearing: "Bearing",
1725
- volume: "Volume",
1726
- mix: "Mixing chain",
1727
- seed: "Seed",
1728
- play: "Play",
1729
- voice_storm: "Voice storm",
1730
- loop: "Loop",
1731
- loop_level: "Loop level",
1732
- loop_pitch: "Loop pitch",
1733
- source: "Source"
1734
- },
1735
- hints: {
1736
- distance: "Metres from the listener: the level falls and the sound is muffled with it.",
1737
- bearing: "Degrees from straight ahead, positive to the right: shows the panning.",
1738
- mix: "The game chain (master only) or the art scene chain (compressor and reverb).",
1739
- seed: "The same seed gives the same sound.",
1740
- voice_storm: "Twenty of the chosen sound at once: the voice limiter drops what its group and the global cap refuse.",
1741
- loop_pitch: "Frequency of an oscillator loop, in hertz (0 leaves it where it is).",
1742
- source: "Where the sound comes from: the distance and bearing set here, or the probe standing in the area."
1743
- },
1744
- options: { none: "None", bench: "Bench settings", probe: "The probe" },
1745
- layers: { reverb: "Reverb", compressor: "Compressor", panning: "Panning", muffling: "Muffling by distance" },
1746
- metrics: {
1747
- voices: "Voices playing",
1748
- peak: "Most voices at once",
1749
- dropped: "Voices dropped",
1750
- loops: "Loops running",
1751
- context: "Audio context",
1752
- plan_length: "Chosen sound: length",
1753
- plan_level: "Chosen sound: level",
1754
- plan_pan: "Chosen sound: pan",
1755
- level_weapons: "Level: weapons",
1756
- level_voices: "Level: voices",
1757
- level_world: "Level: world",
1758
- level_ambience: "Level: ambience",
1759
- level_weather: "Level: weather",
1760
- level_ui: "Level: interface"
1761
- },
1762
- scenarios: {
1763
- panning: "A sound to the right is heard on the right, one to the left on the left, one ahead in the middle",
1764
- distance: "The farther a sound, the quieter, until it is not played",
1765
- determinism: "The same seed gives the same sound plan, another seed another one",
1766
- limiter: "The voice limiter holds a storm of voices to its group rule and its global cap"
1767
- },
1768
- mixes: { game: "Game", art_scene: "Art scene" },
1769
- sheet: { title: "Sound plan", level: "level", distance: "distance", pan: "pan", length: "seconds", silent: "too far to be heard", layer: "layer", none: "no sound chosen" }
1770
- };
1771
- var PT_BR = {
1772
- group: "Som",
1773
- name: "\xC1rea de som",
1774
- probe: "Sonda de som",
1775
- controls: {
1776
- sound: "Som",
1777
- distance: "Dist\xE2ncia",
1778
- bearing: "Dire\xE7\xE3o",
1779
- volume: "Volume",
1780
- mix: "Cadeia de mixagem",
1781
- seed: "Semente",
1782
- play: "Tocar",
1783
- voice_storm: "Tempestade de vozes",
1784
- loop: "La\xE7o",
1785
- loop_level: "N\xEDvel do la\xE7o",
1786
- loop_pitch: "Altura do la\xE7o",
1787
- source: "Origem"
1788
- },
1789
- hints: {
1790
- distance: "Metros at\xE9 o ouvinte: o n\xEDvel cai e o som abafa junto.",
1791
- bearing: "Graus a partir da frente, positivo para a direita: mostra o pan.",
1792
- mix: "A cadeia do jogo (s\xF3 o master) ou a da Cena de Arte (compressor e reverb).",
1793
- seed: "A mesma semente d\xE1 o mesmo som.",
1794
- voice_storm: "Vinte do som escolhido de uma vez: o limite de vozes derruba o que a regra do grupo e o teto global recusam.",
1795
- loop_pitch: "Frequ\xEAncia de um la\xE7o de oscilador, em hertz (0 deixa onde est\xE1).",
1796
- source: "De onde vem o som: a dist\xE2ncia e a dire\xE7\xE3o daqui, ou a sonda que est\xE1 na \xE1rea."
1797
- },
1798
- options: { none: "Nenhum", bench: "Ajustes da bancada", probe: "A sonda" },
1799
- layers: { reverb: "Reverb", compressor: "Compressor", panning: "Pan", muffling: "Abafamento pela dist\xE2ncia" },
1800
- metrics: {
1801
- voices: "Vozes tocando",
1802
- peak: "Mais vozes de uma vez",
1803
- dropped: "Vozes derrubadas",
1804
- loops: "La\xE7os ligados",
1805
- context: "Contexto de \xE1udio",
1806
- plan_length: "Som escolhido: dura\xE7\xE3o",
1807
- plan_level: "Som escolhido: n\xEDvel",
1808
- plan_pan: "Som escolhido: pan",
1809
- level_weapons: "N\xEDvel: armas",
1810
- level_voices: "N\xEDvel: vozes",
1811
- level_world: "N\xEDvel: mundo",
1812
- level_ambience: "N\xEDvel: ambiente",
1813
- level_weather: "N\xEDvel: clima",
1814
- level_ui: "N\xEDvel: interface"
1815
- },
1816
- scenarios: {
1817
- panning: "Um som \xE0 direita sai \xE0 direita, \xE0 esquerda sai \xE0 esquerda, \xE0 frente sai no meio",
1818
- distance: "Quanto mais longe, mais baixo, at\xE9 n\xE3o tocar",
1819
- determinism: "A mesma semente d\xE1 o mesmo plano de som, outra semente d\xE1 outro",
1820
- limiter: "O limite de vozes segura uma tempestade de vozes na regra do grupo e no teto global"
1821
- },
1822
- mixes: { game: "Jogo", art_scene: "Cena de Arte" },
1823
- sheet: { title: "Plano do som", level: "n\xEDvel", distance: "dist\xE2ncia", pan: "pan", length: "segundos", silent: "longe demais para ouvir", layer: "camada", none: "nenhum som escolhido" }
1824
- };
1825
- var audioBenchTextOf = (locale) => locale === "en" ? EN : PT_BR;
1826
-
1827
- // src/bench/module.ts
1828
- var BENCH_BANK = {
1829
- id: "audio_bench",
1830
- sounds: [
1831
- {
1832
- id: "bench_ping",
1833
- bus: "ui",
1834
- pan: true,
1835
- duration: 0.25,
1836
- layers: [
1837
- {
1838
- gain: 0.5,
1839
- wet: 0.3,
1840
- source: { kind: "osc", wave: "sine", frequency: { from: 880 } },
1841
- envelope: [
1842
- [0, 1e-4, "set", "fixed"],
1843
- [2e-3, 1, "exp"],
1844
- ["1d", 1e-4, "exp", "fixed"]
1845
- ]
1846
- }
1847
- ],
1848
- falloff: DISTANCE_CURVES.art_scene,
1849
- sources: ["sdk: bench probe, a 880 Hz ping through the art scene output stage"]
1850
- },
1851
- {
1852
- id: "bench_hiss",
1853
- bus: "ui",
1854
- pan: true,
1855
- duration: [0.3, 0.9],
1856
- layers: [
1857
- {
1858
- gain: 0.4,
1859
- source: { kind: "noise", offset: "random", offsetScale: 1.5, loop: true },
1860
- filters: { mode: "serial", bank: [{ type: "highpass", frequency: { set: 3e3 }, q: 0.7 }] },
1861
- envelope: [
1862
- [0, 1e-4, "set", "fixed"],
1863
- [2e-3, 1, "exp"],
1864
- ["1d", 1e-4, "exp", "fixed"]
1865
- ]
1866
- }
1867
- ],
1868
- falloff: DISTANCE_CURVES.art_scene,
1869
- sources: ["sdk: bench probe, a highpass hiss of random length"]
1870
- }
1871
- ]
1872
- };
1873
- var DISTANCES = [0, 10, 40, 60, 120, 160];
1874
- var STORM = 20;
1875
- var PROBE_ID = "audio_probe";
1876
- var PROBE_AT = [0, 0, -10];
1877
- var NONE = "none";
1878
- var DEFAULT_SOUND = "bench_ping";
1879
- var variantOf = (profile, reverb, compressor) => {
1880
- const { reverb: wet, compressor: chain, ...rest } = profile;
1881
- return { ...rest, id: `${profile.id}${reverb ? "" : "+dry"}${compressor ? "" : "+open"}`, ...wet && reverb ? { reverb: wet } : {}, ...chain && compressor ? { compressor: chain } : {} };
1882
- };
1883
- function createAudioTestModule(options = {}) {
1884
- const locale = options.locale ?? "pt-BR";
1885
- const text = audioBenchTextOf(locale);
1886
- const banks = [BENCH_BANK, ...options.banks ?? [GAME_SFX_BANK, LIBRARY_BANK]];
1887
- let engine = options.engine ?? createAudioEngine({ seed: options.seed ?? 1, banks });
1888
- for (const bank of banks) engine.register(bank);
1889
- let host = null;
1890
- let loop;
1891
- const state = {
1892
- sound: options.sound ?? DEFAULT_SOUND,
1893
- distance: 10,
1894
- bearing: 0,
1895
- volume: 1,
1896
- mix: "art_scene",
1897
- seed: options.seed ?? 1,
1898
- source: "bench",
1899
- loop: NONE,
1900
- loopLevel: 0.1,
1901
- loopPitch: 0,
1902
- reverb: true,
1903
- compressor: true,
1904
- panning: true,
1905
- muffling: true
1906
- };
1907
- const nameOf = (id) => {
1908
- const translated = options.translate?.(`sound.${id}`, locale);
1909
- if (translated) return translated;
1910
- const bank = engine.registry.bankOf(id);
1911
- return bank ? `${bank} / ${id}` : id;
1912
- };
1913
- const soundOptions = () => engine.registry.soundIds().map((id) => ({ id, name: nameOf(id) }));
1914
- const loopOptions = () => [{ id: NONE, name: text.options.none }, ...engine.registry.loopIds().map((id) => ({ id, name: nameOf(id) }))];
1915
- const listener = () => {
1916
- const camera = host?.camera;
1917
- const three = host?.THREE;
1918
- if (typeof camera?.getWorldDirection !== "function" || typeof three?.Vector3 !== "function" || !camera.position) return { position: [0, 0, 0], yaw: 0 };
1919
- const direction = camera.getWorldDirection(new three.Vector3());
1920
- return { position: [camera.position.x, camera.position.y, camera.position.z], yaw: Math.atan2(-direction.x, -direction.z) };
1921
- };
1922
- const probePosition = () => {
1923
- const scene = host?.scene;
1924
- const three = host?.THREE;
1925
- if (typeof scene?.traverse !== "function" || typeof three?.Vector3 !== "function") return void 0;
1926
- let found;
1927
- scene.traverse((object) => {
1928
- if (found || object.userData?.[PROBE_ID] !== true) return;
1929
- const at = object.getWorldPosition(new three.Vector3());
1930
- found = [at.x, at.y, at.z];
1931
- });
1932
- return found;
1933
- };
1934
- const sourceAt = (ears) => {
1935
- const probe = state.source === "probe" ? probePosition() : void 0;
1936
- if (probe) return probe;
1937
- const bearing = state.bearing * Math.PI / 180;
1938
- const forward = [-Math.sin(ears.yaw), -Math.cos(ears.yaw)];
1939
- const right = [Math.cos(ears.yaw), -Math.sin(ears.yaw)];
1940
- return [ears.position[0] + state.distance * (forward[0] * Math.cos(bearing) + right[0] * Math.sin(bearing)), ears.position[1], ears.position[2] + state.distance * (forward[1] * Math.cos(bearing) + right[1] * Math.sin(bearing))];
1941
- };
1942
- const playOptions = () => {
1943
- const ears = listener();
1944
- engine.setListener(ears);
1945
- const at = sourceAt(ears);
1946
- const distance = Math.hypot(at[0] - ears.position[0], at[2] - ears.position[2]);
1947
- return { ...state.panning ? { position: at } : { distance }, volume: state.volume, seed: state.seed };
1948
- };
1949
- const withMuffling = (id, run) => {
1950
- const falloff = engine.registry.sound(id)?.falloff;
1951
- if (state.muffling || !falloff || falloff.model !== "inverse_square" || falloff.cutoffK === void 0) return run();
1952
- engine.registry.patch(id, { falloff: { cutoffK: 0 } });
1953
- try {
1954
- return run();
1955
- } finally {
1956
- engine.registry.patch(id, { falloff: { cutoffK: falloff.cutoffK } });
1957
- }
1958
- };
1959
- const play = () => {
1960
- engine.unlock();
1961
- const chosen = state.sound;
1962
- return withMuffling(chosen, () => engine.play(chosen, playOptions()));
1963
- };
1964
- const plan = () => {
1965
- const chosen = state.sound;
1966
- return withMuffling(chosen, () => engine.plan(chosen, playOptions()));
1967
- };
1968
- const sheet = () => {
1969
- const planned = plan();
1970
- if (!planned) return `${text.sheet.title}: ${engine.registry.sound(state.sound) ? text.sheet.silent : text.sheet.none}`;
1971
- const head = `${text.sheet.title}: ${planned.id} (${planned.bus}) ${text.sheet.level} ${planned.level.toFixed(4)} ${text.sheet.distance} ${planned.distance.toFixed(1)} m${planned.pan === void 0 ? "" : ` ${text.sheet.pan} ${planned.pan.toFixed(3)}`} ${planned.length.toFixed(3)} ${text.sheet.length}`;
1972
- const layers2 = planned.layers.map((layer, index) => {
1973
- const source = layer.source.kind === "noise" ? `noise@${layer.source.offset.toFixed(4)}` : layer.source.kind === "osc" ? `${layer.source.wave}@${layer.source.frequency.value ?? layer.source.frequency.from}` : layer.source.kind;
1974
- const filters = (layer.filters?.bank ?? []).map((filter) => `${filter.type}@${(filter.frequency.value ?? filter.frequency.from ?? 0).toFixed(1)}`).join(" ");
1975
- const envelope2 = layer.envelope.map((point) => `${point.time.toFixed(3)}:${point.value.toPrecision(3)}`).join(" ");
1976
- return ` ${text.sheet.layer} ${index + 1}: ${source} at ${layer.at.toFixed(3)} for ${layer.duration.toFixed(3)} ${filters} [${envelope2}]`;
1977
- });
1978
- return [head, ...layers2].join("\n");
1979
- };
1980
- const applyMix = () => {
1981
- const profile = engine && MIX_PROFILES[state.mix];
1982
- if (profile) engine.setMix(variantOf(profile, state.reverb, state.compressor));
1983
- };
1984
- const setLoop = () => {
1985
- loop?.stop();
1986
- loop = void 0;
1987
- if (state.loop === NONE) return;
1988
- engine.unlock();
1989
- loop = engine.loop(state.loop);
1990
- loop.set({ volume: state.loopLevel, ...state.loopPitch > 0 ? { frequency: state.loopPitch } : {} });
1991
- };
1992
- const storm = () => {
1993
- engine.unlock();
1994
- const base = playOptions();
1995
- const chosen = state.sound;
1996
- for (let index = 0; index < STORM; index++) {
1997
- const spread = base.position ? { position: [base.position[0] + (index - STORM / 2), base.position[1], base.position[2]] } : {};
1998
- withMuffling(chosen, () => engine.play(chosen, { ...base, ...spread, seed: state.seed + index }));
1999
- }
2000
- };
2001
- const onChange = (change) => {
2002
- if (change.kind === "layer") {
2003
- if (change.id === "reverb" || change.id === "compressor") {
2004
- state[change.id] = change.on;
2005
- applyMix();
2006
- } else if (change.id === "panning" || change.id === "muffling") state[change.id] = change.on;
2007
- return;
2008
- }
2009
- if (change.kind === "action") {
2010
- if (change.id === "play") play();
2011
- else if (change.id === "voice_storm") storm();
2012
- return;
2013
- }
2014
- const { id, value } = change;
2015
- if (id === "sound" && typeof value === "string") state.sound = value;
2016
- else if (id === "distance" && typeof value === "string") state.distance = Number(value);
2017
- else if (id === "bearing" && typeof value === "number") state.bearing = value;
2018
- else if (id === "volume" && typeof value === "number") state.volume = value;
2019
- else if (id === "seed" && typeof value === "number") state.seed = value;
2020
- else if (id === "source" && typeof value === "string") state.source = value;
2021
- else if (id === "mix" && typeof value === "string") {
2022
- state.mix = value;
2023
- applyMix();
2024
- } else if (id === "loop" && typeof value === "string") {
2025
- state.loop = value;
2026
- setLoop();
2027
- } else if (id === "loop_level" && typeof value === "number") {
2028
- state.loopLevel = value;
2029
- loop?.set({ volume: value });
2030
- } else if (id === "loop_pitch" && typeof value === "number") {
2031
- state.loopPitch = value;
2032
- if (value > 0) loop?.set({ frequency: value });
2033
- }
2034
- };
2035
- const items = () => {
2036
- const probe = options.probe;
2037
- if (!probe) return [];
2038
- return [
2039
- {
2040
- id: PROBE_ID,
2041
- name: text.probe,
2042
- movable: false,
2043
- build: (THREE) => {
2044
- const root = probe(THREE);
2045
- root.userData = root.userData ?? {};
2046
- root.userData[PROBE_ID] = true;
2047
- return root;
2048
- }
2049
- }
2050
- ];
2051
- };
2052
- const controls = () => [
2053
- { kind: "choice", id: "sound", name: text.controls.sound, options: soundOptions(), default: state.sound },
2054
- { kind: "choice", id: "source", name: text.controls.source, hint: text.hints.source, options: [{ id: "bench", name: text.options.bench }, { id: "probe", name: text.options.probe }], default: state.source },
2055
- { kind: "choice", id: "distance", name: text.controls.distance, hint: text.hints.distance, options: DISTANCES.map((meters) => ({ id: String(meters), name: `${meters} m` })), default: String(state.distance) },
2056
- { kind: "number", id: "bearing", name: text.controls.bearing, hint: text.hints.bearing, unit: "\xB0", min: -180, max: 180, step: 15, default: state.bearing },
2057
- { kind: "number", id: "volume", name: text.controls.volume, min: 0, max: 1, step: 0.05, default: state.volume },
2058
- { kind: "choice", id: "mix", name: text.controls.mix, hint: text.hints.mix, options: Object.keys(MIX_PROFILES).map((id) => ({ id, name: text.mixes[id] ?? id })), default: state.mix },
2059
- { kind: "number", id: "seed", name: text.controls.seed, hint: text.hints.seed, min: 1, max: 9999, step: 1, default: state.seed },
2060
- { kind: "action", id: "play", name: text.controls.play },
2061
- { kind: "action", id: "voice_storm", name: text.controls.voice_storm, hint: text.hints.voice_storm },
2062
- { kind: "choice", id: "loop", name: text.controls.loop, options: loopOptions(), default: state.loop },
2063
- { kind: "number", id: "loop_level", name: text.controls.loop_level, min: 0, max: 0.6, step: 0.01, default: state.loopLevel },
2064
- { kind: "number", id: "loop_pitch", name: text.controls.loop_pitch, hint: text.hints.loop_pitch, unit: "Hz", min: 0, max: 400, step: 5, default: state.loopPitch }
2065
- ];
2066
- const layers = () => ["reverb", "compressor", "panning", "muffling"].map((id) => ({ id, name: text.layers[id] }));
2067
- const metrics = () => [
2068
- { id: "voices", name: text.metrics.voices, digits: 0, read: () => engine.stats().voices },
2069
- { id: "peak", name: text.metrics.peak, digits: 0, max: engine.stats().maxVoices > 0 && Number.isFinite(engine.stats().maxVoices) ? engine.stats().maxVoices : void 0, read: () => engine.stats().peak },
2070
- { id: "dropped", name: text.metrics.dropped, digits: 0, read: () => engine.stats().dropped },
2071
- { id: "loops", name: text.metrics.loops, digits: 0, read: () => engine.stats().loops },
2072
- { id: "context", name: text.metrics.context, read: () => engine.stats().context },
2073
- { id: "plan_length", name: text.metrics.plan_length, unit: "s", digits: 2, read: () => plan()?.length ?? 0 },
2074
- { id: "plan_level", name: text.metrics.plan_level, digits: 3, read: () => plan()?.level ?? 0 },
2075
- { id: "plan_pan", name: text.metrics.plan_pan, digits: 2, read: () => plan()?.pan ?? 0 },
2076
- ...BUS_IDS.map((bus) => ({ id: `level_${bus}`, name: text.metrics[`level_${bus}`], digits: 3, read: () => engine.level(bus) }))
2077
- ];
2078
- const scenarios = () => [
2079
- {
2080
- id: "panning",
2081
- name: text.scenarios.panning,
2082
- run: ({ expect }) => {
2083
- engine.setListener({ position: [0, 0, 0], yaw: 0 });
2084
- const pan = (at) => engine.plan("bench_ping", { position: at })?.pan ?? Number.NaN;
2085
- expect(pan([10, 0, 0]) > 0.3, "a sound to the right pans right", { pan: pan([10, 0, 0]) });
2086
- expect(pan([-10, 0, 0]) < -0.3, "a sound to the left pans left", { pan: pan([-10, 0, 0]) });
2087
- expect(Math.abs(pan([0, 0, -10])) < 0.05, "a sound ahead stays in the middle", { pan: pan([0, 0, -10]) });
2088
- engine.setListener({ position: [0, 0, 0], yaw: Math.PI / 2 });
2089
- expect(pan([0, 0, -10]) > 0.3, "turning the listener left puts what was ahead on the right", { pan: pan([0, 0, -10]) });
2090
- engine.setListener(listener());
2091
- }
2092
- },
2093
- {
2094
- id: "distance",
2095
- name: text.scenarios.distance,
2096
- run: ({ expect }) => {
2097
- const levels = [0, 10, 40, 100].map((meters) => engine.plan("bench_ping", { distance: meters })?.level ?? Number.NaN);
2098
- expect(levels.every((level, index) => index === 0 || level < levels[index - 1]), "the level falls with the distance", { levels });
2099
- const far = engine.registry.sound("sfx_pistol") ? engine.plan("sfx_pistol", { distance: 400 }) : null;
2100
- expect(far === null, "a game noise class is not played too far to be heard");
2101
- }
2102
- },
2103
- {
2104
- id: "determinism",
2105
- name: text.scenarios.determinism,
2106
- run: ({ expect }) => {
2107
- const a = engine.plan("bench_hiss", { seed: 5 });
2108
- const b = engine.plan("bench_hiss", { seed: 5 });
2109
- const c = engine.plan("bench_hiss", { seed: 6 });
2110
- expect(JSON.stringify(a) === JSON.stringify(b), "the same seed gives the same plan");
2111
- expect(JSON.stringify(a) !== JSON.stringify(c), "another seed gives another plan");
2112
- }
2113
- },
2114
- {
2115
- id: "limiter",
2116
- name: text.scenarios.limiter,
2117
- run: ({ expect }) => {
2118
- const voices = createVoiceManager({ maxVoices: 8 });
2119
- const request = (group) => voices.request({ ...group ? { group } : {}, priority: 3, gain: 0.5, distance: 5, length: 1 });
2120
- const grouped = Array.from({ length: STORM }, () => request("undead_voice")).filter((decision) => decision.accepted).length;
2121
- expect(grouped === 1, "the group cooldown lets one voice of a storm through", { accepted: grouped });
2122
- const plain = Array.from({ length: STORM }, () => request()).filter((decision) => decision.accepted).length;
2123
- expect(plain <= 8, "the global cap holds the rest", { accepted: plain });
2124
- }
2125
- }
2126
- ];
2127
- const area = () => ({
2128
- placements: options.probe ? [{ item: PROBE_ID, position: PROBE_AT, asleep: true }] : [],
2129
- view: { eye: [0, 1.7, 3], target: [0, 1.4, -10] }
2130
- });
2131
- const module = {
2132
- id: "audio_area",
2133
- name: text.name,
2134
- ground: { surface: "concrete_slab" },
2135
- group: text.group,
2136
- get engine() {
2137
- return engine;
2138
- },
2139
- items: () => items(),
2140
- area: () => area(),
2141
- controls: () => controls(),
2142
- layers: () => layers(),
2143
- metrics: () => metrics(),
2144
- scenarios: () => scenarios(),
2145
- sheet,
2146
- play,
2147
- attach(lent) {
2148
- host = lent;
2149
- const shared = lent.audio?.engine;
2150
- if (shared && shared !== engine) {
2151
- for (const bank of banks) shared.register(bank);
2152
- engine = shared;
2153
- }
2154
- for (const bus of BUS_IDS) {
2155
- engine.setBus(bus, {});
2156
- engine.level(bus);
2157
- }
2158
- lent.bench?.patch("sound", { options: soundOptions() });
2159
- lent.bench?.patch("loop", { options: loopOptions() });
2160
- const off = lent.bench?.onChange(onChange);
2161
- const offFrame = lent.onFrame(() => {
2162
- if (!shared) engine.setListener(listener());
2163
- });
2164
- return () => {
2165
- off?.();
2166
- offFrame();
2167
- loop?.stop();
2168
- loop = void 0;
2169
- host = null;
2170
- };
2171
- }
2172
- };
2173
- return module;
2174
- }
2175
1141
  export {
2176
1142
  BENCH_BANK,
1143
+ BODY_FALLOFF,
1144
+ BODY_FOLEY_BANK,
1145
+ BODY_FOLEY_SET_IDS,
1146
+ BODY_FOLEY_TAKES,
2177
1147
  BUILD_ORDERS,
2178
1148
  BUS_IDS,
2179
1149
  BUS_PRIORITY,
1150
+ CALIBRATION_ID,
1151
+ CALIBRATION_LOOP_ID,
1152
+ CALIBRATION_LOOP_SOUND,
1153
+ CALIBRATION_SOUND,
1154
+ CRITERIA,
1155
+ CRITERIA_TARGETS,
1156
+ CROSSFADE_STEPS,
1157
+ DEFAULT_CROSSOVER,
2180
1158
  DEFAULT_LISTENER,
1159
+ DEFAULT_LOOP_CROSSFADE,
2181
1160
  DEFAULT_MAX_VOICES,
2182
1161
  DEFAULT_MIX,
1162
+ DEFAULT_SAMPLE_CUTOFF_K,
1163
+ DEFAULT_SAMPLE_FALLOFF,
1164
+ DEFAULT_SAMPLE_PITCH,
1165
+ DEFAULT_TAIL_GAIN,
2183
1166
  DISTANCE_CURVES,
1167
+ FOLEY_BANK,
1168
+ FOLEY_FALLOFF,
1169
+ FOOTSTEP_FALLOFF,
2184
1170
  GAME_SFX_BANK,
2185
1171
  GAME_SFX_CLASSES,
2186
1172
  GAME_SFX_FALLBACK,
1173
+ ITEM_FOLEY,
1174
+ KIT_CATEGORY_BUS,
1175
+ KIT_SAMPLE_ALIASES,
1176
+ LAYER_FLOOR,
1177
+ LEAF_FOLEY,
1178
+ LEAF_FOLEY_SETS,
2187
1179
  LIBRARY_BANK,
2188
1180
  LIBRARY_LOOPS,
2189
1181
  LIBRARY_SOUNDS,
2190
1182
  LOOP_SMOOTHING,
2191
1183
  LOOP_START_ABOVE,
2192
1184
  MIX_PROFILES,
1185
+ OPEN_CUTOFF,
2193
1186
  PAN_LIMIT,
2194
1187
  PAN_MIN_DISTANCE,
1188
+ PICKUP_CLASSES,
1189
+ SAMPLE_ENVIRONMENTS,
1190
+ SDK_LICENSES,
1191
+ SFX_BLOWS,
1192
+ SFX_CATALOG,
1193
+ SFX_CATEGORIES,
1194
+ SFX_IMPACTS,
1195
+ SFX_LAYERS,
1196
+ SFX_MATERIALS,
1197
+ SFX_TIERS,
2195
1198
  VOICE_GROUPS,
2196
1199
  audioBenchTextOf,
1200
+ balanceOf,
2197
1201
  bufferOf,
2198
1202
  buildChain,
2199
1203
  busGain,
2200
1204
  busPriority,
1205
+ calibrationLoader,
1206
+ centroidHz,
1207
+ countHits,
2201
1208
  createAudioEngine,
2202
1209
  createAudioSink,
2203
1210
  createAudioTestModule,
2204
1211
  createLoopState,
2205
1212
  createRng,
1213
+ createSampleStore,
1214
+ createSetPicker,
2206
1215
  createSoundRegistry,
2207
1216
  createVoiceManager,
1217
+ crossGains,
2208
1218
  cutoffDivisor,
1219
+ dbOf,
2209
1220
  drawBetween,
1221
+ encodeWav,
1222
+ endDropDb,
1223
+ equalPowerIn,
2210
1224
  falloffGain,
1225
+ farMixAt,
1226
+ fetchLoader,
2211
1227
  fillImpulse,
2212
1228
  fillNoise,
2213
1229
  globalContext,
1230
+ impactSoundId,
1231
+ inlineLoader,
1232
+ isCalibrationUrl,
2214
1233
  isSilent,
1234
+ kitSampleBank,
1235
+ kitSampleDefaults,
1236
+ limiterCurve,
2215
1237
  listenerDistance,
1238
+ loadKitSamples,
1239
+ loopCrossfade,
1240
+ measureCriteria,
2216
1241
  noiseClassRecipe,
1242
+ onsetIndex,
2217
1243
  panFor,
1244
+ parseSfxName,
1245
+ peakIndex,
1246
+ peakOf,
1247
+ pickTake,
1248
+ planSample,
2218
1249
  planSound,
2219
1250
  realize,
1251
+ realizeSample,
1252
+ recordOutput,
2220
1253
  resolveMix,
1254
+ retunePlan,
1255
+ ringSeconds,
1256
+ rmsDb,
1257
+ sampleBankFromManifest,
1258
+ sampleCutoff,
1259
+ sampleLength,
1260
+ sampleUrls,
2221
1261
  sceneMany,
2222
1262
  sceneNoise,
2223
1263
  sceneRecipe,
2224
1264
  sceneTone,
2225
1265
  sceneVoice,
1266
+ sfxState,
1267
+ splitTier,
2226
1268
  streamFor,
2227
1269
  streamSeed,
2228
- unlockContext
1270
+ tierFor,
1271
+ unlockContext,
1272
+ withAliases
2229
1273
  };
2230
1274
  //# sourceMappingURL=index.js.map