Source: extern/sfx.js

  1. import register from "../util/register.js";
  2. import m_obj_util_fact from "../intern/obj_util.js";
  3. import m_scs_fact from "../intern/scenes.js";
  4. import m_sfx_fact from "../intern/sfx.js";
  5. import m_print_fact from "../intern/print.js";
  6. /**
  7. * Sound effects API.
  8. * Uses Web Audio API for sound effects and HTML5 audio for background music.
  9. * @see https://www.blend4web.com/doc/en/audio.html
  10. * @module sfx
  11. * @cc_externs AudioContext webkitAudioContext MediaElementAudioSourceNode
  12. */
  13. function SFX(ns, exports) {
  14. var m_obj_util = m_obj_util_fact(ns);
  15. var m_scs = m_scs_fact(ns);
  16. var m_sfx = m_sfx_fact(ns);
  17. var m_print = m_print_fact(ns);
  18. /**
  19. * Play sound through the speaker.
  20. * @method module:sfx.play
  21. * @param {Object3D} obj Object 3D
  22. * @param {number} [when=0] Delay after exec in seconds
  23. * @param {number} [duration=0] Duration of the speaker's playback cycle (in
  24. * seconds). duration=0 - assign default value according to sound playback length.
  25. */
  26. exports.play = function(obj, when, duration) {
  27. when = when || 0;
  28. duration = duration || 0;
  29. m_sfx.play(obj, when, duration);
  30. }
  31. /**
  32. * Play sound through the speaker using the default delay and duration params.
  33. * @method module:sfx.play_def
  34. * @param {Object3D} obj Object 3D
  35. */
  36. exports.play_def = function(obj) {
  37. m_sfx.play_def(obj);
  38. }
  39. /**
  40. * Check if sound is played through the speaker now.
  41. * @method module:sfx.is_playing
  42. * @param {Object3D} obj Object 3D
  43. * @returns {boolean} Playing state
  44. */
  45. exports.is_playing = function(obj) {
  46. return m_sfx.is_playing(obj);
  47. }
  48. /**
  49. * Stop the speaker.
  50. * @method module:sfx.stop
  51. * @param {Object3D} obj Object 3D
  52. */
  53. exports.stop = function(obj) {
  54. m_sfx.stop(obj);
  55. }
  56. /**
  57. * Pause the speaker.
  58. * @method module:sfx.pause
  59. * @param {Object3D} obj Object 3D
  60. */
  61. exports.pause = function(obj) {
  62. m_sfx.speaker_pause(obj);
  63. }
  64. /**
  65. * Resume the paused speaker.
  66. * @method module:sfx.resume
  67. * @param {Object3D} obj Object 3D
  68. */
  69. exports.resume = function(obj) {
  70. m_sfx.speaker_resume(obj);
  71. }
  72. /**
  73. * Stop the speaker's looping playback.
  74. * @method module:sfx.loop_stop
  75. * @param {Object3D} obj Speaker object
  76. * @param {number} [when=0] Delay after exec in seconds
  77. * @param {boolean} [wait=false] Wait loop until currently played cycle is
  78. * finished
  79. */
  80. exports.loop_stop = function(obj, when, wait) {
  81. when = when || 0;
  82. wait = wait || false;
  83. m_sfx.loop_stop(obj, when, wait);
  84. }
  85. /**
  86. * Change the speaker playback rate value.
  87. * @method module:sfx.playrate
  88. * @param {Object3D} obj Object 3D
  89. * @param {number} playrate Playback rate (1.0 - normal speed).
  90. */
  91. exports.playrate = function(obj, playrate) {
  92. m_sfx.playrate(obj, playrate);
  93. }
  94. /**
  95. * Get the speaker playback rate value.
  96. * @method module:sfx.playrate
  97. * @param {Object3D} obj Object 3D
  98. * @returns {number} Playback rate
  99. */
  100. exports.get_playrate = function(obj) {
  101. return m_sfx.get_playrate(obj);
  102. }
  103. /**
  104. * Set cyclic flag.
  105. * @method module:sfx.cyclic
  106. * @param {Object3D} obj Speaker object.
  107. * @param {boolean} cyclic New cyclic flag value.
  108. */
  109. exports.cyclic = function(obj, cyclic) {
  110. m_sfx.cyclic(obj, cyclic);
  111. }
  112. /**
  113. * Check if the cyclic flag is set.
  114. * @method module:sfx.is_cyclic
  115. * @param {Object3D} obj Speaker object.
  116. * @returns {boolean} Cyclic flag value.
  117. */
  118. exports.is_cyclic = function(obj) {
  119. return m_sfx.is_cyclic(obj);
  120. }
  121. /**
  122. * Reset the listener speed.
  123. * Use before rapid listener movements to neutralize undesirable doppler effect.
  124. * @method module:sfx.listener_reset_speed
  125. * @param {number} speed The listener new speed
  126. * @param {?Float32Array} [dir=null] The listener new direction
  127. * @deprecated Use {@link module:sfx.listener_stride|sfx.listener_stride} instead
  128. */
  129. exports.listener_reset_speed = function(speed, dir) {
  130. m_sfx.listener_stride();
  131. }
  132. /**
  133. * Make a listener stride.
  134. * Use before quick listener movements to neutralize undesirable doppler effect.
  135. * @method module:sfx.listener_stride
  136. */
  137. exports.listener_stride = function() {
  138. m_sfx.listener_stride();
  139. }
  140. /**
  141. * Reset the speaker speed.
  142. * It's necessary to nullify speed before the speaker has moved quickly in order
  143. * to neutralize the undesirable doppler effect.
  144. * @method module:sfx.speaker_reset_speed
  145. * @param {Object3D} obj Speaker object.
  146. * @param {number} speed The speaker's new speed
  147. * @param {?Float32Array} [dir=null] The speaker's new direction
  148. * @deprecated Use {@link module:sfx.speaker_stride|sfx.speaker_stride} instead
  149. */
  150. exports.speaker_reset_speed = function(obj, speed, dir) {
  151. m_sfx.speaker_stride(obj);
  152. }
  153. /**
  154. * Make a speaker stride.
  155. * Use before rapid speaker movements to neutralize undesirable doppler effect.
  156. * @method module:sfx.speaker_reset_speed
  157. * @param {Object3D} obj Speaker object.
  158. */
  159. exports.speaker_stride = function(obj) {
  160. m_sfx.speaker_stride(obj);
  161. }
  162. /**
  163. * Get volume level.
  164. * @method module:sfx.get_volume
  165. * @param {?Object3D} obj Object 3D or null for MASTER volume
  166. * @returns {number} Volume (0..1)
  167. */
  168. exports.get_volume = function(obj) {
  169. if (obj && typeof obj === "object")
  170. return m_sfx.get_volume(obj);
  171. else
  172. return m_sfx.get_master_volume();
  173. }
  174. /**
  175. * Set volume level.
  176. * @method module:sfx.set_volume
  177. * @param {?Object3D} obj Object 3D or null for MASTER volume
  178. * @param {number} volume Volume (0..1)
  179. */
  180. exports.set_volume = function(obj, volume) {
  181. if (obj && typeof obj === "object")
  182. m_sfx.set_volume(obj, volume);
  183. else
  184. m_sfx.set_master_volume(volume);
  185. }
  186. /**
  187. * Mute/unmute.
  188. * @method module:sfx.mute
  189. * @param {?Object3D} obj Speaker object or null to mute the whole scene.
  190. * @param {boolean} muted New state
  191. */
  192. exports.mute = function(obj, muted) {
  193. if (obj && typeof obj === "object")
  194. m_sfx.mute(obj, muted);
  195. else
  196. m_sfx.mute_master(muted);
  197. }
  198. /**
  199. * Check if the speaker is muted.
  200. * @method module:sfx.is_muted
  201. * @param {?Object3D} obj Speaker object or null for the whole scene.
  202. * @returns {boolean} Muted state.
  203. */
  204. exports.is_muted = function(obj) {
  205. if (obj && typeof obj === "object")
  206. return m_sfx.is_muted(obj);
  207. else
  208. return m_sfx.is_master_muted();
  209. }
  210. /**
  211. * Get the speaker objects which are used by the module.
  212. * @returns {Array} Speaker object array
  213. */
  214. exports.get_speaker_objects = function() {
  215. return m_sfx.get_speaker_objects().slice(0);
  216. }
  217. /**
  218. * Check if there are some active speakers in use or not.
  219. * @method module:sfx.check_active_speakers
  220. * @returns {boolean} Check result
  221. */
  222. exports.check_active_speakers = m_sfx.check_active_speakers;
  223. /**
  224. * Set compressor params.
  225. * @method module:sfx.set_compressor_params
  226. * @param {CompressorParams} params Params object
  227. * @cc_externs threshold knee ratio attack release
  228. */
  229. exports.set_compressor_params = function(params) {
  230. m_sfx.set_compressor_params(m_scs.get_active(), params);
  231. }
  232. /**
  233. * Get compressor params.
  234. * @method module:sfx.get_compressor_params
  235. * @returns {CompressorParams} Params object
  236. */
  237. exports.get_compressor_params = function() {
  238. return m_sfx.get_compressor_params(m_scs.get_active());
  239. }
  240. /**
  241. * Duck (reduce the volume).
  242. * works independently from the volume API and the volume randomization
  243. * @method module:sfx.duck
  244. * @param {?Object3D} obj Object 3D or null for MASTER
  245. * @param {number} value Duck amount.
  246. * @param {number} time Time to change volume.
  247. */
  248. exports.duck = function(obj, value, time) {
  249. if (obj && typeof obj === "object")
  250. m_sfx.duck(obj, value, time);
  251. else
  252. m_sfx.duck_master(value, time);
  253. }
  254. /**
  255. * Unduck (restore the volume).
  256. * @method module:sfx.unduck
  257. * @param {?Object3D} obj Object 3D or null for MASTER
  258. */
  259. exports.unduck = function(obj) {
  260. if (obj && typeof obj === "object")
  261. m_sfx.unduck(obj);
  262. else
  263. m_sfx.unduck_master();
  264. }
  265. /**
  266. * Apply the new playlist from the given set of speakers.
  267. * The new playlist starts playing immediately.
  268. * @method module:sfx.apply_playlist
  269. * @param {Object3D[]} objs Array of objects.
  270. * @param {number} delay Number of seconds between tracks
  271. * @param {boolean} random Randomize playback sequence
  272. */
  273. exports.apply_playlist = m_sfx.apply_playlist;
  274. /**
  275. * Stop playback and clear the playlist.
  276. * @method module:sfx.clear_playlist
  277. */
  278. exports.clear_playlist = m_sfx.clear_playlist;
  279. /**
  280. * Detect supported audio container.
  281. * Containers have same meaning as file extension here, for each one possible
  282. * fallback exists:
  283. * <ul>
  284. * <li>ogg -> mp4
  285. * <li>mp3 -> ogg
  286. * <li>mp4 -> ogg
  287. * </ul>
  288. * @method module:sfx.detect_audio_container
  289. * @param {string} [hint="ogg"] Required container
  290. * @returns {string} Supported container or ""
  291. */
  292. exports.detect_audio_container = m_sfx.detect_audio_container;
  293. /**
  294. * Detect supported video container.
  295. * Containers have same meaning as file extension here, for each one possible
  296. * fallback exists:
  297. * <ul>
  298. * <li>ogv -> m4v
  299. * <li>m4v -> webm
  300. * <li>webm -> m4v
  301. * </ul>
  302. * @method module:sfx.detect_video_container
  303. * @param {string} [hint="webm"] Required container
  304. * @returns {string} Supported container or ""
  305. */
  306. exports.detect_video_container = m_sfx.detect_video_container;
  307. /**
  308. * Set positional params.
  309. * @method module:sfx.set_positional_params
  310. * @param {Object3D} obj Object 3D
  311. * @param {PositionalParams} params Params object
  312. * @cc_externs dist_ref dist_max attenuation
  313. */
  314. exports.set_positional_params = m_sfx.set_positional_params;
  315. /**
  316. * Get positional params.
  317. * @method module:sfx.get_positional_params
  318. * @param {Object3D} obj Object 3D
  319. * @returns {PositionalParams} Params object
  320. */
  321. exports.get_positional_params = m_sfx.get_positional_params;
  322. /**
  323. * Set filter params.
  324. * @method module:sfx.set_filter_params
  325. * @param {Object3D} obj Object 3D
  326. * @param {FilterParams} params Params object
  327. * @cc_externs freq Q gain
  328. */
  329. exports.set_filter_params = m_sfx.set_filter_params;
  330. /**
  331. * Get filter params.
  332. * @method module:sfx.get_filter_params
  333. * @param {Object3D} obj Object 3D
  334. * @returns {FilterParams} Params object
  335. */
  336. exports.get_filter_params = m_sfx.get_filter_params;
  337. /**
  338. * Get filter frequency response.
  339. * @method module:sfx.get_filter_freq_response
  340. * @param {Object3D} obj Object 3D
  341. * @param {Float32Array} freq_arr Input array with frequencies.
  342. * @param {Float32Array} mag_arr Output array with filter response magnitudes.
  343. * @param {Float32Array} phase_arr Output array with filter response phases.
  344. */
  345. exports.get_filter_freq_response = m_sfx.get_filter_freq_response;
  346. /**
  347. * Get duration of the speaker's playback cycle.
  348. * Zero duration means looped or non-ready speaker
  349. * @method module:sfx.get_duration
  350. * @param {?Object3D} obj Speaker object.
  351. * @returns {number} Duration
  352. */
  353. exports.get_duration = function(obj) {
  354. if (!obj || !m_obj_util.is_speaker(obj)) {
  355. m_print.error("Object \"" + (obj ? obj.name : undefined) +
  356. "\" is not a valid speaker");
  357. return 0;
  358. }
  359. return m_sfx.get_duration(obj);
  360. }
  361. }
  362. var sfx_factory = register("sfx", SFX);
  363. export default sfx_factory;