sfx.js 12 KB

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